windows: Use a real synchronization primitive for CD detection thread init.
authorRyan C. Gordon <icculus@icculus.org>
Sat, 05 Aug 2017 01:24:53 -0400
changeset 1534 2035d523fc6f
parent 1533 49e7fb6d5b37
child 1535 9aad8ee469f5
windows: Use a real synchronization primitive for CD detection thread init. Before we were waiting on a volatile int in a tight loop with a Sleep(50).
src/physfs_platform_windows.c
--- a/src/physfs_platform_windows.c	Fri Aug 04 22:35:49 2017 -0400
+++ b/src/physfs_platform_windows.c	Sat Aug 05 01:24:53 2017 -0400
@@ -234,8 +234,7 @@
 #define deinitCDThread()
 #else
 static HANDLE detectCDThreadHandle = NULL;
-static HWND detectCDHwnd = 0;
-static volatile int initialDiscDetectionComplete = 0;
+static HWND detectCDHwnd = NULL;
 static volatile DWORD drivesWithMediaBitmap = 0;
 
 typedef BOOL (WINAPI *fnSTEM)(DWORD, LPDWORD b);
@@ -309,8 +308,9 @@
 } /* detectCDWndProc */
 
 
-static DWORD WINAPI detectCDThread(LPVOID lpParameter)
+static DWORD WINAPI detectCDThread(LPVOID arg)
 {
+    HANDLE initialDiscDetectionComplete = *((HANDLE *) arg);
     const char *classname = "PhysicsFSDetectCDCatcher";
     const char *winname = "PhysicsFSDetectCDMsgWindow";
     HINSTANCE hInstance = GetModuleHandleW(NULL);
@@ -326,7 +326,7 @@
     class_atom = RegisterClassExA(&wce);
     if (class_atom == 0)
     {
-        initialDiscDetectionComplete = 1;  /* let main thread go on. */
+        SetEvent(initialDiscDetectionComplete);  /* let main thread go on. */
         return 0;
     } /* if */
 
@@ -336,7 +336,7 @@
 
     if (detectCDHwnd == NULL)
     {
-        initialDiscDetectionComplete = 1;  /* let main thread go on. */
+        SetEvent(initialDiscDetectionComplete);  /* let main thread go on. */
         UnregisterClassA(classname, hInstance);
         return 0;
     } /* if */
@@ -345,8 +345,8 @@
 
     /* Do initial detection, possibly blocking awhile... */
     drivesWithMediaBitmap = pollDiscDrives();
-    /* !!! FIXME: atomic operation, please. */
-    initialDiscDetectionComplete = 1;  /* let main thread go on. */
+
+    SetEvent(initialDiscDetectionComplete);  /* let main thread go on. */
 
     do
     {
@@ -390,13 +390,18 @@
      */
     if (!detectCDThreadHandle)
     {
-        initialDiscDetectionComplete = 0;
-        detectCDThreadHandle = CreateThread(NULL,0,detectCDThread,NULL,0,NULL);
-        if (detectCDThreadHandle == NULL)
+        HANDLE initialDetectDone = CreateEvent(NULL, TRUE, FALSE, NULL);
+        if (!initialDetectDone)
             return;  /* oh well. */
 
-        while (!initialDiscDetectionComplete)
-            Sleep(50);
+        detectCDThreadHandle = CreateThread(NULL, 0, detectCDThread,
+                                            &initialDetectDone, 0, NULL);
+        if (detectCDThreadHandle)
+            WaitForSingleObject(initialDetectDone, INFINITE);
+        CloseHandle(initialDetectDone);
+
+        if (!detectCDThreadHandle)
+            return;  /* oh well. */
     } /* if */
 
     drives = drivesWithMediaBitmap; /* whatever the thread has seen, we take. */
@@ -418,7 +423,6 @@
             PostMessageW(detectCDHwnd, WM_QUIT, 0, 0);
         CloseHandle(detectCDThreadHandle);
         detectCDThreadHandle = NULL;
-        initialDiscDetectionComplete = 0;
         drivesWithMediaBitmap = 0;
     } /* if */
 } /* deinitCDThread */