[PATCH] dinput: Wait for the hook thread to exit when stopping it.

Rémi Bernon rbernon at codeweavers.com
Fri Mar 26 12:36:01 CDT 2021


FlatOut2 demo calls FreeLibrary on the dinput8 module more times than
it has loaded it, and the module reference that the internal thread has
is getting decremented before its exit.

Having an internal window to destroy also makes it more likely to crash
as it takes more time to exit calls the window procedure function.

Waiting for the thread to complete when all the dinput instances are
destroyed ensures that the thread isn't alive when the game frees the
DLL, and prevents the thread from crashing.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50673
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---

This could be nicer by using two critical sections instead (one for the
acquired devices and one for the hooks / dinput instance list), so the
hook thread never enters dinput_hook_crit, and we could wait here inside
it, but it's probably more future proof this way.

 dlls/dinput/dinput_main.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c
index 45023fc104a..5da60cf1f7c 100644
--- a/dlls/dinput/dinput_main.c
+++ b/dlls/dinput/dinput_main.c
@@ -1861,6 +1861,7 @@ static BOOL check_hook_thread(void)
 {
     static HANDLE hook_thread;
     HMODULE module;
+    HANDLE wait_handle = NULL;
 
     EnterCriticalSection(&dinput_hook_crit);
 
@@ -1884,11 +1885,17 @@ static BOOL check_hook_thread(void)
 
         hook_thread_id = 0;
         PostThreadMessageW(tid, WM_USER+0x10, 0, 0);
-        CloseHandle(hook_thread);
+        wait_handle = hook_thread;
         hook_thread = NULL;
     }
 
     LeaveCriticalSection(&dinput_hook_crit);
+
+    if (wait_handle)
+    {
+        WaitForSingleObject(wait_handle, INFINITE);
+        CloseHandle(wait_handle);
+    }
     return hook_thread_id != 0;
 }
 
-- 
2.30.2




More information about the wine-devel mailing list