aboutsummaryrefslogtreecommitdiff
path: root/core/thread
diff options
context:
space:
mode:
authorFeoramund <161657516+Feoramund@users.noreply.github.com>2024-05-10 17:00:07 -0400
committerFeoramund <161657516+Feoramund@users.noreply.github.com>2024-05-10 17:24:45 -0400
commit33c6f75a2ea8ba1b21c64767914d5faf4e2d22b0 (patch)
treed90fa802f8f29891962da1ce310843ee6932f7e7 /core/thread
parent2250eb3e78eb38d22c0e8c288f82e6ded20b3cfe (diff)
Fix joining non-`Started` threads from blocking main thread
Diffstat (limited to 'core/thread')
-rw-r--r--core/thread/thread_unix.odin9
-rw-r--r--core/thread/thread_windows.odin12
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) {