Call pthread_cancel on Darwin, with advisory comment

This commit is contained in:
Feoramund
2024-06-28 20:47:37 -04:00
parent 13539d3be1
commit 0ea0fac2f9
+17 -14
View File
@@ -23,10 +23,8 @@ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread {
__unix_thread_entry_proc :: proc "c" (t: rawptr) -> rawptr { __unix_thread_entry_proc :: proc "c" (t: rawptr) -> rawptr {
t := (^Thread)(t) t := (^Thread)(t)
when ODIN_OS != .Darwin { // We need to give the thread a moment to start up before we enable cancellation.
// We need to give the thread a moment to start up before we enable cancellation. can_set_thread_cancel_state := unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_ENABLE, nil) == 0
can_set_thread_cancel_state := unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_ENABLE, nil) == 0
}
sync.lock(&t.mutex) sync.lock(&t.mutex)
@@ -42,12 +40,10 @@ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread {
return nil return nil
} }
when ODIN_OS != .Darwin { // Enable thread's cancelability.
// Enable thread's cancelability. if can_set_thread_cancel_state {
if can_set_thread_cancel_state { unix.pthread_setcanceltype (unix.PTHREAD_CANCEL_ASYNCHRONOUS, nil)
unix.pthread_setcanceltype (unix.PTHREAD_CANCEL_ASYNCHRONOUS, nil) unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_ENABLE, nil)
unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_ENABLE, nil)
}
} }
{ {
@@ -169,10 +165,17 @@ _destroy :: proc(t: ^Thread) {
} }
_terminate :: proc(t: ^Thread, exit_code: int) { _terminate :: proc(t: ^Thread, exit_code: int) {
// `pthread_cancel` is unreliable on Darwin for unknown reasons. // NOTE(Feoramund): For thread cancellation to succeed on BSDs and
when ODIN_OS != .Darwin { // possibly Darwin systems, the thread must call one of the pthread
unix.pthread_cancel(t.unix_thread) // cancelation points at some point after this.
} //
// The most obvious one of these is `pthread_cancel`, but there is an
// entire list of functions that act as cancelation points available in the
// pthreads manual page.
//
// This is in contrast to behavior I have seen on Linux where the thread is
// just terminated.
unix.pthread_cancel(t.unix_thread)
} }
_yield :: proc() { _yield :: proc() {