Added thread-safe initialization/cleanup support

Also went through and removed inappropriate uses of spinlocks.

Fixes https://github.com/libsdl-org/SDL/issues/10872
This commit is contained in:
Sam Lantinga
2024-09-16 22:45:37 -07:00
parent 7edd43c276
commit 9275c533ca
7 changed files with 208 additions and 132 deletions

View File

@@ -121,7 +121,40 @@ bool SDL_endswith(const char *string, const char *suffix)
return false;
}
// Assume we can wrap SDL_AtomicInt values and cast to Uint32
bool SDL_ShouldInit(SDL_InitState *state)
{
while (SDL_AtomicGet(&state->status) != SDL_INIT_STATUS_INITIALIZED) {
if (SDL_AtomicCompareAndSwap(&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_AtomicCompareAndSwap(&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_AtomicSet(&state->status, SDL_INIT_STATUS_INITIALIZED);
} else {
SDL_AtomicSet(&state->status, SDL_INIT_STATUS_UNINITIALIZED);
}
}
SDL_COMPILE_TIME_ASSERT(sizeof_object_id, sizeof(int) == sizeof(Uint32));
Uint32 SDL_GetNextObjectID(void)