authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-30 11:45:08-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-30 22:03:33-08:00
logb6f4bb91c41bb78276ad54725ae5c61a160defd6
tree141115a0a7bd28a43686b924c670de5977c7c709
parent25aef0dd8786c5b5342eda167a609529efa09353

std.Io: add documentation to Batch


2 files changed, 31 insertions(+), 5 deletions(-)

lib/std/Io.zig+30-4
...@@ -150,7 +150,7 @@ pub const VTable = struct {...@@ -150,7 +150,7 @@ pub const VTable = struct {
150 futexWake: *const fn (?*anyopaque, ptr: *const u32, max_waiters: u32) void,150 futexWake: *const fn (?*anyopaque, ptr: *const u32, max_waiters: u32) void,
151151
152 operate: *const fn (?*anyopaque, Operation) Cancelable!Operation.Result,152 operate: *const fn (?*anyopaque, Operation) Cancelable!Operation.Result,
153 batchAwaitAsync: *const fn (?*anyopaque, *Batch) Batch.AwaitAsyncError!void,153 batchAwaitAsync: *const fn (?*anyopaque, *Batch) Cancelable!void,
154 batchAwaitConcurrent: *const fn (?*anyopaque, *Batch, Timeout) Batch.AwaitConcurrentError!void,154 batchAwaitConcurrent: *const fn (?*anyopaque, *Batch, Timeout) Batch.AwaitConcurrentError!void,
155 batchCancel: *const fn (?*anyopaque, *Batch) void,155 batchCancel: *const fn (?*anyopaque, *Batch) void,
156156
...@@ -359,7 +359,7 @@ pub fn operate(io: Io, operation: Operation) Cancelable!Operation.Result {...@@ -359,7 +359,7 @@ pub fn operate(io: Io, operation: Operation) Cancelable!Operation.Result {
359/// complete.359/// complete.
360///360///
361/// This is a low-level abstraction based on `Operation`. For a higher361/// This is a low-level abstraction based on `Operation`. For a higher
362/// level API that operates on `Future`, see `Select`.362/// level API that operates on `Future`, see `Select` and `Group`.
363pub const Batch = struct {363pub const Batch = struct {
364 storage: []Operation.Storage,364 storage: []Operation.Storage,
365 unused: Operation.List,365 unused: Operation.List,
...@@ -422,6 +422,11 @@ pub const Batch = struct {...@@ -422,6 +422,11 @@ pub const Batch = struct {
422 b.submissions.tail = .fromIndex(index);422 b.submissions.tail = .fromIndex(index);
423 }423 }
424424
425 /// After calling `awaitAsync`, `awaitConcurrent`, or `cancel`, this
426 /// function iterates over the completed operations.
427 ///
428 /// Each completion returned from this function dequeues from the `Batch`.
429 /// It is not required to dequeue all completions before awaiting again.
425 pub fn next(b: *Batch) ?struct { index: u32, result: Operation.Result } {430 pub fn next(b: *Batch) ?struct { index: u32, result: Operation.Result } {
426 const index = b.completions.head;431 const index = b.completions.head;
427 if (index == .none) return null;432 if (index == .none) return null;
...@@ -441,16 +446,37 @@ pub const Batch = struct {...@@ -441,16 +446,37 @@ pub const Batch = struct {
441 return .{ .index = index.toIndex(), .result = completion.result };446 return .{ .index = index.toIndex(), .result = completion.result };
442 }447 }
443448
444 pub const AwaitAsyncError = Cancelable;449 /// Waits for at least one of the submitted operations to complete. After
445 pub fn awaitAsync(b: *Batch, io: Io) AwaitAsyncError!void {450 /// this function returns the completed operations can be iterated with
451 /// `next`.
452 ///
453 /// This function provides opportunity for the implementation to introduce
454 /// concurrency into the batched operations, but unlike `awaitConcurrent`,
455 /// does not require it, and therefore cannot fail with
456 /// `error.ConcurrencyUnavailable`.
457 pub fn awaitAsync(b: *Batch, io: Io) Cancelable!void {
446 return io.vtable.batchAwaitAsync(io.userdata, b);458 return io.vtable.batchAwaitAsync(io.userdata, b);
447 }459 }
448460
449 pub const AwaitConcurrentError = ConcurrentError || Cancelable || Timeout.Error;461 pub const AwaitConcurrentError = ConcurrentError || Cancelable || Timeout.Error;
462
463 /// Waits for at least one of the submitted operations to complete. After
464 /// this function returns the completed operations can be iterated with
465 /// `next`.
466 ///
467 /// Unlike `awaitAsync`, this function requires the implementation to
468 /// perform the operations concurrently and therefore can fail with
469 /// `error.ConcurrencyUnavailable`.
450 pub fn awaitConcurrent(b: *Batch, io: Io, timeout: Timeout) AwaitConcurrentError!void {470 pub fn awaitConcurrent(b: *Batch, io: Io, timeout: Timeout) AwaitConcurrentError!void {
451 return io.vtable.batchAwaitConcurrent(io.userdata, b, timeout);471 return io.vtable.batchAwaitConcurrent(io.userdata, b, timeout);
452 }472 }
453473
474 /// Requests all pending operations to be interrupted, then waits for all
475 /// pending operations to complete. After this returns, the `Batch` is in a
476 /// well-defined state, ready to be iterated with `next`. Successfully
477 /// canceled operations will be absent from the iteration. Some operations
478 /// may have successfully completed regardless of the cancel request and
479 /// will appear in the iteration.
454 pub fn cancel(b: *Batch, io: Io) void {480 pub fn cancel(b: *Batch, io: Io) void {
455 return io.vtable.batchCancel(io.userdata, b);481 return io.vtable.batchCancel(io.userdata, b);
456 }482 }
lib/std/Io/Threaded.zig+1-1
...@@ -2495,7 +2495,7 @@ fn operate(userdata: ?*anyopaque, operation: Io.Operation) Io.Cancelable!Io.Oper...@@ -2495,7 +2495,7 @@ fn operate(userdata: ?*anyopaque, operation: Io.Operation) Io.Cancelable!Io.Oper
2495 }2495 }
2496}2496}
24972497
2498fn batchAwaitAsync(userdata: ?*anyopaque, b: *Io.Batch) Io.Batch.AwaitAsyncError!void {2498fn batchAwaitAsync(userdata: ?*anyopaque, b: *Io.Batch) Io.Cancelable!void {
2499 const t: *Threaded = @ptrCast(@alignCast(userdata));2499 const t: *Threaded = @ptrCast(@alignCast(userdata));
2500 if (is_windows) {2500 if (is_windows) {
2501 batchAwaitWindows(b, false) catch |err| switch (err) {2501 batchAwaitWindows(b, false) catch |err| switch (err) {