# SDL: Refactor property assignment setup and cleanup

**URL:** <https://discourse.libsdl.org/t/sdl-refactor-property-assignment-setup-and-cleanup/69470>\
**Category:** SDL Commits\
**Created:** [October 2, 2026, 5:22pm UTC](https://discourse.libsdl.org/t/sdl-refactor-property-assignment-setup-and-cleanup/69470 "2026-10-02T17:22:35Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![SDLPushPostBot](https://discourse.libsdl.org/user_avatar/discourse.libsdl.org/sdlpushpostbot/32/4370_2.png) [@SDLPushPostBot](https://discourse.libsdl.org/u/SDLPushPostBot)\
**Post date:** [October 2, 2026, 5:22pm UTC](https://discourse.libsdl.org/t/sdl-refactor-property-assignment-setup-and-cleanup/69470/1 "2026-10-02T17:22:35Z")

</div>

> <https://github.com/libsdl-org/SDL/commit/118acdf6a7ad9bacba917fa815c08d81f4271eb6>

```diff
From 118acdf6a7ad9bacba917fa815c08d81f4271eb6 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Fri, 2 Oct 2026 07:46:33 -0700
Subject: [PATCH] Refactor property assignment setup and cleanup

---
 src/SDL_properties.c | 242 ++++++++++++++++++-------------------------
 1 file changed, 100 insertions(+), 142 deletions(-)

diff --git a/src/SDL_properties.c b/src/SDL_properties.c
index 467964e48ced0..f044d3b3e5ad6 100644
--- a/src/SDL_properties.c
+++ b/src/SDL_properties.c
@@ -341,67 +341,73 @@ void SDL_UnlockProperties(SDL_PropertiesID props)
     SDL_UnlockMutex(properties->lock);
 }
 
-bool SDL_SetPointerPropertyWithCleanup(SDL_PropertiesID props, const char *name, void *value, SDL_CleanupPropertyCallback cleanup, void *userdata)
+static bool SDL_SetupPropertyAssignment(SDL_PropertiesID props, const char *name, SDL_Properties **properties)
 {
- SDL_Properties *properties = NULL;
- bool result = true;
-
- if (!value) {
- result = SDL_ClearProperty(props, name);
- goto done;
- }
-
     CHECK_PARAM(!props) {
- result = SDL_InvalidParamError("props");
- goto done;
+ return SDL_InvalidParamError("props");
     }
     CHECK_PARAM(!name || !*name) {
- result = SDL_InvalidParamError("name");
- goto done;
+ return SDL_InvalidParamError("name");
     }
 
- SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)props, (const void **)&properties);
+ SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)props, (const void **)properties);
     CHECK_PARAM(!properties) {
- result = SDL_InvalidParamError("props");
- goto done;
+ return SDL_InvalidParamError("props");
     }
 
- SDL_LockMutex(properties->lock);
- {
- SDL_Property *existing;
- if (SDL_FindInHashTable(properties->props, name, (const void **)&existing)) {
- if (existing->type == SDL_PROPERTY_TYPE_POINTER &&
- existing->value.pointer_value == value &&
- existing->cleanup == cleanup &&
- existing->userdata == userdata) {
- // The value is already set
- } else {
- SDL_FreePropertyContents(existing, true);
+ SDL_LockMutex((*properties)->lock);
+ return true;
+}
 
- existing->type = SDL_PROPERTY_TYPE_POINTER;
- existing->value.pointer_value = value;
- existing->cleanup = cleanup;
- existing->userdata = userdata;
- }
- } else {
- char *key = SDL_strdup(name);
- SDL_Property *property = (SDL_Property *)SDL_calloc(1, sizeof(*property));
- if (property) {
- property->type = SDL_PROPERTY_TYPE_POINTER;
- property->value.pointer_value = value;
- property->cleanup = cleanup;
- property->userdata = userdata;
- }
- if (!key || !property ||
- !SDL_InsertIntoHashTable(properties->props, key, property, false)) {
- SDL_FreePropertyWithCleanup(key, property, NULL, true);
- result = false;
+static void SDL_CleanupPropertyAssignment(SDL_Properties *properties)
+{
+ SDL_UnlockMutex(properties->lock);
+}
+
+bool SDL_SetPointerPropertyWithCleanup(SDL_PropertiesID props, const char *name, void *value, SDL_CleanupPropertyCallback cleanup, void *userdata)
+{
+ SDL_Properties *properties = NULL;
+ bool result;
+
+ if (value) {
+ result = SDL_SetupPropertyAssignment(props, name, &properties);
+ if (result) {
+ SDL_Property *existing;
+ if (SDL_FindInHashTable(properties->props, name, (const void **)&existing)) {
+ if (existing->type == SDL_PROPERTY_TYPE_POINTER &&
+ existing->value.pointer_value == value &&
+ existing->cleanup == cleanup &&
+ existing->userdata == userdata) {
+ // The value is already set
+ } else {
+ SDL_FreePropertyContents(existing, true);
+
+ existing->type = SDL_PROPERTY_TYPE_POINTER;
+ existing->value.pointer_value = value;
+ existing->cleanup = cleanup;
+ existing->userdata = userdata;
+ }
+ } else {
+ char *key = SDL_strdup(name);
+ SDL_Property *property = (SDL_Property *)SDL_calloc(1, sizeof(*property));
+ if (property) {
+ property->type = SDL_PROPERTY_TYPE_POINTER;
+ property->value.pointer_value = value;
+ property->cleanup = cleanup;
+ property->userdata = userdata;
+ }
+ if (!key || !property ||
+ !SDL_InsertIntoHashTable(properties->props, key, property, false)) {
+ SDL_FreePropertyWithCleanup(key, property, NULL, true);
+ result = false;
+ }
             }
+ SDL_CleanupPropertyAssignment(properties);
         }
+ } else {
+ result = SDL_ClearProperty(props, name);
     }
- SDL_UnlockMutex(properties->lock);
 
-done:
     if (!result && cleanup) {
         cleanup(userdata, value);
     }
@@ -438,61 +444,49 @@ bool SDL_SetSurfaceProperty(SDL_PropertiesID props, const char *name, SDL_Surfac
 bool SDL_SetStringProperty(SDL_PropertiesID props, const char *name, const char *value)
 {
     SDL_Properties *properties = NULL;
- bool result = true;
-
- if (!value) {
- return SDL_ClearProperty(props, name);
- }
-
- CHECK_PARAM(!props) {
- return SDL_InvalidParamError("props");
- }
- CHECK_PARAM(!name || !*name) {
- return SDL_InvalidParamError("name");
- }
-
- SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)props, (const void **)&properties);
- CHECK_PARAM(!properties) {
- return SDL_InvalidParamError("props");
- }
+ bool result;
 
- SDL_LockMutex(properties->lock);
- {
- SDL_Property *existing;
- if (SDL_FindInHashTable(properties->props, name, (const void **)&existing)) {
- if (existing->type == SDL_PROPERTY_TYPE_STRING &&
- SDL_strcmp(existing->value.string_value, value) == 0) {
- // The value is already set
- } else {
- char *string = SDL_strdup(value);
- if (string) {
- SDL_FreePropertyContents(existing, true);
- existing->type = SDL_PROPERTY_TYPE_STRING;
- existing->value.string_value = string;
+ if (value) {
+ result = SDL_SetupPropertyAssignment(props, name, &properties);
+ if (result) {
+ SDL_Property *existing;
+ if (SDL_FindInHashTable(properties->props, name, (const void **)&existing)) {
+ if (existing->type == SDL_PROPERTY_TYPE_STRING &&
+ SDL_strcmp(existing->value.string_value, value) == 0) {
+ // The value is already set
                 } else {
- result = false;
+ char *string = SDL_strdup(value);
+ if (string) {
+ SDL_FreePropertyContents(existing, true);
+ existing->type = SDL_PROPERTY_TYPE_STRING;
+ existing->value.string_value = string;
+ } else {
+ result = false;
+ }
                 }
- }
- } else {
- char *key = SDL_strdup(name);
- SDL_Property *property = (SDL_Property *)SDL_calloc(1, sizeof(*property));
- char *string = SDL_strdup(value);
- if (property) {
- property->type = SDL_PROPERTY_TYPE_STRING;
- property->value.string_value = string;
- }
- if (!key || !property || !string ||
- !SDL_InsertIntoHashTable(properties->props, key, property, false)) {
+ } else {
+ char *key = SDL_strdup(name);
+ SDL_Property *property = (SDL_Property *)SDL_calloc(1, sizeof(*property));
+ char *string = SDL_strdup(value);
                 if (property) {
- property->value.string_value = NULL;
+ property->type = SDL_PROPERTY_TYPE_STRING;
+ property->value.string_value = string;
+ }
+ if (!key || !property || !string ||
+ !SDL_InsertIntoHashTable(properties->props, key, property, false)) {
+ if (property) {
+ property->value.string_value = NULL;
+ }
+ SDL_free(string);
+ SDL_FreePropertyWithCleanup(key, property, NULL, true);
+ result = false;
                 }
- SDL_free(string);
- SDL_FreePropertyWithCleanup(key, property, NULL, true);
- result = false;
             }
+ SDL_CleanupPropertyAssignment(properties);
         }
+ } else {
+ return SDL_ClearProperty(props, name);
     }
- SDL_UnlockMutex(properties->lock);
 
     return result;
 }
@@ -500,22 +494,10 @@ bool SDL_SetStringProperty(SDL_PropertiesID props, const char *name, const char
 bool SDL_SetNumberProperty(SDL_PropertiesID props, const char *name, Sint64 value)
 {
     SDL_Properties *properties = NULL;
- bool result = true;
-
- CHECK_PARAM(!props) {
- return SDL_InvalidParamError("props");
- }
- CHECK_PARAM(!name || !*name) {
- return SDL_InvalidParamError("name");
- }
-
- SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)props, (const void **)&properties);
- CHECK_PARAM(!properties) {
- return SDL_InvalidParamError("props");
- }
+ bool result;
 
- SDL_LockMutex(properties->lock);
- {
+ result = SDL_SetupPropertyAssignment(props, name, &properties);
+ if (result) {
         SDL_Property *existing;
         if (SDL_FindInHashTable(properties->props, name, (const void **)&existing)) {
             if (existing->type != SDL_PROPERTY_TYPE_NUMBER) {
@@ -536,8 +518,8 @@ bool SDL_SetNumberProperty(SDL_PropertiesID props, const char *name, Sint64 valu
                 result = false;
             }
         }
+ SDL_CleanupPropertyAssignment(properties);
     }
- SDL_UnlockMutex(properties->lock);
 
     return result;
 }
@@ -545,22 +527,10 @@ bool SDL_SetNumberProperty(SDL_PropertiesID props, const char *name, Sint64 valu
 bool SDL_SetFloatProperty(SDL_PropertiesID props, const char *name, float value)
 {
     SDL_Properties *properties = NULL;
- bool result = true;
-
- CHECK_PARAM(!props) {
- return SDL_InvalidParamError("props");
- }
- CHECK_PARAM(!name || !*name) {
- return SDL_InvalidParamError("name");
- }
-
- SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)props, (const void **)&properties);
- CHECK_PARAM(!properties) {
- return SDL_InvalidParamError("props");
- }
+ bool result;
 
- SDL_LockMutex(properties->lock);
- {
+ result = SDL_SetupPropertyAssignment(props, name, &properties);
+ if (result) {
         SDL_Property *existing;
         if (SDL_FindInHashTable(properties->props, name, (const void **)&existing)) {
             if (existing->type != SDL_PROPERTY_TYPE_FLOAT) {
@@ -581,8 +551,8 @@ bool SDL_SetFloatProperty(SDL_PropertiesID props, const char *name, float value)
                 result = false;
             }
         }
+ SDL_CleanupPropertyAssignment(properties);
     }
- SDL_UnlockMutex(properties->lock);
 
     return result;
 }
@@ -590,22 +560,10 @@ bool SDL_SetFloatProperty(SDL_PropertiesID props, const char *name, float value)
 bool SDL_SetBooleanProperty(SDL_PropertiesID props, const char *name, bool value)
 {
     SDL_Properties *properties = NULL;
- bool result = true;
-
- CHECK_PARAM(!props) {
- return SDL_InvalidParamError("props");
- }
- CHECK_PARAM(!name || !*name) {
- return SDL_InvalidParamError("name");
- }
-
- SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)props, (const void **)&properties);
- CHECK_PARAM(!properties) {
- return SDL_InvalidParamError("props");
- }
+ bool result;
 
- SDL_LockMutex(properties->lock);
- {
+ result = SDL_SetupPropertyAssignment(props, name, &properties);
+ if (result) {
         SDL_Property *existing;
         if (SDL_FindInHashTable(properties->props, name, (const void **)&existing)) {
             if (existing->type != SDL_PROPERTY_TYPE_BOOLEAN) {
@@ -626,8 +584,8 @@ bool SDL_SetBooleanProperty(SDL_PropertiesID props, const char *name, bool value
                 result = false;
             }
         }
+ SDL_CleanupPropertyAssignment(properties);
     }
- SDL_UnlockMutex(properties->lock);
 
     return result;
 }

```
