LibC: Wait for thread before returning from pthread_create

We now make sure the thread starts up and sets its id. There was a race
condition where a process could create a thread and immediately try to
join it. If the thread had not initialized itself the join would fail
with EINVAL as we passed -1 as its id.
This commit is contained in:
2026-07-03 02:14:10 +03:00
parent 13bf1ba647
commit 917321eb5f

View File

@@ -99,7 +99,7 @@ extern "C" void _pthread_trampoline_cpp(void* arg)
{ {
auto info = *static_cast<pthread_trampoline_info_t*>(arg); auto info = *static_cast<pthread_trampoline_info_t*>(arg);
info.uthread->id = syscall(SYS_THREAD_GETID); BAN::atomic_store(info.uthread->id, syscall(SYS_THREAD_GETID));
#if defined(__x86_64__) #if defined(__x86_64__)
syscall(SYS_SET_FSBASE, info.uthread); syscall(SYS_SET_FSBASE, info.uthread);
@@ -500,6 +500,10 @@ int pthread_create(pthread_t* __restrict thread, const pthread_attr_t* __restric
if (syscall(SYS_THREAD_CREATE, _pthread_trampoline, info, info->uthread->attr.stackaddr, info->uthread->attr.stacksize) == -1) if (syscall(SYS_THREAD_CREATE, _pthread_trampoline, info, info->uthread->attr.stackaddr, info->uthread->attr.stacksize) == -1)
goto pthread_create_error; goto pthread_create_error;
// wait for the thread to initialize its id
while (BAN::atomic_load(result->id) == -1)
sched_yield();
if (thread) if (thread)
*thread = result; *thread = result;
return 0; return 0;