5 static volatile HANDLE onceHandle = NULL;
\r
7 static void initOnceHandle( _PDCLIB_once_flag *flag )
\r
9 HANDLE tOnceHandle = CreateEvent(NULL, TRUE, TRUE, NULL);
\r
11 = InterlockedCompareExchangePointer(&flag->_Handle, tOnceHandle, NULL);
\r
13 CloseHandle(tOnceHandle);
\r
16 void _PDCLIB_call_once(_PDCLIB_once_flag *flag, void (*func)(void))
\r
18 if(!flag->_Handle) initOnceHandle(flag);
\r
20 long oldVal = InterlockedCompareExchange(&flag->_State, 1, -1);
\r
25 } else if(oldVal == -1) {
\r
26 // We are doing the initialization
\r
28 if(InterlockedDecrement(&flag->_State) == 0)
\r
29 CloseHandle(flag->_Handle);
\r
30 SetEvent(flag->_Handle);
\r
33 // Somebody else is initializing - we are waiting
\r
34 long newOldVal = InterlockedCompareExchange(&flag->_State, oldVal,
\r
36 if(newOldVal == oldVal) {
\r
37 // We incremented the "waiters" counter
\r
38 if(WaitForSingleObject(flag->_Handle, INFINITE) != WAIT_OBJECT_0)
\r
40 if(InterlockedDecrement(&flag->_State) == 0)
\r
41 CloseHandle(flag->_Handle);
\r
53 #include <_PDCLIB_test.h>
\r
56 static int count = 0;
\r
57 static once_flag once = ONCE_FLAG_INIT;
\r
59 static void do_once(void)
\r
68 TESTCASE(count == 0);
\r
69 call_once(&once, do_once);
\r
70 TESTCASE(count == 1);
\r
71 call_once(&once, do_once);
\r
72 TESTCASE(count == 1);
\r
74 TESTCASE(count == 2);
\r
76 return TEST_RESULTS;
\r