From 48e213b4cddea928b824cc46d285df98d904f6e0 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 26 Sep 2024 18:08:58 -0700 Subject: [PATCH] Fixed SDL_ShouldQuit() returning false during status transitions We should wait for the state to stabilize before SDL_ShouldQuit() returns. For example: Thread A initializes and increments a use refcount Thread B skips initializing and increments the use refcount Thread B starts cleaning up and checks the use refcount Thread A starts cleaning up, returns because SDL_ShouldQuit() returns false (not initialized), not touching the use refcount Thread B returns because the use refcount isn't zero Now we have the state where the refcount is greater than one and both thread A and B have attempted to cleanup. With this change: Thread A initializes and increments a use refcount Thread B skips initializing and increments the use refcount Thread B starts cleaning up and decrements and checks the use refcount Thread A starts cleaning up, waits for thread B Thread B returns because the use refcount isn't zero Thread A continues and decrements and checks the use refcount, and finishes cleaning up because it has reached 0. --- src/thread/SDL_thread.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/thread/SDL_thread.c b/src/thread/SDL_thread.c index d2b914524c..177dc2102c 100644 --- a/src/thread/SDL_thread.c +++ b/src/thread/SDL_thread.c @@ -533,9 +533,14 @@ bool SDL_ShouldInit(SDL_InitState *state) 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; + while (SDL_GetAtomicInt(&state->status) != SDL_INIT_STATUS_UNINITIALIZED) { + if (SDL_CompareAndSwapAtomicInt(&state->status, SDL_INIT_STATUS_INITIALIZED, SDL_INIT_STATUS_UNINITIALIZING)) { + state->thread = SDL_GetCurrentThreadID(); + return true; + } + + // Wait for the other thread to complete transition + SDL_Delay(1); } return false; }