Module: wine Branch: master Commit: 9d5c801d353b02ed0cf3c03bf5c957bb4ffbecdc URL: https://source.winehq.org/git/wine.git/?a=commit;h=9d5c801d353b02ed0cf3c03bf...
Author: Piotr Caban piotr@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@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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);