Added SDL_ShouldInit() and SDL_ShouldQuit()

These are handy functions to support thread-safe initialization and shutdown.
This commit is contained in:
Sam Lantinga
2024-09-26 15:49:59 -07:00
parent 0e2c4e407a
commit 125e592844
7 changed files with 178 additions and 52 deletions

View File

@@ -121,40 +121,6 @@ bool SDL_endswith(const char *string, const char *suffix)
return false;
}
bool SDL_ShouldInit(SDL_InitState *state)
{
while (SDL_GetAtomicInt(&state->status) != SDL_INIT_STATUS_INITIALIZED) {
if (SDL_CompareAndSwapAtomicInt(&state->status, SDL_INIT_STATUS_UNINITIALIZED, SDL_INIT_STATUS_INITIALIZING)) {
state->thread = SDL_GetCurrentThreadID();
return true;
}
// Wait for the other thread to complete transition
SDL_Delay(1);
}
return false;
}
bool SDL_ShouldQuit(SDL_InitState *state)
{
if (SDL_CompareAndSwapAtomicInt(&state->status, SDL_INIT_STATUS_INITIALIZED, SDL_INIT_STATUS_UNINITIALIZING)) {
state->thread = SDL_GetCurrentThreadID();
return true;
}
return false;
}
void SDL_SetInitialized(SDL_InitState *state, bool initialized)
{
SDL_assert(state->thread == SDL_GetCurrentThreadID());
if (initialized) {
SDL_SetAtomicInt(&state->status, SDL_INIT_STATUS_INITIALIZED);
} else {
SDL_SetAtomicInt(&state->status, SDL_INIT_STATUS_UNINITIALIZED);
}
}
SDL_COMPILE_TIME_ASSERT(sizeof_object_id, sizeof(int) == sizeof(Uint32));
Uint32 SDL_GetNextObjectID(void)

View File

@@ -47,24 +47,6 @@ extern bool SDL_endswith(const char *string, const char *suffix);
*/
extern int SDL_URIToLocal(const char *src, char *dst);
typedef enum SDL_InitStatus
{
SDL_INIT_STATUS_UNINITIALIZED,
SDL_INIT_STATUS_INITIALIZING,
SDL_INIT_STATUS_INITIALIZED,
SDL_INIT_STATUS_UNINITIALIZING
} SDL_InitStatus;
typedef struct SDL_InitState
{
SDL_AtomicInt status;
SDL_ThreadID thread;
} SDL_InitState;
extern bool SDL_ShouldInit(SDL_InitState *state);
extern bool SDL_ShouldQuit(SDL_InitState *state);
extern void SDL_SetInitialized(SDL_InitState *state, bool initialized);
typedef enum
{
SDL_OBJECT_TYPE_UNKNOWN,

View File

@@ -817,6 +817,7 @@ SDL3_0.0.0 {
SDL_SetHapticGain;
SDL_SetHint;
SDL_SetHintWithPriority;
SDL_SetInitialized;
SDL_SetJoystickEventsEnabled;
SDL_SetJoystickLED;
SDL_SetJoystickPlayerIndex;
@@ -895,6 +896,8 @@ SDL3_0.0.0 {
SDL_SetX11EventHook;
SDL_SetiOSAnimationCallback;
SDL_SetiOSEventPump;
SDL_ShouldInit;
SDL_ShouldQuit;
SDL_ShowAndroidToast;
SDL_ShowCursor;
SDL_ShowMessageBox;

View File

@@ -842,6 +842,7 @@
#define SDL_SetHapticGain SDL_SetHapticGain_REAL
#define SDL_SetHint SDL_SetHint_REAL
#define SDL_SetHintWithPriority SDL_SetHintWithPriority_REAL
#define SDL_SetInitialized SDL_SetInitialized_REAL
#define SDL_SetJoystickEventsEnabled SDL_SetJoystickEventsEnabled_REAL
#define SDL_SetJoystickLED SDL_SetJoystickLED_REAL
#define SDL_SetJoystickPlayerIndex SDL_SetJoystickPlayerIndex_REAL
@@ -920,6 +921,8 @@
#define SDL_SetX11EventHook SDL_SetX11EventHook_REAL
#define SDL_SetiOSAnimationCallback SDL_SetiOSAnimationCallback_REAL
#define SDL_SetiOSEventPump SDL_SetiOSEventPump_REAL
#define SDL_ShouldInit SDL_ShouldInit_REAL
#define SDL_ShouldQuit SDL_ShouldQuit_REAL
#define SDL_ShowAndroidToast SDL_ShowAndroidToast_REAL
#define SDL_ShowCursor SDL_ShowCursor_REAL
#define SDL_ShowMessageBox SDL_ShowMessageBox_REAL

View File

@@ -852,6 +852,7 @@ SDL_DYNAPI_PROC(bool,SDL_SetHapticAutocenter,(SDL_Haptic *a, int b),(a,b),return
SDL_DYNAPI_PROC(bool,SDL_SetHapticGain,(SDL_Haptic *a, int b),(a,b),return)
SDL_DYNAPI_PROC(bool,SDL_SetHint,(const char *a, const char *b),(a,b),return)
SDL_DYNAPI_PROC(bool,SDL_SetHintWithPriority,(const char *a, const char *b, SDL_HintPriority c),(a,b,c),return)
SDL_DYNAPI_PROC(void,SDL_SetInitialized,(SDL_InitState *a, bool b),(a,b),)
SDL_DYNAPI_PROC(void,SDL_SetJoystickEventsEnabled,(bool a),(a),)
SDL_DYNAPI_PROC(bool,SDL_SetJoystickLED,(SDL_Joystick *a, Uint8 b, Uint8 c, Uint8 d),(a,b,c,d),return)
SDL_DYNAPI_PROC(bool,SDL_SetJoystickPlayerIndex,(SDL_Joystick *a, int b),(a,b),return)
@@ -930,6 +931,8 @@ SDL_DYNAPI_PROC(void,SDL_SetWindowsMessageHook,(SDL_WindowsMessageHook a, void *
SDL_DYNAPI_PROC(void,SDL_SetX11EventHook,(SDL_X11EventHook a, void *b),(a,b),)
SDL_DYNAPI_PROC(bool,SDL_SetiOSAnimationCallback,(SDL_Window *a, int b, SDL_iOSAnimationCallback c, void *d),(a,b,c,d),return)
SDL_DYNAPI_PROC(void,SDL_SetiOSEventPump,(bool a),(a),)
SDL_DYNAPI_PROC(bool,SDL_ShouldInit,(SDL_InitState *a),(a),return)
SDL_DYNAPI_PROC(bool,SDL_ShouldQuit,(SDL_InitState *a),(a),return)
SDL_DYNAPI_PROC(bool,SDL_ShowAndroidToast,(const char *a, int b, int c, int d, int e),(a,b,c,d,e),return)
SDL_DYNAPI_PROC(bool,SDL_ShowCursor,(void),(),return)
SDL_DYNAPI_PROC(bool,SDL_ShowMessageBox,(const SDL_MessageBoxData *a, int *b),(a,b),return)

View File

@@ -517,3 +517,37 @@ bool SDL_WaitConditionTimeout(SDL_Condition *cond, SDL_Mutex *mutex, Sint32 time
return SDL_WaitConditionTimeoutNS(cond, mutex, timeoutNS);
}
bool SDL_ShouldInit(SDL_InitState *state)
{
while (SDL_GetAtomicInt(&state->status) != SDL_INIT_STATUS_INITIALIZED) {
if (SDL_CompareAndSwapAtomicInt(&state->status, SDL_INIT_STATUS_UNINITIALIZED, SDL_INIT_STATUS_INITIALIZING)) {
state->thread = SDL_GetCurrentThreadID();
return true;
}
// Wait for the other thread to complete transition
SDL_Delay(1);
}
return false;
}
bool SDL_ShouldQuit(SDL_InitState *state)
{
if (SDL_CompareAndSwapAtomicInt(&state->status, SDL_INIT_STATUS_INITIALIZED, SDL_INIT_STATUS_UNINITIALIZING)) {
state->thread = SDL_GetCurrentThreadID();
return true;
}
return false;
}
void SDL_SetInitialized(SDL_InitState *state, bool initialized)
{
SDL_assert(state->thread == SDL_GetCurrentThreadID());
if (initialized) {
SDL_SetAtomicInt(&state->status, SDL_INIT_STATUS_INITIALIZED);
} else {
SDL_SetAtomicInt(&state->status, SDL_INIT_STATUS_UNINITIALIZED);
}
}