From 33c6f75a2ea8ba1b21c64767914d5faf4e2d22b0 Mon Sep 17 00:00:00 2001 From: Feoramund <161657516+Feoramund@users.noreply.github.com> Date: Fri, 10 May 2024 17:00:07 -0400 Subject: [PATCH] Fix joining non-`Started` threads from blocking main thread --- core/thread/thread_unix.odin | 9 +++++++++ core/thread/thread_windows.odin | 12 ++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/core/thread/thread_unix.odin b/core/thread/thread_unix.odin index 290f86eac..7c353fd33 100644 --- a/core/thread/thread_unix.odin +++ b/core/thread/thread_unix.odin @@ -36,6 +36,10 @@ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread { sync.wait(&t.cond, &t.mutex) } + if .Joined in t.flags { + return nil + } + when ODIN_OS != .Darwin { // Enable thread's cancelability. if can_set_thread_cancel_state { @@ -143,6 +147,11 @@ _join :: proc(t: ^Thread) { if res, ok := CAS(&t.flags, unjoined, joined); res == joined && !ok { return } + // Prevent non-started threads from blocking main thread with initial wait + // condition. + if .Started not_in unjoined { + _start(t) + } unix.pthread_join(t.unix_thread, nil) } diff --git a/core/thread/thread_windows.odin b/core/thread/thread_windows.odin index e85b2b62a..4e5e8c07a 100644 --- a/core/thread/thread_windows.odin +++ b/core/thread/thread_windows.odin @@ -24,6 +24,10 @@ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread { __windows_thread_entry_proc :: proc "system" (t_: rawptr) -> win32.DWORD { t := (^Thread)(t_) + if .Joined in t.flags { + return 0 + } + t.id = sync.current_thread_id() { @@ -93,11 +97,15 @@ _join :: proc(t: ^Thread) { return } + t.flags += {.Joined} + + if .Started not_in t.flags { + _start(t) + } + win32.WaitForSingleObject(t.win32_thread, win32.INFINITE) win32.CloseHandle(t.win32_thread) t.win32_thread = win32.INVALID_HANDLE - - t.flags += {.Joined} } _join_multiple :: proc(threads: ..^Thread) {