Piotr Caban : winebus.sys: Stop SDL deviceloop_thread to avoid crash on driver unload.
Alexandre Julliard
julliard at winehq.org
Fri Sep 27 15:56:29 CDT 2019
Module: wine
Branch: master
Commit: 9d5c801d353b02ed0cf3c03bf5c957bb4ffbecdc
URL: https://source.winehq.org/git/wine.git/?a=commit;h=9d5c801d353b02ed0cf3c03bf5c957bb4ffbecdc
Author: Piotr Caban <piotr at codeweavers.com>
Date: Fri Sep 27 12:37:52 2019 +0200
winebus.sys: Stop SDL deviceloop_thread to avoid crash on driver unload.
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/winebus.sys/bus_sdl.c | 43 +++++++++++++++++++++++++++++++++++++------
1 file changed, 37 insertions(+), 6 deletions(-)
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c
index 8fcec46d04..64c5a8a1d2 100644
--- a/dlls/winebus.sys/bus_sdl.c
+++ b/dlls/winebus.sys/bus_sdl.c
@@ -70,6 +70,8 @@ static DWORD map_controllers = 0;
DEFINE_GUID(GUID_DEVCLASS_SDL, 0x463d60b5,0x802b,0x4bb2,0x8f,0xdb,0x7d,0xa9,0xb9,0x96,0x04,0xd8);
static void *sdl_handle = NULL;
+static HANDLE deviceloop_handle;
+static UINT quit_event = -1;
#ifdef SONAME_LIBSDL2
#define MAKE_FUNCPTR(f) static typeof(f) * p##f = NULL
@@ -109,6 +111,8 @@ MAKE_FUNCPTR(SDL_HapticStopAll);
MAKE_FUNCPTR(SDL_JoystickIsHaptic);
MAKE_FUNCPTR(SDL_memset);
MAKE_FUNCPTR(SDL_GameControllerAddMapping);
+MAKE_FUNCPTR(SDL_RegisterEvents);
+MAKE_FUNCPTR(SDL_PushEvent);
#endif
static Uint16 (*pSDL_JoystickGetProduct)(SDL_Joystick * joystick);
static Uint16 (*pSDL_JoystickGetProductVersion)(SDL_Joystick * joystick);
@@ -1075,17 +1079,41 @@ static DWORD CALLBACK deviceloop_thread(void *args)
SetEvent(init_done);
- while (1)
- while (pSDL_WaitEvent(&event) != 0)
+ while (1) {
+ while (pSDL_WaitEvent(&event) != 0) {
+ if (event.type == quit_event) {
+ TRACE("Device thread exiting\n");
+ return 0;
+ }
process_device_event(&event);
-
- TRACE("Device thread exiting\n");
- return 0;
+ }
+ }
}
void sdl_driver_unload( void )
{
+ SDL_Event event;
+
TRACE("Unload Driver\n");
+
+ if (!deviceloop_handle)
+ return;
+
+ quit_event = pSDL_RegisterEvents(1);
+ if (quit_event == -1) {
+ ERR("error registering quit event\n");
+ return;
+ }
+
+ event.type = quit_event;
+ if (pSDL_PushEvent(&event) != 1) {
+ ERR("error pushing quit event\n");
+ return;
+ }
+
+ WaitForSingleObject(deviceloop_handle, INFINITE);
+ CloseHandle(deviceloop_handle);
+ wine_dlclose(sdl_handle, NULL, 0);
}
NTSTATUS sdl_driver_init(void)
@@ -1140,6 +1168,8 @@ NTSTATUS sdl_driver_init(void)
LOAD_FUNCPTR(SDL_JoystickIsHaptic);
LOAD_FUNCPTR(SDL_memset);
LOAD_FUNCPTR(SDL_GameControllerAddMapping);
+ LOAD_FUNCPTR(SDL_RegisterEvents);
+ LOAD_FUNCPTR(SDL_PushEvent);
#undef LOAD_FUNCPTR
pSDL_JoystickGetProduct = wine_dlsym(sdl_handle, "SDL_JoystickGetProduct", NULL, 0);
pSDL_JoystickGetProductVersion = wine_dlsym(sdl_handle, "SDL_JoystickGetProductVersion", NULL, 0);
@@ -1162,12 +1192,13 @@ NTSTATUS sdl_driver_init(void)
result = WaitForMultipleObjects(2, events, FALSE, INFINITE);
CloseHandle(events[0]);
- CloseHandle(events[1]);
if (result == WAIT_OBJECT_0)
{
TRACE("Initialization successful\n");
+ deviceloop_handle = events[1];
return STATUS_SUCCESS;
}
+ CloseHandle(events[1]);
sym_not_found:
wine_dlclose(sdl_handle, NULL, 0);
More information about the wine-cvs
mailing list