From 1182f06c1487149282f699d6265e7ef91e8a56ad Mon Sep 17 00:00:00 2001 From: Brandon Black Date: Tue, 12 May 2026 13:22:07 -0500 Subject: [PATCH 1/2] Io: Fix Threaded.sleep(.none), doc Timeout.none Timeout.none implicitly seems to mean indefinitely nearly everywhere I can see. However, Io.Threaded.sleep() has a short-circuit at the top which treats Timeout.none as effectively zero (no sleep at all), even though the per-target functions it calls afterwards would otherwise would honor .none correctly. This patch removes this (presumably erronenous) short-circuit and documents Timeout.none's meaning explicitly. --- lib/std/Io.zig | 1 + lib/std/Io/Threaded.zig | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/Io.zig b/lib/std/Io.zig index f3ef2757acad16f3dc4e548cc25d1172ba47e032..269372f12ec3a2ebc4f5dae810be15736b7dd5d4 100644 --- a/lib/std/Io.zig +++ b/lib/std/Io.zig @@ -1139,6 +1139,7 @@ pub const Duration = struct { /// Declares under what conditions an operation should return `error.Timeout`. pub const Timeout = union(enum) { + /// `.none` will wait forever none, duration: Clock.Duration, deadline: Clock.Timestamp, diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig index 037fce335064106b7b8051b94d3380e3138f54d5..8180a57dc5f3a73ecf3f9425d1bc69fbdd89b25d 100644 --- a/lib/std/Io/Threaded.zig +++ b/lib/std/Io/Threaded.zig @@ -11711,7 +11711,6 @@ fn nowWasi(clock: Io.Clock) Io.Timestamp { fn sleep(userdata: ?*anyopaque, timeout: Io.Timeout) Io.Cancelable!void { const t: *Threaded = @ptrCast(@alignCast(userdata)); - if (timeout == .none) return; if (use_parking_sleep) return parking_sleep.sleep(timeout); if (native_os == .wasi) return sleepWasi(t, timeout); if (@TypeOf(posix.system.clock_nanosleep) != void) return sleepPosix(timeout); -- 2.54.0 From 47825d7de3b9b26ab1dd7bca669b693bca2995e8 Mon Sep 17 00:00:00 2001 From: Brandon Black Date: Mon, 11 May 2026 07:34:52 -0500 Subject: [PATCH 2/2] Io.operateTimeout: if timeout == .none, operate It's far simpler for the same effective outcome (no Batch instantiation, no quick-success attempt + infinite poll first) --- lib/std/Io.zig | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/std/Io.zig b/lib/std/Io.zig index 269372f12ec3a2ebc4f5dae810be15736b7dd5d4..758768634394597d57c2636ee80d62d73ee2ef38 100644 --- a/lib/std/Io.zig +++ b/lib/std/Io.zig @@ -466,6 +466,7 @@ pub const OperateTimeoutError = Cancelable || Timeout.Error || ConcurrentError; /// Performs one `Operation` with provided `timeout`. pub fn operateTimeout(io: Io, operation: Operation, timeout: Timeout) OperateTimeoutError!Operation.Result { + if (timeout == .none) return io.vtable.operate(io.userdata, operation); var storage: [1]Operation.Storage = undefined; var batch: Batch = .init(&storage); batch.addAt(0, operation); -- 2.54.0