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

@@ -53,7 +53,6 @@ static char **environ;
struct SDL_Environment
{
SDL_Mutex *lock;
SDL_HashTable *strings;
};
static SDL_Environment *SDL_environment;
@@ -88,15 +87,12 @@ SDL_Environment *SDL_CreateEnvironment(bool populated)
return NULL;
}
env->strings = SDL_CreateHashTable(NULL, 16, SDL_HashString, SDL_KeyMatchString, SDL_NukeFreeKey, false);
env->strings = SDL_CreateHashTable(NULL, 16, SDL_HashString, SDL_KeyMatchString, SDL_NukeFreeKey, true, false);
if (!env->strings) {
SDL_free(env);
return NULL;
}
// Don't fail if we can't create a mutex (e.g. on a single-thread environment)
env->lock = SDL_CreateMutex();
if (populated) {
#ifdef SDL_PLATFORM_WINDOWS
LPWCH strings = GetEnvironmentStringsW();
@@ -157,15 +153,10 @@ const char *SDL_GetEnvironmentVariable(SDL_Environment *env, const char *name)
return NULL;
}
SDL_LockMutex(env->lock);
{
const char *value;
if (SDL_FindInHashTable(env->strings, name, (const void **)&value)) {
result = SDL_GetPersistentString(value);
}
const char *value;
if (SDL_FindInHashTable(env->strings, name, (const void **)&value)) {
result = SDL_GetPersistentString(value);
}
SDL_UnlockMutex(env->lock);
return result;
}
@@ -179,7 +170,7 @@ char **SDL_GetEnvironmentVariables(SDL_Environment *env)
return NULL;
}
SDL_LockMutex(env->lock);
SDL_LockHashTable(env->strings, false);
{
size_t count, length = 0;
void *iter;
@@ -216,7 +207,7 @@ char **SDL_GetEnvironmentVariables(SDL_Environment *env)
}
result[count] = NULL;
}
SDL_UnlockMutex(env->lock);
SDL_UnlockHashTable(env->strings);
return result;
}
@@ -233,7 +224,7 @@ bool SDL_SetEnvironmentVariable(SDL_Environment *env, const char *name, const ch
return SDL_InvalidParamError("value");
}
SDL_LockMutex(env->lock);
SDL_LockHashTable(env->strings, true);
{
const void *existing_value;
bool insert = true;
@@ -258,33 +249,21 @@ bool SDL_SetEnvironmentVariable(SDL_Environment *env, const char *name, const ch
}
}
}
SDL_UnlockMutex(env->lock);
SDL_UnlockHashTable(env->strings);
return result;
}
bool SDL_UnsetEnvironmentVariable(SDL_Environment *env, const char *name)
{
bool result = false;
if (!env) {
return SDL_InvalidParamError("env");
} else if (!name || *name == '\0' || SDL_strchr(name, '=') != NULL) {
return SDL_InvalidParamError("name");
}
SDL_LockMutex(env->lock);
{
const void *value;
if (SDL_FindInHashTable(env->strings, name, &value)) {
result = SDL_RemoveFromHashTable(env->strings, name);
} else {
result = true;
}
}
SDL_UnlockMutex(env->lock);
return result;
SDL_RemoveFromHashTable(env->strings, name);
return true;
}
void SDL_DestroyEnvironment(SDL_Environment *env)
@@ -293,7 +272,6 @@ void SDL_DestroyEnvironment(SDL_Environment *env)
return;
}
SDL_DestroyMutex(env->lock);
SDL_DestroyHashTable(env->strings);
SDL_free(env);
}