Browse Source

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.
Sam Lantinga 6 months ago
parent
commit
48e213b4cd
1 changed files with 8 additions and 3 deletions
  1. 8 3
      src/thread/SDL_thread.c

+ 8 - 3
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;
 }