@@ -31,10 +31,12 @@ # include typedef pthread_t of_thread_t; typedef pthread_key_t of_tlskey_t; typedef pthread_mutex_t of_mutex_t; typedef pthread_cond_t of_condition_t; +typedef pthread_once_t of_once_t; +# define OF_ONCE_INIT PTHREAD_ONCE_INIT #elif defined(_WIN32) /* * winsock2.h needs to be included before windows.h. Not including it here * would make it impossible to use sockets after threading.h has been * imported. @@ -48,10 +50,12 @@ typedef CRITICAL_SECTION of_mutex_t; typedef struct { HANDLE event; int count; } of_condition_t; +typedef volatile LONG of_once_t; +# define OF_ONCE_INIT 0 #else # error No threads available! #endif #if defined(OF_HAVE_ATOMIC_OPS) @@ -148,10 +152,31 @@ ExitThread(0); #else # error of_thread_exit not implemented! #endif } + +static OF_INLINE void +of_once(of_once_t *control, void (*func)(void)) +{ +#if defined(OF_HAVE_PTHREADS) + pthread_once(control, func); +#elif defined(_WIN32) + switch (InterlockedCompareExchange(control, 1, 0)) { + case 0: + func(); + InterlockedIncrement(control); + break; + case 1: + while (*control == 1) + Sleep(0); + break; + } +#else +# error of_once not implemented! +#endif +} static OF_INLINE bool of_mutex_new(of_mutex_t *mutex) { #if defined(OF_HAVE_PTHREADS)