fix thread_unix for Darwin after pthread corrections in posix package

afed3ce removed the sys/unix package and moved over to sys/posix, it has
new bindings for the pthread APIs but should have been equivalent (not).

8fb7182 used `CANCEL_ENABLE :: 0`, `CANCEL_DISABLE :: 1`, `CANCEL_DEFERRED :: 0`, `CANCEL_ASYNCHRONOUS :: 1` for Darwin, while the
correct values are `1`, `0`, `2` and `0` respectively (same mistake was made for
FreeBSD in that commit).

What this meant is that the
`pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS)` was not actually
successful, but because the error wasn't checked it was assumed it was.
It also meant `pthread_setcancelstate(PTHREAD_CANCEL_ENABLE)` would
actually be setting `PTHREAD_CANCEL_DISABLE`.

The code in this PR restores the behaviour by now actually deliberately
setting `PTHREAD_CANCEL_DISABLE` and not setting
`PTHREAD_CANCEL_ASYNCHRONOUS` which was the previous behaviour that does
actually seem to work for some reason.

(I also fixed an issue in fmt where `x` would use uppercase if it was a
pointer.)
This commit is contained in:
Laytan Laats
2024-12-01 11:54:52 +11:00
committed by flysand7
parent 96e6393614
commit c08408ea08
5 changed files with 73 additions and 7 deletions
+1 -1
View File
@@ -1531,7 +1531,7 @@ fmt_pointer :: proc(fi: ^Info, p: rawptr, verb: rune) {
case 'o': _fmt_int(fi, u, 8, false, 8*size_of(rawptr), __DIGITS_UPPER)
case 'i', 'd': _fmt_int(fi, u, 10, false, 8*size_of(rawptr), __DIGITS_UPPER)
case 'z': _fmt_int(fi, u, 12, false, 8*size_of(rawptr), __DIGITS_UPPER)
case 'x': _fmt_int(fi, u, 16, false, 8*size_of(rawptr), __DIGITS_UPPER)
case 'x': _fmt_int(fi, u, 16, false, 8*size_of(rawptr), __DIGITS_LOWER)
case 'X': _fmt_int(fi, u, 16, false, 8*size_of(rawptr), __DIGITS_UPPER)
case:
+12 -2
View File
@@ -355,12 +355,16 @@ Thread_Scope :: enum c.int {
}
Cancel_State :: enum c.int {
// Cancel takes place at next cancellation point.
ENABLE = PTHREAD_CANCEL_ENABLE,
// Cancel postponed.
DISABLE = PTHREAD_CANCEL_DISABLE,
}
Cancel_Type :: enum c.int {
// Cancel waits until cancellation point.
DEFERRED = PTHREAD_CANCEL_DEFERRED,
// Cancel occurs immediately.
ASYNCHRONOUS = PTHREAD_CANCEL_ASYNCHRONOUS,
}
@@ -372,6 +376,12 @@ when ODIN_OS == .Darwin {
PTHREAD_CANCEL_DISABLE :: 0x00
PTHREAD_CANCEL_ENABLE :: 0x01
// PTHREAD_CANCEL_ASYNCHRONOUS :: 1
// PTHREAD_CANCEL_DEFERRED :: 0
//
// PTHREAD_CANCEL_DISABLE :: 1
// PTHREAD_CANCEL_ENABLE :: 0
PTHREAD_CANCELED :: rawptr(uintptr(1))
PTHREAD_CREATE_DETACHED :: 2
@@ -434,8 +444,8 @@ when ODIN_OS == .Darwin {
PTHREAD_PRIO_NONE :: 0
PTHREAD_PRIO_PROTECT :: 2
PTHREAD_PROCESS_SHARED :: 0
PTHREAD_PROCESS_PRIVATE :: 1
PTHREAD_PROCESS_SHARED :: 1
PTHREAD_PROCESS_PRIVATE :: 0
PTHREAD_SCOPE_PROCESS :: 0
PTHREAD_SCOPE_SYSTEM :: 2
+12 -4
View File
@@ -23,7 +23,9 @@ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread {
t := (^Thread)(t)
// We need to give the thread a moment to start up before we enable cancellation.
can_set_thread_cancel_state := posix.pthread_setcancelstate(.ENABLE, nil) == nil
// NOTE(laytan): setting to .DISABLE on darwin, with .ENABLE pthread_cancel would deadlock
// most of the time, don't ask me why.
can_set_thread_cancel_state := posix.pthread_setcancelstate(.DISABLE when ODIN_OS == .Darwin else .ENABLE, nil) == nil
t.id = sync.current_thread_id()
@@ -36,9 +38,15 @@ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread {
}
// Enable thread's cancelability.
if can_set_thread_cancel_state {
posix.pthread_setcanceltype (.ASYNCHRONOUS, nil)
posix.pthread_setcancelstate(.ENABLE, nil)
// 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
// basically always make it deadlock.
if ODIN_OS != .Darwin && can_set_thread_cancel_state {
err := posix.pthread_setcancelstate(.ENABLE, nil)
assert_contextless(err == nil)
err = posix.pthread_setcanceltype(.ASYNCHRONOUS, nil)
assert_contextless(err == nil)
}
{