| ... | ... | @@ -5,6 +5,7 @@ const native_os = builtin.os.tag; |
| 5 | 5 | const is_windows = native_os == .windows; |
| 6 | 6 | const windows = std.os.windows; |
| 7 | 7 | const ws2_32 = std.os.windows.ws2_32; |
| 8 | const is_debug = builtin.mode == .Debug; |
| 8 | 9 | |
| 9 | 10 | const std = @import("../std.zig"); |
| 10 | 11 | const Io = std.Io; |
| ... | ... | @@ -72,11 +73,13 @@ const Closure = struct { |
| 72 | 73 | fn requestCancel(closure: *Closure) void { |
| 73 | 74 | switch (@atomicRmw(CancelId, &closure.cancel_tid, .Xchg, .canceling, .acq_rel)) { |
| 74 | 75 | .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 | } |
| 80 | 83 | }, |
| 81 | 84 | } |
| 82 | 85 | } |
| ... | ... | @@ -4883,17 +4886,13 @@ fn address6ToPosix(a: *const net.Ip6Address) posix.sockaddr.in6 { |
| 4883 | 4886 | } |
| 4884 | 4887 | |
| 4885 | 4888 | pub 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; |
| 4890 | 4891 | } |
| 4891 | 4892 | |
| 4892 | 4893 | fn 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; |
| 4897 | 4896 | } |
| 4898 | 4897 | |
| 4899 | 4898 | pub fn posixSocketMode(mode: net.Socket.Mode) u32 { |
| ... | ... | @@ -4911,7 +4910,7 @@ pub fn posixProtocol(protocol: ?net.Protocol) u32 { |
| 4911 | 4910 | } |
| 4912 | 4911 | |
| 4913 | 4912 | fn recoverableOsBugDetected() void { |
| 4914 | | if (builtin.mode == .Debug) unreachable; |
| 4913 | if (is_debug) unreachable; |
| 4915 | 4914 | } |
| 4916 | 4915 | |
| 4917 | 4916 | fn 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 |
| 5424 | 5423 | const linux = std.os.linux; |
| 5425 | 5424 | try t.checkCancel(); |
| 5426 | 5425 | 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)) { |
| 5428 | 5427 | .SUCCESS => {}, // notified by `wake()` |
| 5429 | 5428 | .INTR => {}, // gives caller a chance to check cancellation |
| 5430 | 5429 | .AGAIN => {}, // ptr.* != expect |
| ... | ... | @@ -5447,7 +5446,7 @@ fn futexWait(t: *Threaded, ptr: *const std.atomic.Value(u32), expect: u32) Io.Ca |
| 5447 | 5446 | |
| 5448 | 5447 | if (status >= 0) return; |
| 5449 | 5448 | |
| 5450 | | if (builtin.mode == .Debug) switch (@as(c.E, @enumFromInt(-status))) { |
| 5449 | if (is_debug) switch (@as(c.E, @enumFromInt(-status))) { |
| 5451 | 5450 | // Wait was interrupted by the OS or other spurious signalling. |
| 5452 | 5451 | .INTR => {}, |
| 5453 | 5452 | // 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 |
| 5473 | 5472 | [expected] "r" (signed_expect), |
| 5474 | 5473 | [timeout] "r" (timeout), |
| 5475 | 5474 | ); |
| 5476 | | const is_debug = builtin.mode == .Debug; |
| 5477 | 5475 | switch (result) { |
| 5478 | 5476 | 0 => {}, // ok |
| 5479 | 5477 | 1 => {}, // expected != loaded |
| ... | ... | @@ -5498,7 +5496,7 @@ pub fn futexWaitUncancelable(ptr: *const std.atomic.Value(u32), expect: u32) voi |
| 5498 | 5496 | if (native_os == .linux) { |
| 5499 | 5497 | const linux = std.os.linux; |
| 5500 | 5498 | 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)) { |
| 5502 | 5500 | .SUCCESS => {}, // notified by `wake()` |
| 5503 | 5501 | .INTR => {}, // gives caller a chance to check cancellation |
| 5504 | 5502 | .AGAIN => {}, // ptr.* != expect |
| ... | ... | @@ -5520,7 +5518,7 @@ pub fn futexWaitUncancelable(ptr: *const std.atomic.Value(u32), expect: u32) voi |
| 5520 | 5518 | |
| 5521 | 5519 | if (status >= 0) return; |
| 5522 | 5520 | |
| 5523 | | if (builtin.mode == .Debug) switch (@as(c.E, @enumFromInt(-status))) { |
| 5521 | if (is_debug) switch (@as(c.E, @enumFromInt(-status))) { |
| 5524 | 5522 | // Wait was interrupted by the OS or other spurious signalling. |
| 5525 | 5523 | .INTR => {}, |
| 5526 | 5524 | // 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 |
| 5545 | 5543 | [expected] "r" (signed_expect), |
| 5546 | 5544 | [timeout] "r" (timeout), |
| 5547 | 5545 | ); |
| 5548 | | const is_debug = builtin.mode == .Debug; |
| 5549 | 5546 | switch (result) { |
| 5550 | 5547 | 0 => {}, // ok |
| 5551 | 5548 | 1 => {}, // expected != loaded |
| ... | ... | @@ -5569,7 +5566,7 @@ pub fn futexWaitDurationUncancelable(ptr: *const std.atomic.Value(u32), expect: |
| 5569 | 5566 | const linux = std.os.linux; |
| 5570 | 5567 | var ts = timestampToPosix(timeout.toNanoseconds()); |
| 5571 | 5568 | 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)) { |
| 5573 | 5570 | .SUCCESS => {}, // notified by `wake()` |
| 5574 | 5571 | .INTR => {}, // gives caller a chance to check cancellation |
| 5575 | 5572 | .AGAIN => {}, // ptr.* != expect |
| ... | ... | @@ -5594,7 +5591,7 @@ pub fn futexWake(ptr: *const std.atomic.Value(u32), max_waiters: u32) void { |
| 5594 | 5591 | .{ .cmd = .WAKE, .private = true }, |
| 5595 | 5592 | @min(max_waiters, std.math.maxInt(i32)), |
| 5596 | 5593 | ); |
| 5597 | | if (builtin.mode == .Debug) switch (linux.E.init(rc)) { |
| 5594 | if (is_debug) switch (linux.E.init(rc)) { |
| 5598 | 5595 | .SUCCESS => {}, // successful wake up |
| 5599 | 5596 | .INVAL => {}, // invalid futex_wait() on ptr done elsewhere |
| 5600 | 5597 | .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 { |
| 5607 | 5604 | .NO_ERRNO = true, |
| 5608 | 5605 | .WAKE_ALL = max_waiters > 1, |
| 5609 | 5606 | }; |
| 5610 | | const is_debug = builtin.mode == .Debug; |
| 5611 | 5607 | while (true) { |
| 5612 | 5608 | const status = c.__ulock_wake(flags, ptr, 0); |
| 5613 | 5609 | if (status >= 0) return; |
| ... | ... | @@ -5756,7 +5752,7 @@ pub const ResetEvent = enum(u32) { |
| 5756 | 5752 | |
| 5757 | 5753 | fn closeSocketWindows(s: ws2_32.SOCKET) void { |
| 5758 | 5754 | const rc = ws2_32.closesocket(s); |
| 5759 | | if (builtin.mode == .Debug) switch (rc) { |
| 5755 | if (is_debug) switch (rc) { |
| 5760 | 5756 | 0 => {}, |
| 5761 | 5757 | ws2_32.SOCKET_ERROR => switch (ws2_32.WSAGetLastError()) { |
| 5762 | 5758 | else => recoverableOsBugDetected(), |