From c0e45c61b54322f807e00233c9f104c225eb12bb Mon Sep 17 00:00:00 2001 From: deuce <> Date: Sun, 4 Oct 2015 22:09:00 +0000 Subject: [PATCH] Add a pthread_once() implementation for Win32 (untested on Win32). --- src/xpdev/threadwrap.c | 22 ++++++++++++++++++++++ src/xpdev/threadwrap.h | 8 ++++++++ 2 files changed, 30 insertions(+) diff --git a/src/xpdev/threadwrap.c b/src/xpdev/threadwrap.c index b7c727b35f..60acca5df0 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 bfd41467d2..f5944c9e92 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) -- GitLab