authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-27 07:32:06-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-10-29 06:20:51-07:00
logf6c5525c8476a1a11c7ebbcdca764010eb10f9a6
tree2bb7b8f7b8cd8f2a26647b30fc792fb77a8811ef
parentfd7475c8b2e4ee0d3a12f8517720facc407379b5

std.Io.Threaded: fix compilation on pthreads linux


1 files changed, 20 insertions(+), 24 deletions(-)

lib/std/Io/Threaded.zig+20-24
......@@ -5,6 +5,7 @@ const native_os = builtin.os.tag;
55const is_windows = native_os == .windows;
66const windows = std.os.windows;
77const ws2_32 = std.os.windows.ws2_32;
8const is_debug = builtin.mode == .Debug;
89
910const std = @import("../std.zig");
1011const Io = std.Io;
......@@ -72,11 +73,13 @@ const Closure = struct {
7273 fn requestCancel(closure: *Closure) void {
7374 switch (@atomicRmw(CancelId, &closure.cancel_tid, .Xchg, .canceling, .acq_rel)) {
7475 .none, .canceling => {},
75 else => |tid| switch (native_os) {
76 .linux => _ = std.os.linux.tgkill(std.os.linux.getpid(), @bitCast(tid.toThreadId()), posix.SIG.IO),
77 else => if (std.Thread.use_pthreads) {
78 assert(std.c.pthread_kill(tid.toThreadId(), posix.SIG.IO) == 0);
79 },
76 else => |tid| {
77 if (std.Thread.use_pthreads) {
78 const rc = std.c.pthread_kill(tid.toThreadId(), posix.SIG.IO);
79 if (is_debug) assert(rc == 0);
80 } else if (native_os == .linux) {
81 _ = std.os.linux.tgkill(std.os.linux.getpid(), @bitCast(tid.toThreadId()), posix.SIG.IO);
82 }
8083 },
8184 }
8285 }
......@@ -4883,17 +4886,13 @@ fn address6ToPosix(a: *const net.Ip6Address) posix.sockaddr.in6 {
48834886}
48844887
48854888pub fn errnoBug(err: posix.E) Io.UnexpectedError {
4886 switch (builtin.mode) {
4887 .Debug => std.debug.panic("programmer bug caused syscall error: {t}", .{err}),
4888 else => return error.Unexpected,
4889 }
4889 if (is_debug) std.debug.panic("programmer bug caused syscall error: {t}", .{err});
4890 return error.Unexpected;
48904891}
48914892
48924893fn wsaErrorBug(err: ws2_32.WinsockError) Io.UnexpectedError {
4893 switch (builtin.mode) {
4894 .Debug => std.debug.panic("programmer bug caused syscall error: {t}", .{err}),
4895 else => return error.Unexpected,
4896 }
4894 if (is_debug) std.debug.panic("programmer bug caused syscall error: {t}", .{err});
4895 return error.Unexpected;
48974896}
48984897
48994898pub fn posixSocketMode(mode: net.Socket.Mode) u32 {
......@@ -4911,7 +4910,7 @@ pub fn posixProtocol(protocol: ?net.Protocol) u32 {
49114910}
49124911
49134912fn recoverableOsBugDetected() void {
4914 if (builtin.mode == .Debug) unreachable;
4913 if (is_debug) unreachable;
49154914}
49164915
49174916fn clockToPosix(clock: Io.Clock) posix.clockid_t {
......@@ -5424,7 +5423,7 @@ fn futexWait(t: *Threaded, ptr: *const std.atomic.Value(u32), expect: u32) Io.Ca
54245423 const linux = std.os.linux;
54255424 try t.checkCancel();
54265425 const rc = linux.futex_4arg(ptr, .{ .cmd = .WAIT, .private = true }, expect, null);
5427 if (builtin.mode == .Debug) switch (linux.E.init(rc)) {
5426 if (is_debug) switch (linux.E.init(rc)) {
54285427 .SUCCESS => {}, // notified by `wake()`
54295428 .INTR => {}, // gives caller a chance to check cancellation
54305429 .AGAIN => {}, // ptr.* != expect
......@@ -5447,7 +5446,7 @@ fn futexWait(t: *Threaded, ptr: *const std.atomic.Value(u32), expect: u32) Io.Ca
54475446
54485447 if (status >= 0) return;
54495448
5450 if (builtin.mode == .Debug) switch (@as(c.E, @enumFromInt(-status))) {
5449 if (is_debug) switch (@as(c.E, @enumFromInt(-status))) {
54515450 // Wait was interrupted by the OS or other spurious signalling.
54525451 .INTR => {},
54535452 // Address of the futex was paged out. This is unlikely, but possible in theory, and
......@@ -5473,7 +5472,6 @@ fn futexWait(t: *Threaded, ptr: *const std.atomic.Value(u32), expect: u32) Io.Ca
54735472 [expected] "r" (signed_expect),
54745473 [timeout] "r" (timeout),
54755474 );
5476 const is_debug = builtin.mode == .Debug;
54775475 switch (result) {
54785476 0 => {}, // ok
54795477 1 => {}, // expected != loaded
......@@ -5498,7 +5496,7 @@ pub fn futexWaitUncancelable(ptr: *const std.atomic.Value(u32), expect: u32) voi
54985496 if (native_os == .linux) {
54995497 const linux = std.os.linux;
55005498 const rc = linux.futex_4arg(ptr, .{ .cmd = .WAIT, .private = true }, expect, null);
5501 if (builtin.mode == .Debug) switch (linux.E.init(rc)) {
5499 if (is_debug) switch (linux.E.init(rc)) {
55025500 .SUCCESS => {}, // notified by `wake()`
55035501 .INTR => {}, // gives caller a chance to check cancellation
55045502 .AGAIN => {}, // ptr.* != expect
......@@ -5520,7 +5518,7 @@ pub fn futexWaitUncancelable(ptr: *const std.atomic.Value(u32), expect: u32) voi
55205518
55215519 if (status >= 0) return;
55225520
5523 if (builtin.mode == .Debug) switch (@as(c.E, @enumFromInt(-status))) {
5521 if (is_debug) switch (@as(c.E, @enumFromInt(-status))) {
55245522 // Wait was interrupted by the OS or other spurious signalling.
55255523 .INTR => {},
55265524 // Address of the futex was paged out. This is unlikely, but possible in theory, and
......@@ -5545,7 +5543,6 @@ pub fn futexWaitUncancelable(ptr: *const std.atomic.Value(u32), expect: u32) voi
55455543 [expected] "r" (signed_expect),
55465544 [timeout] "r" (timeout),
55475545 );
5548 const is_debug = builtin.mode == .Debug;
55495546 switch (result) {
55505547 0 => {}, // ok
55515548 1 => {}, // expected != loaded
......@@ -5569,7 +5566,7 @@ pub fn futexWaitDurationUncancelable(ptr: *const std.atomic.Value(u32), expect:
55695566 const linux = std.os.linux;
55705567 var ts = timestampToPosix(timeout.toNanoseconds());
55715568 const rc = linux.futex_4arg(ptr, .{ .cmd = .WAIT, .private = true }, expect, &ts);
5572 if (builtin.mode == .Debug) switch (linux.E.init(rc)) {
5569 if (is_debug) switch (linux.E.init(rc)) {
55735570 .SUCCESS => {}, // notified by `wake()`
55745571 .INTR => {}, // gives caller a chance to check cancellation
55755572 .AGAIN => {}, // ptr.* != expect
......@@ -5594,7 +5591,7 @@ pub fn futexWake(ptr: *const std.atomic.Value(u32), max_waiters: u32) void {
55945591 .{ .cmd = .WAKE, .private = true },
55955592 @min(max_waiters, std.math.maxInt(i32)),
55965593 );
5597 if (builtin.mode == .Debug) switch (linux.E.init(rc)) {
5594 if (is_debug) switch (linux.E.init(rc)) {
55985595 .SUCCESS => {}, // successful wake up
55995596 .INVAL => {}, // invalid futex_wait() on ptr done elsewhere
56005597 .FAULT => {}, // pointer became invalid while doing the wake
......@@ -5607,7 +5604,6 @@ pub fn futexWake(ptr: *const std.atomic.Value(u32), max_waiters: u32) void {
56075604 .NO_ERRNO = true,
56085605 .WAKE_ALL = max_waiters > 1,
56095606 };
5610 const is_debug = builtin.mode == .Debug;
56115607 while (true) {
56125608 const status = c.__ulock_wake(flags, ptr, 0);
56135609 if (status >= 0) return;
......@@ -5756,7 +5752,7 @@ pub const ResetEvent = enum(u32) {
57565752
57575753fn closeSocketWindows(s: ws2_32.SOCKET) void {
57585754 const rc = ws2_32.closesocket(s);
5759 if (builtin.mode == .Debug) switch (rc) {
5755 if (is_debug) switch (rc) {
57605756 0 => {},
57615757 ws2_32.SOCKET_ERROR => switch (ws2_32.WSAGetLastError()) {
57625758 else => recoverableOsBugDetected(),