Allow initializing hints and properties from any thread

This commit is contained in:
Sam Lantinga
2024-09-17 02:55:23 -07:00
parent d0edf68774
commit 807b8a9d4d
3 changed files with 79 additions and 47 deletions

View File

@@ -252,21 +252,14 @@ void SDL_InitMainThread(void)
{ {
SDL_InitTLSData(); SDL_InitTLSData();
SDL_InitEnvironment(); SDL_InitEnvironment();
SDL_InitProperties();
SDL_InitHints();
SDL_InitTicks(); SDL_InitTicks();
SDL_InitFilesystem(); SDL_InitFilesystem();
SDL_InitLog();
SDL_GetGlobalProperties();
} }
static void SDL_QuitMainThread(void) static void SDL_QuitMainThread(void)
{ {
SDL_QuitLog();
SDL_QuitFilesystem(); SDL_QuitFilesystem();
SDL_QuitTicks(); SDL_QuitTicks();
SDL_QuitHints();
SDL_QuitProperties();
SDL_QuitEnvironment(); SDL_QuitEnvironment();
SDL_QuitTLSData(); SDL_QuitTLSData();
} }
@@ -625,6 +618,10 @@ void SDL_Quit(void)
*/ */
SDL_memset(SDL_SubsystemRefCount, 0x0, sizeof(SDL_SubsystemRefCount)); SDL_memset(SDL_SubsystemRefCount, 0x0, sizeof(SDL_SubsystemRefCount));
SDL_QuitLog();
SDL_QuitHints();
SDL_QuitProperties();
SDL_QuitMainThread(); SDL_QuitMainThread();
SDL_bInMainQuit = false; SDL_bInMainQuit = false;

View File

@@ -36,20 +36,37 @@ typedef struct SDL_Hint
SDL_HintWatch *callbacks; SDL_HintWatch *callbacks;
} SDL_Hint; } SDL_Hint;
static SDL_PropertiesID SDL_hint_props = 0; static SDL_AtomicU32 SDL_hint_props;
static SDL_PropertiesID GetHintProperties(bool create)
{
if (!SDL_hint_props && create) {
SDL_hint_props = SDL_CreateProperties();
}
return SDL_hint_props;
}
void SDL_InitHints(void) void SDL_InitHints(void)
{ {
// Just make sure the hint properties are created on the main thread }
(void)GetHintProperties(true);
void SDL_QuitHints(void)
{
SDL_PropertiesID props;
do {
props = SDL_GetAtomicU32(&SDL_hint_props);
} while (!SDL_CompareAndSwapAtomicU32(&SDL_hint_props, props, 0));
if (props) {
SDL_DestroyProperties(props);
}
}
static SDL_PropertiesID GetHintProperties(bool create)
{
SDL_PropertiesID props = SDL_GetAtomicU32(&SDL_hint_props);
if (!props && create) {
props = SDL_CreateProperties();
if (!SDL_CompareAndSwapAtomicU32(&SDL_hint_props, 0, props)) {
// Somebody else created hint properties before us, just use those
SDL_DestroyProperties(props);
props = SDL_GetAtomicU32(&SDL_hint_props);
}
}
return props;
} }
static void SDLCALL CleanupHintProperty(void *userdata, void *value) static void SDLCALL CleanupHintProperty(void *userdata, void *value)
@@ -336,9 +353,3 @@ void SDL_RemoveHintCallback(const char *name, SDL_HintCallback callback, void *u
SDL_UnlockProperties(hints); SDL_UnlockProperties(hints);
} }
void SDL_QuitHints(void)
{
SDL_DestroyProperties(SDL_hint_props);
SDL_hint_props = 0;
}

View File

@@ -48,10 +48,11 @@ typedef struct
SDL_Mutex *lock; SDL_Mutex *lock;
} SDL_Properties; } SDL_Properties;
static SDL_InitState SDL_properties_init;
static SDL_HashTable *SDL_properties; static SDL_HashTable *SDL_properties;
static SDL_Mutex *SDL_properties_lock; static SDL_Mutex *SDL_properties_lock;
static SDL_PropertiesID SDL_last_properties_id; static SDL_PropertiesID SDL_last_properties_id;
static SDL_PropertiesID SDL_global_properties; static SDL_AtomicU32 SDL_global_properties;
static void SDL_FreePropertyWithCleanup(const void *key, const void *value, void *data, bool cleanup) static void SDL_FreePropertyWithCleanup(const void *key, const void *value, void *data, bool cleanup)
@@ -99,27 +100,42 @@ static void SDL_FreeProperties(const void *key, const void *value, void *data)
bool SDL_InitProperties(void) bool SDL_InitProperties(void)
{ {
if (!SDL_properties_lock) { if (!SDL_ShouldInit(&SDL_properties_init)) {
SDL_properties_lock = SDL_CreateMutex(); return true;
if (!SDL_properties_lock) {
return false;
}
} }
// If this fails we'll continue without it.
SDL_properties_lock = SDL_CreateMutex();
SDL_properties = SDL_CreateHashTable(NULL, 16, SDL_HashID, SDL_KeyMatchID, SDL_FreeProperties, false);
if (!SDL_properties) { if (!SDL_properties) {
SDL_properties = SDL_CreateHashTable(NULL, 16, SDL_HashID, SDL_KeyMatchID, SDL_FreeProperties, false); goto error;
if (!SDL_properties) {
return false;
}
} }
SDL_SetInitialized(&SDL_properties_init, true);
return true; return true;
error:
SDL_SetInitialized(&SDL_properties_init, true);
SDL_QuitProperties();
return false;
} }
void SDL_QuitProperties(void) void SDL_QuitProperties(void)
{ {
if (SDL_global_properties) { if (!SDL_ShouldQuit(&SDL_properties_init)) {
SDL_DestroyProperties(SDL_global_properties); return;
SDL_global_properties = 0;
} }
SDL_PropertiesID props;
do {
props = SDL_GetAtomicU32(&SDL_global_properties);
} while (!SDL_CompareAndSwapAtomicU32(&SDL_global_properties, props, 0));
if (props) {
SDL_DestroyProperties(props);
}
if (SDL_properties) { if (SDL_properties) {
SDL_DestroyHashTable(SDL_properties); SDL_DestroyHashTable(SDL_properties);
SDL_properties = NULL; SDL_properties = NULL;
@@ -128,14 +144,27 @@ void SDL_QuitProperties(void)
SDL_DestroyMutex(SDL_properties_lock); SDL_DestroyMutex(SDL_properties_lock);
SDL_properties_lock = NULL; SDL_properties_lock = NULL;
} }
SDL_SetInitialized(&SDL_properties_init, false);
}
static bool SDL_CheckInitProperties(void)
{
return SDL_InitProperties();
} }
SDL_PropertiesID SDL_GetGlobalProperties(void) SDL_PropertiesID SDL_GetGlobalProperties(void)
{ {
if (!SDL_global_properties) { SDL_PropertiesID props = SDL_GetAtomicU32(&SDL_global_properties);
SDL_global_properties = SDL_CreateProperties(); if (!props) {
props = SDL_CreateProperties();
if (!SDL_CompareAndSwapAtomicU32(&SDL_global_properties, 0, props)) {
// Somebody else created global properties before us, just use those
SDL_DestroyProperties(props);
props = SDL_GetAtomicU32(&SDL_global_properties);
}
} }
return SDL_global_properties; return props;
} }
SDL_PropertiesID SDL_CreateProperties(void) SDL_PropertiesID SDL_CreateProperties(void)
@@ -144,7 +173,7 @@ SDL_PropertiesID SDL_CreateProperties(void)
SDL_Properties *properties = NULL; SDL_Properties *properties = NULL;
bool inserted = false; bool inserted = false;
if (!SDL_properties && !SDL_InitProperties()) { if (!SDL_CheckInitProperties()) {
return 0; return 0;
} }
@@ -156,14 +185,9 @@ SDL_PropertiesID SDL_CreateProperties(void)
if (!properties->props) { if (!properties->props) {
goto error; goto error;
} }
properties->lock = SDL_CreateMutex();
if (!properties->lock) {
goto error;
}
if (!SDL_InitProperties()) { // If this fails we'll continue without it.
goto error; properties->lock = SDL_CreateMutex();
}
SDL_LockMutex(SDL_properties_lock); SDL_LockMutex(SDL_properties_lock);
++SDL_last_properties_id; ++SDL_last_properties_id;