diff --git a/lib/base/heimbase.c b/lib/base/heimbase.c index 4848bd5b7..8f5694d27 100644 --- a/lib/base/heimbase.c +++ b/lib/base/heimbase.c @@ -368,7 +368,16 @@ _heim_type_get_tid(heim_type_t type) void heim_base_once_f(heim_base_once_t *once, void *ctx, void (*func)(void *)) { -#ifdef HAVE_DISPATCH_DISPATCH_H +#if defined(WIN32) + if (InterlockedCompareExchange(&once->started, 1L, 0L) == 0L) { + once->running = 1L; + (*func)(ctx); + once->running = 0L; + } else { + while (once->running) + SwitchToThread(); + } +#elif defined(HAVE_DISPATCH_DISPATCH_H) dispatch_once_f(once, ctx, func); #else static HEIMDAL_MUTEX mutex = HEIMDAL_MUTEX_INITIALIZER; diff --git a/lib/base/heimbase.h b/lib/base/heimbase.h index 6d4332509..c617a6344 100644 --- a/lib/base/heimbase.h +++ b/lib/base/heimbase.h @@ -56,8 +56,16 @@ typedef void * heim_object_t; typedef unsigned int heim_tid_t; typedef heim_object_t heim_bool_t; typedef heim_object_t heim_null_t; -#define HEIM_BASE_ONCE_INIT 0 +#if defined(WIN32) +typedef struct { + LONG started; + LONG running; +} heim_base_once_t; +# define HEIM_BASE_ONCE_INIT {0L, 0L} +#else +# define HEIM_BASE_ONCE_INIT 0 typedef long heim_base_once_t; /* XXX arch dependant */ +#endif #if !defined(__has_extension) #define __has_extension(x) 0