Revamped joystick locking

This makes the joystick locking more robust by holding the lock while updating joysticks.

The lock should be held when calling any SDL joystick function on a different thread than the one calling SDL_PumpEvents() and SDL_JoystickUpdate().

It is now possible to hold the lock while reinitializing the joystick subsystem, however any open joysticks will become invalid and potentially cause crashes if used afterwards.

Fixes https://github.com/libsdl-org/SDL/issues/6063
This commit is contained in:
Sam Lantinga
2022-08-30 11:42:13 -07:00
parent ff233fe306
commit 40bd4feedc
5 changed files with 138 additions and 115 deletions

View File

@@ -36,7 +36,6 @@
#include "SDL_endian.h"
#include "SDL_events.h"
#include "SDL_hints.h"
#include "SDL_mutex.h"
#include "SDL_timer.h"
#include "../usb_ids.h"
#include "../SDL_sysjoystick.h"
@@ -96,7 +95,6 @@ typedef struct WindowsGamingInputGamepadState WindowsGamingInputGamepadState;
static SDL_bool SDL_RAWINPUT_inited = SDL_FALSE;
static int SDL_RAWINPUT_numjoysticks = 0;
static SDL_mutex *SDL_RAWINPUT_mutex = NULL;
static void RAWINPUT_JoystickClose(SDL_Joystick *joystick);
@@ -865,7 +863,6 @@ RAWINPUT_JoystickInit(void)
return -1;
}
SDL_RAWINPUT_mutex = SDL_CreateMutex();
SDL_RAWINPUT_inited = SDL_TRUE;
if ((GetRawInputDeviceList(NULL, &device_count, sizeof(RAWINPUTDEVICELIST)) != -1) && device_count > 0) {
@@ -1927,7 +1924,7 @@ RAWINPUT_WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
LRESULT result = -1;
if (SDL_RAWINPUT_inited) {
SDL_LockMutex(SDL_RAWINPUT_mutex);
SDL_LockJoysticks();
switch (msg) {
case WM_INPUT_DEVICE_CHANGE:
@@ -1973,7 +1970,7 @@ RAWINPUT_WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
break;
}
SDL_UnlockMutex(SDL_RAWINPUT_mutex);
SDL_UnlockJoysticks();
}
if (result >= 0) {
@@ -1998,9 +1995,6 @@ RAWINPUT_JoystickQuit(void)
SDL_RAWINPUT_numjoysticks = 0;
SDL_RAWINPUT_inited = SDL_FALSE;
SDL_DestroyMutex(SDL_RAWINPUT_mutex);
SDL_RAWINPUT_mutex = NULL;
}
static SDL_bool