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).
This commit is contained in:
Ryan C. Gordon 2017-08-05 01:24:53 -04:00
parent befc894b1f
commit be9bf023d0
1 changed files with 17 additions and 13 deletions

View File

@ -234,8 +234,7 @@ static inline PHYSFS_ErrorCode errcodeFromWinApi(void)
#define deinitCDThread() #define deinitCDThread()
#else #else
static HANDLE detectCDThreadHandle = NULL; static HANDLE detectCDThreadHandle = NULL;
static HWND detectCDHwnd = 0; static HWND detectCDHwnd = NULL;
static volatile int initialDiscDetectionComplete = 0;
static volatile DWORD drivesWithMediaBitmap = 0; static volatile DWORD drivesWithMediaBitmap = 0;
typedef BOOL (WINAPI *fnSTEM)(DWORD, LPDWORD b); typedef BOOL (WINAPI *fnSTEM)(DWORD, LPDWORD b);
@ -309,8 +308,9 @@ static LRESULT CALLBACK detectCDWndProc(HWND hwnd, UINT msg,
} /* detectCDWndProc */ } /* detectCDWndProc */
static DWORD WINAPI detectCDThread(LPVOID lpParameter) static DWORD WINAPI detectCDThread(LPVOID arg)
{ {
HANDLE initialDiscDetectionComplete = *((HANDLE *) arg);
const char *classname = "PhysicsFSDetectCDCatcher"; const char *classname = "PhysicsFSDetectCDCatcher";
const char *winname = "PhysicsFSDetectCDMsgWindow"; const char *winname = "PhysicsFSDetectCDMsgWindow";
HINSTANCE hInstance = GetModuleHandleW(NULL); HINSTANCE hInstance = GetModuleHandleW(NULL);
@ -326,7 +326,7 @@ static DWORD WINAPI detectCDThread(LPVOID lpParameter)
class_atom = RegisterClassExA(&wce); class_atom = RegisterClassExA(&wce);
if (class_atom == 0) if (class_atom == 0)
{ {
initialDiscDetectionComplete = 1; /* let main thread go on. */ SetEvent(initialDiscDetectionComplete); /* let main thread go on. */
return 0; return 0;
} /* if */ } /* if */
@ -336,7 +336,7 @@ static DWORD WINAPI detectCDThread(LPVOID lpParameter)
if (detectCDHwnd == NULL) if (detectCDHwnd == NULL)
{ {
initialDiscDetectionComplete = 1; /* let main thread go on. */ SetEvent(initialDiscDetectionComplete); /* let main thread go on. */
UnregisterClassA(classname, hInstance); UnregisterClassA(classname, hInstance);
return 0; return 0;
} /* if */ } /* if */
@ -345,8 +345,8 @@ static DWORD WINAPI detectCDThread(LPVOID lpParameter)
/* Do initial detection, possibly blocking awhile... */ /* Do initial detection, possibly blocking awhile... */
drivesWithMediaBitmap = pollDiscDrives(); drivesWithMediaBitmap = pollDiscDrives();
/* !!! FIXME: atomic operation, please. */
initialDiscDetectionComplete = 1; /* let main thread go on. */ SetEvent(initialDiscDetectionComplete); /* let main thread go on. */
do do
{ {
@ -390,13 +390,18 @@ static void detectAvailableCDs(PHYSFS_StringCallback cb, void *data)
*/ */
if (!detectCDThreadHandle) if (!detectCDThreadHandle)
{ {
initialDiscDetectionComplete = 0; HANDLE initialDetectDone = CreateEvent(NULL, TRUE, FALSE, NULL);
detectCDThreadHandle = CreateThread(NULL,0,detectCDThread,NULL,0,NULL); if (!initialDetectDone)
if (detectCDThreadHandle == NULL)
return; /* oh well. */ return; /* oh well. */
while (!initialDiscDetectionComplete) detectCDThreadHandle = CreateThread(NULL, 0, detectCDThread,
Sleep(50); &initialDetectDone, 0, NULL);
if (detectCDThreadHandle)
WaitForSingleObject(initialDetectDone, INFINITE);
CloseHandle(initialDetectDone);
if (!detectCDThreadHandle)
return; /* oh well. */
} /* if */ } /* if */
drives = drivesWithMediaBitmap; /* whatever the thread has seen, we take. */ drives = drivesWithMediaBitmap; /* whatever the thread has seen, we take. */
@ -418,7 +423,6 @@ static void deinitCDThread(void)
PostMessageW(detectCDHwnd, WM_QUIT, 0, 0); PostMessageW(detectCDHwnd, WM_QUIT, 0, 0);
CloseHandle(detectCDThreadHandle); CloseHandle(detectCDThreadHandle);
detectCDThreadHandle = NULL; detectCDThreadHandle = NULL;
initialDiscDetectionComplete = 0;
drivesWithMediaBitmap = 0; drivesWithMediaBitmap = 0;
} /* if */ } /* if */
} /* deinitCDThread */ } /* deinitCDThread */