#define GSSEAP_MUTEX_DESTROY(m) DeleteCriticalSection((m))
#define GSSEAP_MUTEX_LOCK(m) EnterCriticalSection((m))
#define GSSEAP_MUTEX_UNLOCK(m) LeaveCriticalSection((m))
-#define GSSEAP_ONCE_LEAVE do { return TRUE; } while (0)
/* Thread-local is handled separately */
-#define GSSEAP_THREAD_ONCE INIT_ONCE
-#define GSSEAP_ONCE_CALLBACK(cb) BOOL CALLBACK cb(PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
-#define GSSEAP_ONCE(o, i) InitOnceExecuteOnce((o), (i), NULL, NULL)
-#define GSSEAP_ONCE_INITIALIZER INIT_ONCE_STATIC_INIT
+/* Once is handled separately because INIT_ONCE is only on Vista and above */
+#define GSSEAP_ONCE_LEAVE
+#define GSSEAP_ONCE_CALLBACK(cb) void CALLBACK cb(void)
#else
#include <new>
/* lazy initialisation */
+#ifdef WIN32
+static volatile OM_uint32 gssEapAttrProvidersInitStatus = GSS_S_UNAVAILABLE;
+#else
static GSSEAP_THREAD_ONCE gssEapAttrProvidersInitOnce = GSSEAP_ONCE_INITIALIZER;
static OM_uint32 gssEapAttrProvidersInitStatus = GSS_S_UNAVAILABLE;
+#endif
GSSEAP_ONCE_CALLBACK(gssEapAttrProvidersInitInternal)
{
GSSEAP_ASSERT(major == GSS_S_COMPLETE);
#endif
+#ifdef WIN32
+ InterlockedCompareExchangeRelease(&gssEapAttrProvidersInitStatus,
+ major, GSS_S_UNAVAILABLE);
+#else
gssEapAttrProvidersInitStatus = major;
+#endif
GSSEAP_ONCE_LEAVE;
}
static OM_uint32
gssEapAttrProvidersInit(OM_uint32 *minor)
{
+#ifdef WIN32
+ if (gssEapAttrProvidersInitStatus == GSS_S_UNAVAILABLE)
+ gssEapAttrProvidersInitInternal();
+#else
GSSEAP_ONCE(&gssEapAttrProvidersInitOnce, gssEapAttrProvidersInitInternal);
+#endif
if (GSS_ERROR(gssEapAttrProvidersInitStatus))
*minor = GSSEAP_NO_ATTR_PROVIDERS;