aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorJeroen van Rijn <Kelimion@users.noreply.github.com>2025-06-21 11:54:46 +0200
committerGitHub <noreply@github.com>2025-06-21 11:54:46 +0200
commitedb1f8a76dfb380d862fb2d2d1239a398fc87fcd (patch)
treecba4f52771815f3308314fcfbab601bf150cd928 /core
parent8dc374a6ae43d773eba78a66d850a3733d500988 (diff)
parent1903d7211ee42286cb45aa77a7c97e3bb131e4d5 (diff)
Merge pull request #5383 from Kelimion/thread-fix
Fix early join after start.
Diffstat (limited to 'core')
-rw-r--r--core/thread/thread_unix.odin11
-rw-r--r--core/thread/thread_windows.odin15
2 files changed, 13 insertions, 13 deletions
diff --git a/core/thread/thread_unix.odin b/core/thread/thread_unix.odin
index 7be5103ae..1431442a9 100644
--- a/core/thread/thread_unix.odin
+++ b/core/thread/thread_unix.odin
@@ -29,14 +29,10 @@ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread {
t.id = sync.current_thread_id()
- if .Started not_in sync.atomic_load(&t.flags) {
+ for (.Started not_in sync.atomic_load(&t.flags)) {
sync.wait(&t.start_ok)
}
- if .Joined in sync.atomic_load(&t.flags) {
- return nil
- }
-
// Enable thread's cancelability.
// NOTE(laytan): Darwin does not correctly/fully support all of this, not doing this does
// actually make pthread_cancel work in the capacity of my tests, while executing this would
@@ -148,10 +144,13 @@ _join :: proc(t: ^Thread) {
// Prevent non-started threads from blocking main thread with initial wait
// condition.
- if .Started not_in sync.atomic_load(&t.flags) {
+ for (.Started not_in sync.atomic_load(&t.flags)) {
_start(t)
}
+
posix.pthread_join(t.unix_thread, nil)
+
+ t.flags += {.Joined}
}
_join_multiple :: proc(threads: ..^Thread) {
diff --git a/core/thread/thread_windows.odin b/core/thread/thread_windows.odin
index 438f79c6f..358e3e7f1 100644
--- a/core/thread/thread_windows.odin
+++ b/core/thread/thread_windows.odin
@@ -13,6 +13,7 @@ Thread_Os_Specific :: struct {
win32_thread: win32.HANDLE,
win32_thread_id: win32.DWORD,
mutex: sync.Mutex,
+ start_ok: sync.Sema,
}
_thread_priority_map := [Thread_Priority]i32{
@@ -27,8 +28,8 @@ _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 sync.atomic_load(&t.flags) {
- return 0
+ for (.Started not_in sync.atomic_load(&t.flags)) {
+ sync.wait(&t.start_ok)
}
{
@@ -102,16 +103,15 @@ _join :: proc(t: ^Thread) {
return
}
- t.flags += {.Joined}
-
- if .Started not_in t.flags {
- t.flags += {.Started}
- win32.ResumeThread(t.win32_thread)
+ for (.Started not_in sync.atomic_load(&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) {
@@ -135,6 +135,7 @@ _join_multiple :: proc(threads: ..^Thread) {
for t in threads {
win32.CloseHandle(t.win32_thread)
t.win32_thread = win32.INVALID_HANDLE
+ t.flags += {.Joined}
}
}