diff --git a/include/SDL3/SDL_joystick.h b/include/SDL3/SDL_joystick.h index f0ecc0428f..e3bf5988c2 100644 --- a/include/SDL3/SDL_joystick.h +++ b/include/SDL3/SDL_joystick.h @@ -81,7 +81,7 @@ extern "C" { * help Clang's thread safety analysis tools to function. Do not attempt * to access this symbol from your app, it will not work! */ -extern SDL_Mutex *SDL_joystick_lock; +extern SDL_Mutex *SDL_event_lock; #endif /** @@ -186,7 +186,7 @@ typedef enum SDL_JoystickConnectionState * * \since This function is available since SDL 3.2.0. */ -extern SDL_DECLSPEC void SDLCALL SDL_LockJoysticks(void) SDL_ACQUIRE(SDL_joystick_lock); +extern SDL_DECLSPEC void SDLCALL SDL_LockJoysticks(void) SDL_ACQUIRE(SDL_event_lock); /** * Locking for atomic access to the joystick API. @@ -201,7 +201,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_LockJoysticks(void) SDL_ACQUIRE(SDL_joystic * * \since This function is available since SDL 3.6.0. */ -extern SDL_DECLSPEC bool SDLCALL SDL_TryLockJoysticks(void) SDL_ACQUIRE(SDL_joystick_lock); +extern SDL_DECLSPEC bool SDLCALL SDL_TryLockJoysticks(void) SDL_TRY_ACQUIRE(true, SDL_event_lock); /** * Unlocking for atomic access to the joystick API. @@ -211,7 +211,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_TryLockJoysticks(void) SDL_ACQUIRE(SDL_joys * * \since This function is available since SDL 3.2.0. */ -extern SDL_DECLSPEC void SDLCALL SDL_UnlockJoysticks(void) SDL_RELEASE(SDL_joystick_lock); +extern SDL_DECLSPEC void SDLCALL SDL_UnlockJoysticks(void) SDL_RELEASE(SDL_event_lock); /** * Return whether a joystick is currently connected. diff --git a/src/SDL.c b/src/SDL.c index 02d1e4e8c1..61d14bbff7 100644 --- a/src/SDL.c +++ b/src/SDL.c @@ -298,6 +298,7 @@ void SDL_InitMainThread(void) SDL_InitEnvironment(); SDL_InitTicks(); SDL_InitFilesystem(); + SDL_CreateEventLock(); if (!done_info) { const char *value; @@ -316,6 +317,7 @@ void SDL_InitMainThread(void) static void SDL_QuitMainThread(void) { + SDL_DestroyEventLock(); SDL_QuitFilesystem(); SDL_QuitTicks(); SDL_QuitEnvironment(); diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c index e2ef1a35f3..a0ed2fc3bf 100644 --- a/src/events/SDL_events.c +++ b/src/events/SDL_events.c @@ -161,6 +161,23 @@ static struct } SDL_EventQ = { NULL, false, { 0 }, 0, NULL, NULL, NULL }; +SDL_Mutex *SDL_event_lock = NULL; // This needs to support recursive locks + +void SDL_CreateEventLock(void) +{ + if (!SDL_event_lock) { + SDL_event_lock = SDL_CreateMutex(); + } +} + +void SDL_DestroyEventLock(void) +{ + if (SDL_event_lock) { + SDL_DestroyMutex(SDL_event_lock); + SDL_event_lock = NULL; + } +} + static void SDL_CleanupTemporaryMemory(void *data) { SDL_TemporaryMemoryState *state = (SDL_TemporaryMemoryState *)data; @@ -965,8 +982,9 @@ void SDL_StopEventLoop(void) const char *report = SDL_GetHint("SDL_EVENT_QUEUE_STATISTICS"); int i; SDL_EventEntry *entry; + SDL_Mutex *lock = SDL_EventQ.lock; - SDL_LockMutex(SDL_EventQ.lock); + SDL_LockMutex(lock); SDL_EventQ.active = false; @@ -1004,17 +1022,10 @@ void SDL_StopEventLoop(void) SDL_QuitEventWatchList(&SDL_event_watchers); SDL_QuitWindowEventWatch(); - SDL_Mutex *lock = NULL; - if (SDL_EventQ.lock) { - lock = SDL_EventQ.lock; - SDL_EventQ.lock = NULL; - } + SDL_EventQ.lock = NULL; SDL_UnlockMutex(lock); - - if (lock) { - SDL_DestroyMutex(lock); - } + SDL_DestroyMutex(lock); } // This function (and associated calls) may be called more than once @@ -1833,7 +1844,7 @@ bool SDL_PushEvent(SDL_Event *event) void SDL_SetEventFilter(SDL_EventFilter filter, void *userdata) { SDL_EventEntry *event, *next; - SDL_LockMutex(SDL_event_watchers.lock); + SDL_LockMutex(SDL_event_lock); { // Set filter and discard pending events SDL_event_watchers.filter.callback = filter; @@ -1852,18 +1863,18 @@ void SDL_SetEventFilter(SDL_EventFilter filter, void *userdata) SDL_UnlockMutex(SDL_EventQ.lock); } } - SDL_UnlockMutex(SDL_event_watchers.lock); + SDL_UnlockMutex(SDL_event_lock); } bool SDL_GetEventFilter(SDL_EventFilter *filter, void **userdata) { SDL_EventWatcher event_ok; - SDL_LockMutex(SDL_event_watchers.lock); + SDL_LockMutex(SDL_event_lock); { event_ok = SDL_event_watchers.filter; } - SDL_UnlockMutex(SDL_event_watchers.lock); + SDL_UnlockMutex(SDL_event_lock); if (filter) { *filter = event_ok.callback; diff --git a/src/events/SDL_events_c.h b/src/events/SDL_events_c.h index 377b04ec17..cfb467b9ed 100644 --- a/src/events/SDL_events_c.h +++ b/src/events/SDL_events_c.h @@ -36,6 +36,15 @@ #include "SDL_pen_c.h" #include "SDL_windowevents_c.h" +// The event mutex +// +// This mutex prevents multiple threads from watching multiple events +// simultaneously and also protects resources like joysticks that may +// be accessed from multiple threads and also generate events. +extern SDL_Mutex *SDL_event_lock; +extern void SDL_CreateEventLock(void); +extern void SDL_DestroyEventLock(void); + // Start and stop the event processing loop extern bool SDL_StartEventLoop(void); extern void SDL_StopEventLoop(void); diff --git a/src/events/SDL_eventwatch.c b/src/events/SDL_eventwatch.c index 5d0ff35317..434f730751 100644 --- a/src/events/SDL_eventwatch.c +++ b/src/events/SDL_eventwatch.c @@ -21,25 +21,16 @@ #include "SDL_internal.h" #include "SDL_eventwatch_c.h" +#include "SDL_events_c.h" bool SDL_InitEventWatchList(SDL_EventWatchList *list) { - if (list->lock == NULL) { - list->lock = SDL_CreateMutex(); - if (list->lock == NULL) { - return false; - } - } return true; } void SDL_QuitEventWatchList(SDL_EventWatchList *list) { - if (list->lock) { - SDL_DestroyMutex(list->lock); - list->lock = NULL; - } if (list->watchers) { SDL_free(list->watchers); list->watchers = NULL; @@ -56,13 +47,13 @@ bool SDL_DispatchEventWatchList(SDL_EventWatchList *list, SDL_Event *event) return true; } - SDL_LockMutex(list->lock); + SDL_LockMutex(SDL_event_lock); { // Make sure we only dispatch the current watcher list int i, count = list->count; if (filter->callback && !filter->callback(filter->userdata, event)) { - SDL_UnlockMutex(list->lock); + SDL_UnlockMutex(SDL_event_lock); return false; } @@ -86,7 +77,7 @@ bool SDL_DispatchEventWatchList(SDL_EventWatchList *list, SDL_Event *event) list->removed = false; } } - SDL_UnlockMutex(list->lock); + SDL_UnlockMutex(SDL_event_lock); return true; } @@ -95,7 +86,7 @@ bool SDL_AddEventWatchList(SDL_EventWatchList *list, SDL_EventFilter filter, voi { bool result = true; - SDL_LockMutex(list->lock); + SDL_LockMutex(SDL_event_lock); { SDL_EventWatcher *watchers; @@ -113,14 +104,14 @@ bool SDL_AddEventWatchList(SDL_EventWatchList *list, SDL_EventFilter filter, voi result = false; } } - SDL_UnlockMutex(list->lock); + SDL_UnlockMutex(SDL_event_lock); return result; } void SDL_RemoveEventWatchList(SDL_EventWatchList *list, SDL_EventFilter filter, void *userdata) { - SDL_LockMutex(list->lock); + SDL_LockMutex(SDL_event_lock); { int i; @@ -139,5 +130,5 @@ void SDL_RemoveEventWatchList(SDL_EventWatchList *list, SDL_EventFilter filter, } } } - SDL_UnlockMutex(list->lock); + SDL_UnlockMutex(SDL_event_lock); } diff --git a/src/events/SDL_eventwatch_c.h b/src/events/SDL_eventwatch_c.h index 5c382a7cae..e004809f37 100644 --- a/src/events/SDL_eventwatch_c.h +++ b/src/events/SDL_eventwatch_c.h @@ -29,7 +29,6 @@ typedef struct SDL_EventWatcher typedef struct SDL_EventWatchList { - SDL_Mutex *lock; SDL_EventWatcher filter; SDL_EventWatcher *watchers; int count; diff --git a/src/events/SDL_touch.c b/src/events/SDL_touch.c index b8ebb78aee..17bcb93f0b 100644 --- a/src/events/SDL_touch.c +++ b/src/events/SDL_touch.c @@ -25,21 +25,20 @@ #include "SDL_events_c.h" #include "../video/SDL_sysvideo.h" -static SDL_Mutex *SDL_touch_lock = NULL; // This needs to support recursive locks static int SDL_touch_locked = 0; struct SDL_Touch { - SDL_TouchID id SDL_GUARDED_BY(SDL_touch_lock); - SDL_TouchDeviceType type SDL_GUARDED_BY(SDL_touch_lock); - int num_fingers SDL_GUARDED_BY(SDL_touch_lock); - int max_fingers SDL_GUARDED_BY(SDL_touch_lock); - SDL_Finger **fingers SDL_GUARDED_BY(SDL_touch_lock); - char *name SDL_GUARDED_BY(SDL_touch_lock); + SDL_TouchID id SDL_GUARDED_BY(SDL_event_lock); + SDL_TouchDeviceType type SDL_GUARDED_BY(SDL_event_lock); + int num_fingers SDL_GUARDED_BY(SDL_event_lock); + int max_fingers SDL_GUARDED_BY(SDL_event_lock); + SDL_Finger **fingers SDL_GUARDED_BY(SDL_event_lock); + char *name SDL_GUARDED_BY(SDL_event_lock); }; -static int SDL_num_touch SDL_GUARDED_BY(SDL_touch_lock) = 0; -static SDL_Touch **SDL_touchDevices SDL_GUARDED_BY(SDL_touch_lock) = NULL; +static int SDL_num_touch SDL_GUARDED_BY(SDL_event_lock) = 0; +static SDL_Touch **SDL_touchDevices SDL_GUARDED_BY(SDL_event_lock) = NULL; // for mapping touch events to mice static bool finger_touching = false; @@ -49,23 +48,22 @@ static SDL_TouchID track_touchid; // Public functions bool SDL_InitTouch(void) { - SDL_touch_lock = SDL_CreateMutex(); return true; } -static void SDL_LockTouch(void) SDL_ACQUIRE(SDL_touch_lock) +static void SDL_LockTouch(void) SDL_ACQUIRE(SDL_event_lock) { - SDL_LockMutex(SDL_touch_lock); + SDL_LockMutex(SDL_event_lock); ++SDL_touch_locked; } -static void SDL_UnlockTouch(void) SDL_RELEASE(SDL_touch_lock) +static void SDL_UnlockTouch(void) SDL_RELEASE(SDL_event_lock) { --SDL_touch_locked; - SDL_UnlockMutex(SDL_touch_lock); + SDL_UnlockMutex(SDL_event_lock); } -static void SDL_AssertTouchLocked(void) SDL_ASSERT_CAPABILITY(SDL_touch_lock) +static void SDL_AssertTouchLocked(void) SDL_ASSERT_CAPABILITY(SDL_event_lock) { SDL_assert(SDL_touch_locked > 0); } @@ -614,9 +612,6 @@ void SDL_QuitTouch(void) SDL_touchDevices = NULL; } SDL_UnlockTouch(); - - SDL_DestroyMutex(SDL_touch_lock); - SDL_touch_lock = NULL; } int SDL_SendPinch(SDL_EventType type, Uint64 timestamp, SDL_Window *window, float scale) diff --git a/src/joystick/SDL_gamepad.c b/src/joystick/SDL_gamepad.c index 0a660c5633..4fd4a4711b 100644 --- a/src/joystick/SDL_gamepad.c +++ b/src/joystick/SDL_gamepad.c @@ -75,8 +75,8 @@ } while (0) static bool SDL_gamepads_initialized; -static SDL_Gamepad *SDL_gamepads SDL_GUARDED_BY(SDL_joystick_lock) = NULL; -static SDL_HashTable *SDL_gamepad_names SDL_GUARDED_BY(SDL_joystick_lock) = NULL; +static SDL_Gamepad *SDL_gamepads SDL_GUARDED_BY(SDL_event_lock) = NULL; +static SDL_HashTable *SDL_gamepad_names SDL_GUARDED_BY(SDL_event_lock) = NULL; // The face button style of a gamepad typedef enum @@ -96,7 +96,7 @@ typedef enum SDL_GAMEPAD_MAPPING_PRIORITY_USER, } SDL_GamepadMappingPriority; -#define _guarded SDL_GUARDED_BY(SDL_joystick_lock) +#define _guarded SDL_GUARDED_BY(SDL_event_lock) typedef struct GamepadMapping_t { @@ -121,13 +121,13 @@ typedef struct #undef _guarded static SDL_GUID s_zeroGUID; -static GamepadMapping_t *s_pSupportedGamepads SDL_GUARDED_BY(SDL_joystick_lock) = NULL; -static GamepadMapping_t *s_pDefaultMapping SDL_GUARDED_BY(SDL_joystick_lock) = NULL; -static GamepadMapping_t *s_pXInputMapping SDL_GUARDED_BY(SDL_joystick_lock) = NULL; -static MappingChangeTracker *s_mappingChangeTracker SDL_GUARDED_BY(SDL_joystick_lock) = NULL; -static SDL_HashTable *s_gamepadInstanceIDs SDL_GUARDED_BY(SDL_joystick_lock) = NULL; +static GamepadMapping_t *s_pSupportedGamepads SDL_GUARDED_BY(SDL_event_lock) = NULL; +static GamepadMapping_t *s_pDefaultMapping SDL_GUARDED_BY(SDL_event_lock) = NULL; +static GamepadMapping_t *s_pXInputMapping SDL_GUARDED_BY(SDL_event_lock) = NULL; +static MappingChangeTracker *s_mappingChangeTracker SDL_GUARDED_BY(SDL_event_lock) = NULL; +static SDL_HashTable *s_gamepadInstanceIDs SDL_GUARDED_BY(SDL_event_lock) = NULL; -#define _guarded SDL_GUARDED_BY(SDL_joystick_lock) +#define _guarded SDL_GUARDED_BY(SDL_event_lock) // The SDL gamepad structure struct SDL_Gamepad diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index 79c5997e21..22d92fac2d 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -114,19 +114,14 @@ static SDL_JoystickDriver *SDL_joystick_drivers[] = { #endif }; -#ifndef SDL_THREAD_SAFETY_ANALYSIS -static -#endif -SDL_Mutex *SDL_joystick_lock = NULL; // This needs to support recursive locks -static SDL_AtomicInt SDL_joystick_lock_pending; static int SDL_joysticks_locked; static bool SDL_joysticks_initialized; static bool SDL_joysticks_quitting; static bool SDL_joystick_being_added; -static SDL_Joystick *SDL_joysticks SDL_GUARDED_BY(SDL_joystick_lock) = NULL; -static int SDL_joystick_player_count SDL_GUARDED_BY(SDL_joystick_lock) = 0; -static SDL_JoystickID *SDL_joystick_players SDL_GUARDED_BY(SDL_joystick_lock) = NULL; -static SDL_HashTable *SDL_joystick_names SDL_GUARDED_BY(SDL_joystick_lock) = NULL; +static SDL_Joystick *SDL_joysticks SDL_GUARDED_BY(SDL_event_lock) = NULL; +static int SDL_joystick_player_count SDL_GUARDED_BY(SDL_event_lock) = 0; +static SDL_JoystickID *SDL_joystick_players SDL_GUARDED_BY(SDL_event_lock) = NULL; +static SDL_HashTable *SDL_joystick_names SDL_GUARDED_BY(SDL_event_lock) = NULL; static bool SDL_joystick_allows_background_events = false; static Uint32 initial_old_xboxone_controllers[] = { @@ -706,16 +701,13 @@ bool SDL_JoysticksQuitting(void) void SDL_LockJoysticks(void) { - (void)SDL_AtomicIncRef(&SDL_joystick_lock_pending); - SDL_LockMutex(SDL_joystick_lock); - (void)SDL_AtomicDecRef(&SDL_joystick_lock_pending); - + SDL_LockMutex(SDL_event_lock); ++SDL_joysticks_locked; } bool SDL_TryLockJoysticks(void) { - if (SDL_TryLockMutex(SDL_joystick_lock)) { + if (SDL_TryLockMutex(SDL_event_lock)) { ++SDL_joysticks_locked; return true; } @@ -724,34 +716,8 @@ bool SDL_TryLockJoysticks(void) void SDL_UnlockJoysticks(void) { - bool last_unlock = false; - --SDL_joysticks_locked; - - if (!SDL_joysticks_initialized) { - // NOTE: There's a small window here where another thread could lock the mutex after we've checked for pending locks - if (!SDL_joysticks_locked && SDL_GetAtomicInt(&SDL_joystick_lock_pending) == 0) { - last_unlock = true; - } - } - - /* The last unlock after joysticks are uninitialized will cleanup the mutex, - * allowing applications to lock joysticks while reinitializing the system. - */ - if (last_unlock) { - SDL_Mutex *joystick_lock = SDL_joystick_lock; - - SDL_LockMutex(joystick_lock); - { - SDL_UnlockMutex(SDL_joystick_lock); - - SDL_joystick_lock = NULL; - } - SDL_UnlockMutex(joystick_lock); - SDL_DestroyMutex(joystick_lock); - } else { - SDL_UnlockMutex(SDL_joystick_lock); - } + SDL_UnlockMutex(SDL_event_lock); } bool SDL_JoysticksLocked(void) @@ -892,11 +858,6 @@ bool SDL_InitJoysticks(void) int i; bool result = false; - // Create the joystick list lock - if (SDL_joystick_lock == NULL) { - SDL_joystick_lock = SDL_CreateMutex(); - } - if (!SDL_InitSubSystem(SDL_INIT_EVENTS)) { return false; } diff --git a/src/joystick/SDL_joystick_c.h b/src/joystick/SDL_joystick_c.h index b80fb6b651..69e42b0209 100644 --- a/src/joystick/SDL_joystick_c.h +++ b/src/joystick/SDL_joystick_c.h @@ -48,7 +48,7 @@ extern bool SDL_JoysticksQuitting(void); extern bool SDL_JoysticksLocked(void); // Make sure we currently have the joysticks locked -extern void SDL_AssertJoysticksLocked(void) SDL_ASSERT_CAPABILITY(SDL_joystick_lock); +extern void SDL_AssertJoysticksLocked(void) SDL_ASSERT_CAPABILITY(SDL_event_lock); // Function to return whether there are any joysticks opened by the application extern bool SDL_JoysticksOpened(void); diff --git a/src/joystick/SDL_steam_virtual_gamepad.c b/src/joystick/SDL_steam_virtual_gamepad.c index 7d1ef1a890..1a6079c669 100644 --- a/src/joystick/SDL_steam_virtual_gamepad.c +++ b/src/joystick/SDL_steam_virtual_gamepad.c @@ -33,11 +33,11 @@ #include #endif -static char *SDL_steam_virtual_gamepad_info_file SDL_GUARDED_BY(SDL_joystick_lock) = NULL; -static Uint64 SDL_steam_virtual_gamepad_info_file_mtime SDL_GUARDED_BY(SDL_joystick_lock) = 0; -static Uint64 SDL_steam_virtual_gamepad_info_check_time SDL_GUARDED_BY(SDL_joystick_lock) = 0; -static SDL_SteamVirtualGamepadInfo **SDL_steam_virtual_gamepad_info SDL_GUARDED_BY(SDL_joystick_lock) = NULL; -static int SDL_steam_virtual_gamepad_info_count SDL_GUARDED_BY(SDL_joystick_lock) = 0; +static char *SDL_steam_virtual_gamepad_info_file SDL_GUARDED_BY(SDL_event_lock) = NULL; +static Uint64 SDL_steam_virtual_gamepad_info_file_mtime SDL_GUARDED_BY(SDL_event_lock) = 0; +static Uint64 SDL_steam_virtual_gamepad_info_check_time SDL_GUARDED_BY(SDL_event_lock) = 0; +static SDL_SteamVirtualGamepadInfo **SDL_steam_virtual_gamepad_info SDL_GUARDED_BY(SDL_event_lock) = NULL; +static int SDL_steam_virtual_gamepad_info_count SDL_GUARDED_BY(SDL_event_lock) = 0; static Uint64 GetFileModificationTime(const char *file) diff --git a/src/joystick/SDL_sysjoystick.h b/src/joystick/SDL_sysjoystick.h index 76bce9006d..d428d50bd9 100644 --- a/src/joystick/SDL_sysjoystick.h +++ b/src/joystick/SDL_sysjoystick.h @@ -25,6 +25,7 @@ // This is the system specific header for the SDL joystick API #include "SDL_joystick_c.h" +#include "../events/SDL_events_c.h" // Set up for C function definitions, even when using C++ #ifdef __cplusplus @@ -78,7 +79,7 @@ typedef struct SDL_JoystickCapSenseInfo bool down; } SDL_JoystickCapSenseInfo; -#define _guarded SDL_GUARDED_BY(SDL_joystick_lock) +#define _guarded SDL_GUARDED_BY(SDL_event_lock) struct SDL_Joystick { diff --git a/src/joystick/hidapi/SDL_hidapijoystick.c b/src/joystick/hidapi/SDL_hidapijoystick.c index c8bca941aa..2ab43b2c83 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick.c +++ b/src/joystick/hidapi/SDL_hidapijoystick.c @@ -117,7 +117,7 @@ static int SDL_HIDAPI_numdrivers = 0; static SDL_AtomicInt SDL_HIDAPI_updating_devices; static bool SDL_HIDAPI_hints_changed = false; static Uint32 SDL_HIDAPI_change_count = 0; -static SDL_HIDAPI_Device *SDL_HIDAPI_devices SDL_GUARDED_BY(SDL_joystick_lock); +static SDL_HIDAPI_Device *SDL_HIDAPI_devices SDL_GUARDED_BY(SDL_event_lock); static int SDL_HIDAPI_numjoysticks = 0; static bool SDL_HIDAPI_combine_joycons = true; static bool initialized = false; diff --git a/src/joystick/linux/SDL_sysjoystick.c b/src/joystick/linux/SDL_sysjoystick.c index ede0d5efdc..1c3cdf916f 100644 --- a/src/joystick/linux/SDL_sysjoystick.c +++ b/src/joystick/linux/SDL_sysjoystick.c @@ -186,10 +186,10 @@ typedef struct SDL_sensorlist_item } SDL_sensorlist_item; static bool SDL_classic_joysticks = false; -static SDL_joylist_item *SDL_joylist SDL_GUARDED_BY(SDL_joystick_lock) = NULL; -static SDL_joylist_item *SDL_joylist_tail SDL_GUARDED_BY(SDL_joystick_lock) = NULL; -static int numjoysticks SDL_GUARDED_BY(SDL_joystick_lock) = 0; -static SDL_sensorlist_item *SDL_sensorlist SDL_GUARDED_BY(SDL_joystick_lock) = NULL; +static SDL_joylist_item *SDL_joylist SDL_GUARDED_BY(SDL_event_lock) = NULL; +static SDL_joylist_item *SDL_joylist_tail SDL_GUARDED_BY(SDL_event_lock) = NULL; +static int numjoysticks SDL_GUARDED_BY(SDL_event_lock) = 0; +static SDL_sensorlist_item *SDL_sensorlist SDL_GUARDED_BY(SDL_event_lock) = NULL; static int inotify_fd = -1; static Uint64 last_joy_detect_time; diff --git a/src/joystick/virtual/SDL_virtualjoystick.c b/src/joystick/virtual/SDL_virtualjoystick.c index 2655dbd830..a5c7be9c1a 100644 --- a/src/joystick/virtual/SDL_virtualjoystick.c +++ b/src/joystick/virtual/SDL_virtualjoystick.c @@ -28,7 +28,7 @@ #include "../SDL_sysjoystick.h" #include "../SDL_joystick_c.h" -static joystick_hwdata *g_VJoys SDL_GUARDED_BY(SDL_joystick_lock) = NULL; +static joystick_hwdata *g_VJoys SDL_GUARDED_BY(SDL_event_lock) = NULL; static joystick_hwdata *VIRTUAL_HWDataForInstance(SDL_JoystickID instance_id) { diff --git a/src/sensor/SDL_sensor.c b/src/sensor/SDL_sensor.c index d3eb58fbf4..9091fb44c6 100644 --- a/src/sensor/SDL_sensor.c +++ b/src/sensor/SDL_sensor.c @@ -51,14 +51,9 @@ static SDL_SensorDriver *SDL_sensor_drivers[] = { #endif }; -#ifndef SDL_THREAD_SAFETY_ANALYSIS -static -#endif -SDL_Mutex *SDL_sensor_lock = NULL; // This needs to support recursive locks -static SDL_AtomicInt SDL_sensor_lock_pending; static int SDL_sensors_locked; static bool SDL_sensors_initialized; -static SDL_Sensor *SDL_sensors SDL_GUARDED_BY(SDL_sensor_lock) = NULL; +static SDL_Sensor *SDL_sensors SDL_GUARDED_BY(SDL_event_lock) = NULL; #define CHECK_SENSOR_MAGIC(sensor, result) \ CHECK_PARAM(!SDL_ObjectValid(sensor, SDL_OBJECT_TYPE_SENSOR)) { \ @@ -74,43 +69,14 @@ bool SDL_SensorsInitialized(void) void SDL_LockSensors(void) { - (void)SDL_AtomicIncRef(&SDL_sensor_lock_pending); - SDL_LockMutex(SDL_sensor_lock); - (void)SDL_AtomicDecRef(&SDL_sensor_lock_pending); - + SDL_LockMutex(SDL_event_lock); ++SDL_sensors_locked; } void SDL_UnlockSensors(void) { - bool last_unlock = false; - --SDL_sensors_locked; - - if (!SDL_sensors_initialized) { - // NOTE: There's a small window here where another thread could lock the mutex after we've checked for pending locks - if (!SDL_sensors_locked && SDL_GetAtomicInt(&SDL_sensor_lock_pending) == 0) { - last_unlock = true; - } - } - - /* The last unlock after sensors are uninitialized will cleanup the mutex, - * allowing applications to lock sensors while reinitializing the system. - */ - if (last_unlock) { - SDL_Mutex *sensor_lock = SDL_sensor_lock; - - SDL_LockMutex(sensor_lock); - { - SDL_UnlockMutex(SDL_sensor_lock); - - SDL_sensor_lock = NULL; - } - SDL_UnlockMutex(sensor_lock); - SDL_DestroyMutex(sensor_lock); - } else { - SDL_UnlockMutex(SDL_sensor_lock); - } + SDL_UnlockMutex(SDL_event_lock); } bool SDL_SensorsLocked(void) @@ -128,11 +94,6 @@ bool SDL_InitSensors(void) int i; bool status; - // Create the sensor list lock - if (SDL_sensor_lock == NULL) { - SDL_sensor_lock = SDL_CreateMutex(); - } - if (!SDL_InitSubSystem(SDL_INIT_EVENTS)) { return false; } diff --git a/src/sensor/SDL_sensor_c.h b/src/sensor/SDL_sensor_c.h index 90c05d4ec6..ec6a138636 100644 --- a/src/sensor/SDL_sensor_c.h +++ b/src/sensor/SDL_sensor_c.h @@ -23,10 +23,6 @@ #ifndef SDL_sensor_c_h_ #define SDL_sensor_c_h_ -#ifdef SDL_THREAD_SAFETY_ANALYSIS -extern SDL_Mutex *SDL_sensor_lock; -#endif - struct SDL_SensorDriver; // Useful functions and variables from SDL_sensor.c @@ -42,10 +38,10 @@ extern bool SDL_SensorsInitialized(void); extern bool SDL_SensorsLocked(void); // Make sure we currently have the sensors locked -extern void SDL_AssertSensorsLocked(void) SDL_ASSERT_CAPABILITY(SDL_sensor_lock); +extern void SDL_AssertSensorsLocked(void) SDL_ASSERT_CAPABILITY(SDL_event_lock); -extern void SDL_LockSensors(void) SDL_ACQUIRE(SDL_sensor_lock); -extern void SDL_UnlockSensors(void) SDL_RELEASE(SDL_sensor_lock); +extern void SDL_LockSensors(void) SDL_ACQUIRE(SDL_event_lock); +extern void SDL_UnlockSensors(void) SDL_RELEASE(SDL_event_lock); // Function to return whether there are any sensors opened by the application extern bool SDL_SensorsOpened(void); diff --git a/src/sensor/SDL_syssensor.h b/src/sensor/SDL_syssensor.h index 6c6ccf83c7..7452d9d6ea 100644 --- a/src/sensor/SDL_syssensor.h +++ b/src/sensor/SDL_syssensor.h @@ -26,8 +26,9 @@ // This is the system specific header for the SDL sensor API #include "SDL_sensor_c.h" +#include "../events/SDL_events_c.h" -#define _guarded SDL_GUARDED_BY(SDL_sensor_lock) +#define _guarded SDL_GUARDED_BY(SDL_event_lock) // The SDL sensor structure struct SDL_Sensor