SDL_HashTable is now optionally thread-safe

Fixes https://github.com/libsdl-org/SDL/issues/11635
This commit is contained in:
Sam Lantinga
2024-12-12 11:51:27 -08:00
parent e0cee83a3a
commit 61511c48a4
12 changed files with 175 additions and 181 deletions

View File

@@ -50,8 +50,7 @@ typedef struct
static SDL_InitState SDL_properties_init;
static SDL_HashTable *SDL_properties;
static SDL_Mutex *SDL_properties_lock;
static SDL_PropertiesID SDL_last_properties_id;
static SDL_AtomicU32 SDL_last_properties_id;
static SDL_AtomicU32 SDL_global_properties;
@@ -104,10 +103,7 @@ bool SDL_InitProperties(void)
return true;
}
// 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);
SDL_properties = SDL_CreateHashTable(NULL, 16, SDL_HashID, SDL_KeyMatchID, SDL_FreeProperties, true, false);
if (!SDL_properties) {
goto error;
}
@@ -140,10 +136,6 @@ void SDL_QuitProperties(void)
SDL_DestroyHashTable(SDL_properties);
SDL_properties = NULL;
}
if (SDL_properties_lock) {
SDL_DestroyMutex(SDL_properties_lock);
SDL_properties_lock = NULL;
}
SDL_SetInitialized(&SDL_properties_init, false);
}
@@ -181,7 +173,7 @@ SDL_PropertiesID SDL_CreateProperties(void)
if (!properties) {
goto error;
}
properties->props = SDL_CreateHashTable(NULL, 4, SDL_HashString, SDL_KeyMatchString, SDL_FreeProperty, false);
properties->props = SDL_CreateHashTable(NULL, 4, SDL_HashString, SDL_KeyMatchString, SDL_FreeProperty, false, false);
if (!properties->props) {
goto error;
}
@@ -189,16 +181,18 @@ SDL_PropertiesID SDL_CreateProperties(void)
// If this fails we'll continue without it.
properties->lock = SDL_CreateMutex();
SDL_LockMutex(SDL_properties_lock);
++SDL_last_properties_id;
if (SDL_last_properties_id == 0) {
++SDL_last_properties_id;
for ( ; ; ) {
props = (SDL_GetAtomicU32(&SDL_last_properties_id) + 1);
if (props == 0) {
continue;
}
if (SDL_CompareAndSwapAtomicU32(&SDL_last_properties_id, props - 1, props)) {
break;
}
}
props = SDL_last_properties_id;
if (SDL_InsertIntoHashTable(SDL_properties, (const void *)(uintptr_t)props, properties)) {
inserted = true;
}
SDL_UnlockMutex(SDL_properties_lock);
if (inserted) {
// All done!
@@ -223,11 +217,8 @@ bool SDL_CopyProperties(SDL_PropertiesID src, SDL_PropertiesID dst)
return SDL_InvalidParamError("dst");
}
SDL_LockMutex(SDL_properties_lock);
SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)src, (const void **)&src_properties);
SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)dst, (const void **)&dst_properties);
SDL_UnlockMutex(SDL_properties_lock);
if (!src_properties) {
return SDL_InvalidParamError("src");
}
@@ -290,10 +281,7 @@ bool SDL_LockProperties(SDL_PropertiesID props)
return SDL_InvalidParamError("props");
}
SDL_LockMutex(SDL_properties_lock);
SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)props, (const void **)&properties);
SDL_UnlockMutex(SDL_properties_lock);
if (!properties) {
return SDL_InvalidParamError("props");
}
@@ -310,10 +298,7 @@ void SDL_UnlockProperties(SDL_PropertiesID props)
return;
}
SDL_LockMutex(SDL_properties_lock);
SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)props, (const void **)&properties);
SDL_UnlockMutex(SDL_properties_lock);
if (!properties) {
return;
}
@@ -335,10 +320,7 @@ static bool SDL_PrivateSetProperty(SDL_PropertiesID props, const char *name, SDL
return SDL_InvalidParamError("name");
}
SDL_LockMutex(SDL_properties_lock);
SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)props, (const void **)&properties);
SDL_UnlockMutex(SDL_properties_lock);
if (!properties) {
SDL_FreePropertyWithCleanup(NULL, property, NULL, true);
return SDL_InvalidParamError("props");
@@ -496,10 +478,7 @@ SDL_PropertyType SDL_GetPropertyType(SDL_PropertiesID props, const char *name)
return SDL_PROPERTY_TYPE_INVALID;
}
SDL_LockMutex(SDL_properties_lock);
SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)props, (const void **)&properties);
SDL_UnlockMutex(SDL_properties_lock);
if (!properties) {
return SDL_PROPERTY_TYPE_INVALID;
}
@@ -528,10 +507,7 @@ void *SDL_GetPointerProperty(SDL_PropertiesID props, const char *name, void *def
return value;
}
SDL_LockMutex(SDL_properties_lock);
SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)props, (const void **)&properties);
SDL_UnlockMutex(SDL_properties_lock);
if (!properties) {
return value;
}
@@ -566,10 +542,7 @@ const char *SDL_GetStringProperty(SDL_PropertiesID props, const char *name, cons
return value;
}
SDL_LockMutex(SDL_properties_lock);
SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)props, (const void **)&properties);
SDL_UnlockMutex(SDL_properties_lock);
if (!properties) {
return value;
}
@@ -627,10 +600,7 @@ Sint64 SDL_GetNumberProperty(SDL_PropertiesID props, const char *name, Sint64 de
return value;
}
SDL_LockMutex(SDL_properties_lock);
SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)props, (const void **)&properties);
SDL_UnlockMutex(SDL_properties_lock);
if (!properties) {
return value;
}
@@ -674,10 +644,7 @@ float SDL_GetFloatProperty(SDL_PropertiesID props, const char *name, float defau
return value;
}
SDL_LockMutex(SDL_properties_lock);
SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)props, (const void **)&properties);
SDL_UnlockMutex(SDL_properties_lock);
if (!properties) {
return value;
}
@@ -721,10 +688,7 @@ bool SDL_GetBooleanProperty(SDL_PropertiesID props, const char *name, bool defau
return value;
}
SDL_LockMutex(SDL_properties_lock);
SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)props, (const void **)&properties);
SDL_UnlockMutex(SDL_properties_lock);
if (!properties) {
return value;
}
@@ -772,10 +736,7 @@ bool SDL_EnumerateProperties(SDL_PropertiesID props, SDL_EnumeratePropertiesCall
return SDL_InvalidParamError("callback");
}
SDL_LockMutex(SDL_properties_lock);
SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)props, (const void **)&properties);
SDL_UnlockMutex(SDL_properties_lock);
if (!properties) {
return SDL_InvalidParamError("props");
}
@@ -833,7 +794,5 @@ void SDL_DestroyProperties(SDL_PropertiesID props)
return;
}
SDL_LockMutex(SDL_properties_lock);
SDL_RemoveFromHashTable(SDL_properties, (const void *)(uintptr_t)props);
SDL_UnlockMutex(SDL_properties_lock);
}