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