Module: wine Branch: master Commit: 4659f98314ca7b97f17bcafe0eae965b94eaeb5b URL: http://source.winehq.org/git/wine.git/?a=commit;h=4659f98314ca7b97f17bcafe0e...
Author: Vitaliy Margolen wine-patches@kievinfo.com Date: Mon May 14 19:56:48 2007 -0600
dinput: Prevent race between destroying the hook window and unloading the dll.
---
dlls/dinput/dinput_main.c | 34 ++++++++++++++++++---------------- 1 files changed, 18 insertions(+), 16 deletions(-)
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c index 789e6e7..402855e 100644 --- a/dlls/dinput/dinput_main.c +++ b/dlls/dinput/dinput_main.c @@ -753,6 +753,7 @@ static LRESULT CALLBACK dinput_hook_WndProc(HWND hWnd, UINT message, WPARAM wPar
static HWND hook_thread_hwnd; static LONG hook_thread_refcount; +static HANDLE hook_thread;
static const WCHAR classW[]={'H','o','o','k','_','L','L','_','C','L',0};
@@ -776,6 +777,7 @@ static DWORD WINAPI hook_thread_proc(void *param) } else ERR("Error creating message window\n");
+ UnregisterClassW(classW, DINPUT_instance); return 0; }
@@ -791,39 +793,36 @@ static CRITICAL_SECTION dinput_hook_crit = { &dinput_critsect_debug, -1, 0, 0, 0 static BOOL create_hook_thread(void) { LONG ref; - static ATOM class_atom;
EnterCriticalSection(&dinput_hook_crit);
- if (!class_atom) + ref = ++hook_thread_refcount; + TRACE("Refcount %d\n", ref); + if (ref == 1) { + DWORD tid; + HANDLE event; + + /* Create window class */ WNDCLASSEXW wcex; memset(&wcex, 0, sizeof(wcex)); wcex.cbSize = sizeof(wcex); wcex.lpfnWndProc = dinput_hook_WndProc; wcex.lpszClassName = classW; - wcex.hInstance = GetModuleHandleW(0); - if (!(class_atom = RegisterClassExW(&wcex))) ERR("Error registering window class\n"); - } - - ref = ++hook_thread_refcount; - TRACE("Refcount %d\n", ref); - if (ref == 1) - { - DWORD tid; - HANDLE thread, event; + wcex.hInstance = DINPUT_instance; + if (!RegisterClassExW(&wcex)) + ERR("Error registering window class\n");
event = CreateEventW(NULL, FALSE, FALSE, NULL); - thread = CreateThread(NULL, 0, hook_thread_proc, &event, 0, &tid); - if (event && thread) + hook_thread = CreateThread(NULL, 0, hook_thread_proc, &event, 0, &tid); + if (event && hook_thread) { HANDLE handles[2]; handles[0] = event; - handles[1] = thread; + handles[1] = hook_thread; WaitForMultipleObjects(2, handles, FALSE, INFINITE); } CloseHandle(event); - CloseHandle(thread); } LeaveCriticalSection(&dinput_hook_crit);
@@ -842,6 +841,9 @@ static void release_hook_thread(void) HWND hwnd = hook_thread_hwnd; hook_thread_hwnd = 0; SendMessageW(hwnd, WM_USER+0x10, 0, 0); + /* wait for hook thread to exit */ + WaitForSingleObject(hook_thread, INFINITE); + CloseHandle(hook_thread); } LeaveCriticalSection(&dinput_hook_crit); }