From 0756603e6d88d4e453e9dbfba5fea10c15babee6 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Mon, 30 Mar 2026 10:08:06 -0400
Subject: [PATCH] thread: SDL_CreateThread() shouldn't return before the new
thread is set up.
Fixes #15290.
---
src/thread/SDL_thread.c | 14 ++++++++++++++
src/thread/SDL_thread_c.h | 1 +
2 files changed, 15 insertions(+)
diff --git a/src/thread/SDL_thread.c b/src/thread/SDL_thread.c
index 04b0573920449..9ffba9592c531 100644
--- a/src/thread/SDL_thread.c
+++ b/src/thread/SDL_thread.c
@@ -333,6 +333,8 @@ void SDL_RunThread(SDL_Thread *thread)
// Get the thread id
thread->threadid = SDL_GetCurrentThreadID();
+ SDL_SignalSemaphore(thread->ready_sem); // the thread is officially ready to run!
+
// Run the function
*statusloc = userfunc(userdata);
@@ -389,6 +391,13 @@ SDL_Thread *SDL_CreateThreadWithPropertiesRuntime(SDL_PropertiesID props,
}
}
+ thread->ready_sem = SDL_CreateSemaphore(0);
+ if (!thread->ready_sem) {
+ SDL_free(thread->name);
+ SDL_free(thread);
+ return NULL;
+ }
+
thread->userfunc = fn;
thread->userdata = userdata;
thread->stacksize = stacksize;
@@ -399,11 +408,16 @@ SDL_Thread *SDL_CreateThreadWithPropertiesRuntime(SDL_PropertiesID props,
if (!SDL_SYS_CreateThread(thread, pfnBeginThread, pfnEndThread)) {
// Oops, failed. Gotta free everything
SDL_SetObjectValid(thread, SDL_OBJECT_TYPE_THREAD, false);
+ SDL_DestroySemaphore(thread->ready_sem);
SDL_free(thread->name);
SDL_free(thread);
thread = NULL;
}
+ SDL_WaitSemaphore(thread->ready_sem);
+ SDL_DestroySemaphore(thread->ready_sem);
+ thread->ready_sem = NULL;
+
// Everything is running now
return thread;
}
diff --git a/src/thread/SDL_thread_c.h b/src/thread/SDL_thread_c.h
index 3659b85cc4af3..25b7096482715 100644
--- a/src/thread/SDL_thread_c.h
+++ b/src/thread/SDL_thread_c.h
@@ -54,6 +54,7 @@ struct SDL_Thread
SDL_error errbuf;
char *name;
size_t stacksize; // 0 for default, >0 for user-specified stack size.
+ SDL_Semaphore *ready_sem; // signals when the thread is set up and about to start running.
int(SDLCALL *userfunc)(void *);
void *userdata;
void *data;