From 6d35168a637a93aede6cb5a43be7aed8a7d7ff67 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Mon, 4 May 2026 23:43:34 -0400
Subject: [PATCH] thread: Remove semaphore in thread creation.
This was added so that the new thread definitely has its threadid set, via
SDL_GetCurrentThreadID(), before SDL_CreatThread returns, but this broke
Emscripten, which can't wait on a newly-created thread, since the thread won't
start until a later mainloop iteration.
Now we have the creating thread set this id in SDL_SYS_CreateThread, where
platform-specific logic can figure out how to calculate the new thread's ID
from the parent thread, without using SDL_GetCurrentThreadID().
Fixes #15509.
(cherry picked from commit 922b872b4f3ea0fa5ae959040fe14157ac295449)
---
src/thread/SDL_thread.c | 17 -----------------
src/thread/SDL_thread_c.h | 1 -
src/thread/n3ds/SDL_systhread.c | 4 ++++
src/thread/ps2/SDL_systhread.c | 3 +++
src/thread/psp/SDL_systhread.c | 2 ++
src/thread/pthread/SDL_systhread.c | 2 ++
src/thread/vita/SDL_systhread.c | 2 ++
src/thread/windows/SDL_systhread.c | 3 +++
8 files changed, 16 insertions(+), 18 deletions(-)
diff --git a/src/thread/SDL_thread.c b/src/thread/SDL_thread.c
index 0d02bcd312573..639090c498202 100644
--- a/src/thread/SDL_thread.c
+++ b/src/thread/SDL_thread.c
@@ -335,11 +335,6 @@ void SDL_RunThread(SDL_Thread *thread)
// Perform any system-dependent setup - this function may not fail
SDL_SYS_SetupThread(thread->name);
- // 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);
@@ -396,13 +391,6 @@ 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;
@@ -413,16 +401,11 @@ 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);
return 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 25b7096482715..3659b85cc4af3 100644
--- a/src/thread/SDL_thread_c.h
+++ b/src/thread/SDL_thread_c.h
@@ -54,7 +54,6 @@ 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;
diff --git a/src/thread/n3ds/SDL_systhread.c b/src/thread/n3ds/SDL_systhread.c
index a9a18ab8f70a7..5c1f0a1fa0a55 100644
--- a/src/thread/n3ds/SDL_systhread.c
+++ b/src/thread/n3ds/SDL_systhread.c
@@ -72,6 +72,10 @@ bool SDL_SYS_CreateThread(SDL_Thread *thread,
return SDL_SetError("Couldn't create thread");
}
+ u32 thread_ID = 0;
+ svcGetThreadId(&thread_ID, threadGetHandle(thread->handle));
+ thread->threadid = (SDL_ThreadID) thread_ID;
+
return true;
}
diff --git a/src/thread/ps2/SDL_systhread.c b/src/thread/ps2/SDL_systhread.c
index 96c9dcc8e5966..6d038915c6b4d 100644
--- a/src/thread/ps2/SDL_systhread.c
+++ b/src/thread/ps2/SDL_systhread.c
@@ -95,6 +95,9 @@ bool SDL_SYS_CreateThread(SDL_Thread *thread,
if (StartThread(thread->handle, thread) < 0) {
return SDL_SetError("StartThread() failed");
}
+
+ thread->threadid = (SDL_ThreadID) thread->handle;
+
return true;
}
diff --git a/src/thread/psp/SDL_systhread.c b/src/thread/psp/SDL_systhread.c
index 545165846da6b..f61dcea7909ca 100644
--- a/src/thread/psp/SDL_systhread.c
+++ b/src/thread/psp/SDL_systhread.c
@@ -66,6 +66,8 @@ bool SDL_SYS_CreateThread(SDL_Thread *thread,
return SDL_SetError("sceKernelCreateThread() failed");
}
+ thread->threadid = (SDL_ThreadID) thread->handle;
+
sceKernelStartThread(thread->handle, 4, &thread);
return true;
}
diff --git a/src/thread/pthread/SDL_systhread.c b/src/thread/pthread/SDL_systhread.c
index 09d3c896b8ca8..f4d4c4d872a5e 100644
--- a/src/thread/pthread/SDL_systhread.c
+++ b/src/thread/pthread/SDL_systhread.c
@@ -116,6 +116,8 @@ bool SDL_SYS_CreateThread(SDL_Thread *thread,
return SDL_SetError("Not enough resources to create thread");
}
+ thread->threadid = (SDL_ThreadID) thread->handle; // the SDL thread ID is just the pthread_t.
+
return true;
}
diff --git a/src/thread/vita/SDL_systhread.c b/src/thread/vita/SDL_systhread.c
index 79ac8b5ffb616..32946522a1399 100644
--- a/src/thread/vita/SDL_systhread.c
+++ b/src/thread/vita/SDL_systhread.c
@@ -86,6 +86,8 @@ bool SDL_SYS_CreateThread(SDL_Thread *thread,
return SDL_SetError("sceKernelCreateThread() failed");
}
+ thread->threadid = (SDL_ThreadID) thread->handle;
+
sceKernelStartThread(thread->handle, 4, &thread);
return true;
}
diff --git a/src/thread/windows/SDL_systhread.c b/src/thread/windows/SDL_systhread.c
index 530f44929a2f0..1244c344640e5 100644
--- a/src/thread/windows/SDL_systhread.c
+++ b/src/thread/windows/SDL_systhread.c
@@ -77,15 +77,18 @@ bool SDL_SYS_CreateThread(SDL_Thread *thread,
thread->handle = (SYS_ThreadHandle)((size_t)pfnBeginThread(NULL, (unsigned int)thread->stacksize,
RunThreadViaBeginThreadEx,
thread, flags, &threadid));
+ thread->threadid = (SDL_ThreadID) threadid;
} else {
DWORD threadid = 0;
thread->handle = CreateThread(NULL, thread->stacksize,
RunThreadViaCreateThread,
thread, flags, &threadid);
+ thread->threadid = (SDL_ThreadID) threadid;
}
if (!thread->handle) {
return SDL_SetError("Not enough resources to create thread");
}
+
return true;
}