diff --git a/src/xpdev/threadwrap.c b/src/xpdev/threadwrap.c index b7c727b35fb954016951b07cebe0a897325353b6..60acca5df083c5cb9fe2d81bce5db11093932efd 100644 --- a/src/xpdev/threadwrap.c +++ b/src/xpdev/threadwrap.c @@ -126,6 +126,28 @@ pthread_mutex_t DLLCALL pthread_mutex_initializer_np(BOOL recursive) #if !defined(_POSIX_THREADS) +int DLLCALL pthread_once(pthread_once_t *oc, void (*init)(void)) +{ + if (oc == NULL || init == NULL) + return EINVAL; + switch(InterlockedCompareExchange(&(oc->state), 1, 0)) { + case 0: // Never called + init(); + InterlockedIncrement(&(oc->state)); + return 0; + case 1: // In init function + /* We may not need to use InterlockedCompareExchange() here, + * but I hate marking things as volatile, and hate tight loops + * testing things that aren't marked volatile. + */ + while(InterlockedCompareExchange(&(oc->state), 1, 0) != 2) + SLEEP(1); + return 0; + case 2: // Done. + return 0; + } +} + int DLLCALL pthread_mutex_init(pthread_mutex_t* mutex, void* attr) { (void)attr; diff --git a/src/xpdev/threadwrap.h b/src/xpdev/threadwrap.h index bfd41467d23074de680f21bc0d57dd9f96b2da1f..f5944c9e9200ca603135a3373a8db85be8121929 100644 --- a/src/xpdev/threadwrap.h +++ b/src/xpdev/threadwrap.h @@ -123,6 +123,14 @@ DLLEXPORT int DLLCALL pthread_mutex_destroy(pthread_mutex_t*); #define SetThreadName(c) +// A structure in case we need to add an event or something... +typedef struct { + uint32_t state; +} pthread_once_t; + +#define PTHREAD_ONCE_INIT {0}; +DLLEXPORT int DLLCALL pthread_once(pthread_once_t *oc, void (*init)(void)); + #endif #if !defined(PTHREAD_MUTEX_INITIALIZER_NP)