+
+/* Also include init_once sanity test on Windows */
+#include "thread-w32.h"
+
+HANDLE init_semaphore;
+
+static void init_once_cb(void)
+{
+ tap_result(1, "init_once_cb start");
+
+ ReleaseSemaphore(init_semaphore, 2, NULL);
+ Sleep(1000);
+
+ tap_diag("init_once_cb exit");
+}
+
+static DWORD WINAPI init_thread(LPVOID p)
+{
+ WaitForSingleObject(init_semaphore, INFINITE);
+
+ tap_diag("init_thread start");
+ init_once();
+ tap_diag("init_thread exit");
+
+ return 0;
+}
+
+static void check_init_once(void)
+{
+ HANDLE threads[3];
+ DWORD rc;
+ int i;
+
+ if (!(init_semaphore = CreateSemaphore(NULL, 0, 10, NULL)))
+ tap_bail_out("check_init_once failed (%lu)", GetLastError());
+
+ if (!(threads[0] = CreateThread(NULL, 0, init_thread, NULL, 0, &rc)))
+ tap_bail_out("check_init_once failed (%lu)", GetLastError());
+ if (!(threads[1] = CreateThread(NULL, 0, init_thread, NULL, 0, &rc)))
+ tap_bail_out("check_init_once failed (%lu)", GetLastError());
+ if (!(threads[2] = CreateThread(NULL, 0, init_thread, NULL, 0, &rc)))
+ tap_bail_out("check_init_once failed (%lu)", GetLastError());
+
+ ReleaseSemaphore(init_semaphore, 1, NULL);
+ WaitForMultipleObjects(3, threads, TRUE, INFINITE);
+
+ for (i = 0; i < 3; i++)
+ CloseHandle(threads[i]);
+ CloseHandle(init_semaphore);
+
+ for (i = 0; i < 10000000; i++)
+ init_once();
+}
+
+