Vitaliy Margolen : dinput: Prevent race between destroying the hook window and unloading the dll.

Alexandre Julliard julliard at wine.codeweavers.com
Tue May 15 14:02:17 CDT 2007


Module: wine
Branch: master
Commit: 4659f98314ca7b97f17bcafe0eae965b94eaeb5b
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=4659f98314ca7b97f17bcafe0eae965b94eaeb5b

Author: Vitaliy Margolen <wine-patches at 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);
 }




More information about the wine-cvs mailing list