Commit d90fce3c9eee0b80189f5e3a5f18c2f7a1ab8a37

Sam Lantinga 2017-10-10T11:10:15

Exposed the joystick locking functions for multi-threaded access to the joystick API

diff --git a/include/SDL_joystick.h b/include/SDL_joystick.h
index 698b09c..f598dc8 100644
--- a/include/SDL_joystick.h
+++ b/include/SDL_joystick.h
@@ -106,6 +106,20 @@ typedef enum
 } SDL_JoystickPowerLevel;
 
 /* Function prototypes */
+
+/**
+ * Locking for multi-threaded access to the joystick API
+ *
+ * If you are using the joystick API or handling events from multiple threads
+ * you should use these locking functions to protect access to the joysticks.
+ *
+ * In particular, you are guaranteed that the joystick list won't change, so
+ * the API functions that take a joystick index will be valid, and joystick
+ * and game controller events will not be delivered.
+ */
+extern DECLSPEC void SDLCALL SDL_LockJoysticks(void);
+extern DECLSPEC void SDLCALL SDL_UnlockJoysticks(void);
+
 /**
  *  Count the number of joysticks attached to the system right now
  */
diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h
index 95943bc..3ef56d2 100644
--- a/src/dynapi/SDL_dynapi_overrides.h
+++ b/src/dynapi/SDL_dynapi_overrides.h
@@ -635,3 +635,5 @@
 #define SDL_Vulkan_GetInstanceExtensions SDL_Vulkan_GetInstanceExtensions_REAL
 #define SDL_Vulkan_CreateSurface SDL_Vulkan_CreateSurface_REAL
 #define SDL_Vulkan_GetDrawableSize SDL_Vulkan_GetDrawableSize_REAL
+#define SDL_LockJoysticks SDL_LockJoysticks_REAL
+#define SDL_UnlockJoysticks SDL_UnlockJoysticks_REAL
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index b7466fd..730fbcc 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -669,3 +669,5 @@ SDL_DYNAPI_PROC(void,SDL_Vulkan_UnloadLibrary,(void),(),)
 SDL_DYNAPI_PROC(SDL_bool,SDL_Vulkan_GetInstanceExtensions,(SDL_Window *a, unsigned int *b, const char **c),(a,b,c),return)
 SDL_DYNAPI_PROC(SDL_bool,SDL_Vulkan_CreateSurface,(SDL_Window *a, VkInstance b, VkSurfaceKHR *c),(a,b,c),return)
 SDL_DYNAPI_PROC(void,SDL_Vulkan_GetDrawableSize,(SDL_Window *a, int *b, int *c),(a,b,c),)
+SDL_DYNAPI_PROC(void,SDL_LockJoysticks,(void),(),)
+SDL_DYNAPI_PROC(void,SDL_UnlockJoysticks,(void),(),)
diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c
index 0802c88..13953de 100644
--- a/src/joystick/SDL_gamecontroller.c
+++ b/src/joystick/SDL_gamecontroller.c
@@ -24,9 +24,9 @@
 
 #include "SDL_events.h"
 #include "SDL_assert.h"
+#include "SDL_hints.h"
 #include "SDL_sysjoystick.h"
 #include "SDL_joystick_c.h"
-#include "SDL_hints.h"
 #include "SDL_gamecontrollerdb.h"
 
 #if !SDL_EVENTS_DISABLED
@@ -910,7 +910,7 @@ static ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index)
     SDL_JoystickGUID guid;
     ControllerMapping_t *mapping;
 
-    SDL_LockJoystickList();
+    SDL_LockJoysticks();
     name = SDL_JoystickNameForIndex(device_index);
     guid = SDL_JoystickGetDeviceGUID(device_index);
     mapping = SDL_PrivateGetControllerMappingForNameAndGUID(name, guid);
@@ -919,7 +919,7 @@ static ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index)
         mapping = s_pXInputMapping;
     }
 #endif
-    SDL_UnlockJoystickList();
+    SDL_UnlockJoysticks();
     return mapping;
 }
 
@@ -1349,7 +1349,7 @@ SDL_GameControllerOpen(int device_index)
         return (NULL);
     }
 
-    SDL_LockJoystickList();
+    SDL_LockJoysticks();
 
     gamecontrollerlist = SDL_gamecontrollers;
     /* If the controller is already open, return it */
@@ -1357,7 +1357,7 @@ SDL_GameControllerOpen(int device_index)
         if (SDL_SYS_GetInstanceIdOfDeviceIndex(device_index) == gamecontrollerlist->joystick->instance_id) {
                 gamecontroller = gamecontrollerlist;
                 ++gamecontroller->ref_count;
-                SDL_UnlockJoystickList();
+                SDL_UnlockJoysticks();
                 return (gamecontroller);
         }
         gamecontrollerlist = gamecontrollerlist->next;
@@ -1367,7 +1367,7 @@ SDL_GameControllerOpen(int device_index)
     pSupportedController =  SDL_PrivateGetControllerMapping(device_index);
     if (!pSupportedController) {
         SDL_SetError("Couldn't find mapping for device (%d)", device_index);
-        SDL_UnlockJoystickList();
+        SDL_UnlockJoysticks();
         return NULL;
     }
 
@@ -1375,14 +1375,14 @@ SDL_GameControllerOpen(int device_index)
     gamecontroller = (SDL_GameController *) SDL_calloc(1, sizeof(*gamecontroller));
     if (gamecontroller == NULL) {
         SDL_OutOfMemory();
-        SDL_UnlockJoystickList();
+        SDL_UnlockJoysticks();
         return NULL;
     }
 
     gamecontroller->joystick = SDL_JoystickOpen(device_index);
     if (!gamecontroller->joystick) {
         SDL_free(gamecontroller);
-        SDL_UnlockJoystickList();
+        SDL_UnlockJoysticks();
         return NULL;
     }
 
@@ -1392,7 +1392,7 @@ SDL_GameControllerOpen(int device_index)
             SDL_OutOfMemory();
             SDL_JoystickClose(gamecontroller->joystick);
             SDL_free(gamecontroller);
-            SDL_UnlockJoystickList();
+            SDL_UnlockJoysticks();
             return NULL;
         }
     }
@@ -1403,7 +1403,7 @@ SDL_GameControllerOpen(int device_index)
             SDL_JoystickClose(gamecontroller->joystick);
             SDL_free(gamecontroller->last_match_axis);
             SDL_free(gamecontroller);
-            SDL_UnlockJoystickList();
+            SDL_UnlockJoysticks();
             return NULL;
         }
     }
@@ -1416,7 +1416,7 @@ SDL_GameControllerOpen(int device_index)
     gamecontroller->next = SDL_gamecontrollers;
     SDL_gamecontrollers = gamecontroller;
 
-    SDL_UnlockJoystickList();
+    SDL_UnlockJoysticks();
 
     return (gamecontroller);
 }
@@ -1589,16 +1589,16 @@ SDL_GameControllerFromInstanceID(SDL_JoystickID joyid)
 {
     SDL_GameController *gamecontroller;
 
-    SDL_LockJoystickList();
+    SDL_LockJoysticks();
     gamecontroller = SDL_gamecontrollers;
     while (gamecontroller) {
         if (gamecontroller->joystick->instance_id == joyid) {
-            SDL_UnlockJoystickList();
+            SDL_UnlockJoysticks();
             return gamecontroller;
         }
         gamecontroller = gamecontroller->next;
     }
-    SDL_UnlockJoystickList();
+    SDL_UnlockJoysticks();
     return NULL;
 }
 
@@ -1674,11 +1674,11 @@ SDL_GameControllerClose(SDL_GameController * gamecontroller)
     if (!gamecontroller)
         return;
 
-    SDL_LockJoystickList();
+    SDL_LockJoysticks();
 
     /* First decrement ref count */
     if (--gamecontroller->ref_count > 0) {
-        SDL_UnlockJoystickList();
+        SDL_UnlockJoysticks();
         return;
     }
 
@@ -1705,7 +1705,7 @@ SDL_GameControllerClose(SDL_GameController * gamecontroller)
     SDL_free(gamecontroller->last_hat_mask);
     SDL_free(gamecontroller);
 
-    SDL_UnlockJoystickList();
+    SDL_UnlockJoysticks();
 }
 
 
@@ -1715,12 +1715,12 @@ SDL_GameControllerClose(SDL_GameController * gamecontroller)
 void
 SDL_GameControllerQuit(void)
 {
-    SDL_LockJoystickList();
+    SDL_LockJoysticks();
     while (SDL_gamecontrollers) {
         SDL_gamecontrollers->ref_count = 1;
         SDL_GameControllerClose(SDL_gamecontrollers);
     }
-    SDL_UnlockJoystickList();
+    SDL_UnlockJoysticks();
 }
 
 void
diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c
index 0724db2..4c4cae7 100644
--- a/src/joystick/SDL_joystick.c
+++ b/src/joystick/SDL_joystick.c
@@ -40,7 +40,7 @@ static SDL_bool SDL_updating_joystick = SDL_FALSE;
 static SDL_mutex *SDL_joystick_lock = NULL; /* This needs to support recursive locks */
 
 void
-SDL_LockJoystickList(void)
+SDL_LockJoysticks(void)
 {
     if (SDL_joystick_lock) {
         SDL_LockMutex(SDL_joystick_lock);
@@ -48,7 +48,7 @@ SDL_LockJoystickList(void)
 }
 
 void
-SDL_UnlockJoystickList(void)
+SDL_UnlockJoysticks(void)
 {
     if (SDL_joystick_lock) {
         SDL_UnlockMutex(SDL_joystick_lock);
@@ -168,7 +168,7 @@ SDL_JoystickOpen(int device_index)
         return (NULL);
     }
 
-    SDL_LockJoystickList();
+    SDL_LockJoysticks();
 
     joysticklist = SDL_joysticks;
     /* If the joystick is already open, return it
@@ -178,7 +178,7 @@ SDL_JoystickOpen(int device_index)
         if (SDL_JoystickGetDeviceInstanceID(device_index) == joysticklist->instance_id) {
                 joystick = joysticklist;
                 ++joystick->ref_count;
-                SDL_UnlockJoystickList();
+                SDL_UnlockJoysticks();
                 return (joystick);
         }
         joysticklist = joysticklist->next;
@@ -188,13 +188,13 @@ SDL_JoystickOpen(int device_index)
     joystick = (SDL_Joystick *) SDL_calloc(sizeof(*joystick), 1);
     if (joystick == NULL) {
         SDL_OutOfMemory();
-        SDL_UnlockJoystickList();
+        SDL_UnlockJoysticks();
         return NULL;
     }
 
     if (SDL_SYS_JoystickOpen(joystick, device_index) < 0) {
         SDL_free(joystick);
-        SDL_UnlockJoystickList();
+        SDL_UnlockJoysticks();
         return NULL;
     }
 
@@ -222,7 +222,7 @@ SDL_JoystickOpen(int device_index)
         || ((joystick->nbuttons > 0) && !joystick->buttons)) {
         SDL_OutOfMemory();
         SDL_JoystickClose(joystick);
-        SDL_UnlockJoystickList();
+        SDL_UnlockJoysticks();
         return NULL;
     }
     joystick->epowerlevel = SDL_JOYSTICK_POWER_UNKNOWN;
@@ -244,7 +244,7 @@ SDL_JoystickOpen(int device_index)
     joystick->next = SDL_joysticks;
     SDL_joysticks = joystick;
 
-    SDL_UnlockJoystickList();
+    SDL_UnlockJoysticks();
 
     SDL_SYS_JoystickUpdate(joystick);
 
@@ -460,14 +460,14 @@ SDL_JoystickFromInstanceID(SDL_JoystickID joyid)
 {
     SDL_Joystick *joystick;
 
-    SDL_LockJoystickList();
+    SDL_LockJoysticks();
     for (joystick = SDL_joysticks; joystick; joystick = joystick->next) {
         if (joystick->instance_id == joyid) {
-            SDL_UnlockJoystickList();
+            SDL_UnlockJoysticks();
             return joystick;
         }
     }
-    SDL_UnlockJoystickList();
+    SDL_UnlockJoysticks();
     return NULL;
 }
 
@@ -497,16 +497,16 @@ SDL_JoystickClose(SDL_Joystick * joystick)
         return;
     }
 
-    SDL_LockJoystickList();
+    SDL_LockJoysticks();
 
     /* First decrement ref count */
     if (--joystick->ref_count > 0) {
-        SDL_UnlockJoystickList();
+        SDL_UnlockJoysticks();
         return;
     }
 
     if (SDL_updating_joystick) {
-        SDL_UnlockJoystickList();
+        SDL_UnlockJoysticks();
         return;
     }
 
@@ -538,7 +538,7 @@ SDL_JoystickClose(SDL_Joystick * joystick)
     SDL_free(joystick->buttons);
     SDL_free(joystick);
 
-    SDL_UnlockJoystickList();
+    SDL_UnlockJoysticks();
 }
 
 void
@@ -547,7 +547,7 @@ SDL_JoystickQuit(void)
     /* Make sure we're not getting called in the middle of updating joysticks */
     SDL_assert(!SDL_updating_joystick);
 
-    SDL_LockJoystickList();
+    SDL_LockJoysticks();
 
     /* Stop the event polling */
     while (SDL_joysticks) {
@@ -558,7 +558,7 @@ SDL_JoystickQuit(void)
     /* Quit the joystick setup */
     SDL_SYS_JoystickQuit();
 
-    SDL_UnlockJoystickList();
+    SDL_UnlockJoysticks();
 
 #if !SDL_EVENTS_DISABLED
     SDL_QuitSubSystem(SDL_INIT_EVENTS);
@@ -847,18 +847,18 @@ SDL_JoystickUpdate(void)
 {
     SDL_Joystick *joystick;
 
-    SDL_LockJoystickList();
+    SDL_LockJoysticks();
 
     if (SDL_updating_joystick) {
         /* The joysticks are already being updated */
-        SDL_UnlockJoystickList();
+        SDL_UnlockJoysticks();
         return;
     }
 
     SDL_updating_joystick = SDL_TRUE;
 
     /* Make sure the list is unlocked while dispatching events to prevent application deadlocks */
-    SDL_UnlockJoystickList();
+    SDL_UnlockJoysticks();
 
     for (joystick = SDL_joysticks; joystick; joystick = joystick->next) {
         SDL_SYS_JoystickUpdate(joystick);
@@ -885,7 +885,7 @@ SDL_JoystickUpdate(void)
         }
     }
 
-    SDL_LockJoystickList();
+    SDL_LockJoysticks();
 
     SDL_updating_joystick = SDL_FALSE;
 
@@ -901,7 +901,7 @@ SDL_JoystickUpdate(void)
      */
     SDL_SYS_JoystickDetect();
 
-    SDL_UnlockJoystickList();
+    SDL_UnlockJoysticks();
 }
 
 int
diff --git a/src/joystick/SDL_joystick_c.h b/src/joystick/SDL_joystick_c.h
index 5339b83..85d3920 100644
--- a/src/joystick/SDL_joystick_c.h
+++ b/src/joystick/SDL_joystick_c.h
@@ -33,10 +33,6 @@ extern void SDL_GameControllerQuitMappings(void);
 extern int SDL_GameControllerInit(void);
 extern void SDL_GameControllerQuit(void);
 
-/* Locking for multi-threaded access to the joystick API */
-extern void SDL_LockJoystickList(void);
-extern void SDL_UnlockJoystickList(void);
-
 /* Function to extract information from an SDL joystick GUID */
 extern void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *product, Uint16 *version);