authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-17 20:53:39-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-20 10:38:39-07:00
log363d7deb8a5dad9f66be84d3bb62a7b129c2bfad
tree5adee115c9b0c7ce99811b6b6e79dd53afffa46a
parent33b10abaf607d794c9fc379248c8b97c6195c053

std.Io: fix error handling and asyncParallel docs


3 files changed, 20 insertions(+), 20 deletions(-)

lib/std/Io.zig+10-10
...@@ -946,7 +946,7 @@ pub const VTable = struct {...@@ -946,7 +946,7 @@ pub const VTable = struct {
946 context: []const u8,946 context: []const u8,
947 context_alignment: std.mem.Alignment,947 context_alignment: std.mem.Alignment,
948 start: *const fn (context: *const anyopaque, result: *anyopaque) void,948 start: *const fn (context: *const anyopaque, result: *anyopaque) void,
949 ) ?*AnyFuture,949 ) error{OutOfMemory}!*AnyFuture,
950 /// Returning `null` indicates resource allocation failed.950 /// Returning `null` indicates resource allocation failed.
951 ///951 ///
952 /// Thread-safe.952 /// Thread-safe.
...@@ -959,7 +959,7 @@ pub const VTable = struct {...@@ -959,7 +959,7 @@ pub const VTable = struct {
959 context: []const u8,959 context: []const u8,
960 context_alignment: std.mem.Alignment,960 context_alignment: std.mem.Alignment,
961 start: *const fn (context: *const anyopaque, result: *anyopaque) void,961 start: *const fn (context: *const anyopaque, result: *anyopaque) void,
962 ) ?*AnyFuture,962 ) error{OutOfMemory}!*AnyFuture,
963 /// Executes `start` asynchronously in a manner such that it cleans itself963 /// Executes `start` asynchronously in a manner such that it cleans itself
964 /// up. This mode does not support results, await, or cancel.964 /// up. This mode does not support results, await, or cancel.
965 ///965 ///
...@@ -1573,7 +1573,7 @@ pub fn asyncConcurrent(...@@ -1573,7 +1573,7 @@ pub fn asyncConcurrent(
1573 }1573 }
1574 };1574 };
1575 var future: Future(Result) = undefined;1575 var future: Future(Result) = undefined;
1576 future.any_future = io.vtable.asyncConcurrent(1576 future.any_future = try io.vtable.asyncConcurrent(
1577 io.userdata,1577 io.userdata,
1578 @sizeOf(Result),1578 @sizeOf(Result),
1579 .of(Result),1579 .of(Result),
...@@ -1584,14 +1584,14 @@ pub fn asyncConcurrent(...@@ -1584,14 +1584,14 @@ pub fn asyncConcurrent(
1584 return future;1584 return future;
1585}1585}
15861586
1587/// Calls `function` with `args`, such that the return value of the function is1587/// Simultaneously calls `function` with `args` while passing control flow back
1588/// not guaranteed to be available until `await` is called, while simultaneously1588/// to the caller. The return value of the function is not guaranteed to be
1589/// passing control flow back to the caller.1589/// available until `await` is called.
1590///1590///
1591/// This has the strongest guarantees of all async family functions, placing1591/// This has the strongest guarantees of all async family functions, placing
1592/// the most restrictions on what kind of `Io` implementations are supported.1592/// the most restrictions on what kind of `Io` implementations are supported.
1593/// By calling `asyncConcurrent` instead, one allows, for example,1593/// By calling `asyncConcurrent` instead, one allows, for example, stackful
1594/// stackful single-threaded non-blocking I/O.1594/// single-threaded non-blocking I/O.
1595///1595///
1596/// See also:1596/// See also:
1597/// * `asyncConcurrent`1597/// * `asyncConcurrent`
...@@ -1611,9 +1611,9 @@ pub fn asyncParallel(...@@ -1611,9 +1611,9 @@ pub fn asyncParallel(
1611 }1611 }
1612 };1612 };
1613 var future: Future(Result) = undefined;1613 var future: Future(Result) = undefined;
1614 future.any_future = io.vtable.asyncConcurrent(1614 future.any_future = try io.vtable.asyncParallel(
1615 io.userdata,1615 io.userdata,
1616 @ptrCast((&future.result)[0..1]),1616 @sizeOf(Result),
1617 .of(Result),1617 .of(Result),
1618 @ptrCast((&args)[0..1]),1618 @ptrCast((&args)[0..1]),
1619 .of(Args),1619 .of(Args),
lib/std/Io/EventLoop.zig+4-4
...@@ -879,7 +879,7 @@ fn async(...@@ -879,7 +879,7 @@ fn async(
879 context_alignment: Alignment,879 context_alignment: Alignment,
880 start: *const fn (context: *const anyopaque, result: *anyopaque) void,880 start: *const fn (context: *const anyopaque, result: *anyopaque) void,
881) ?*std.Io.AnyFuture {881) ?*std.Io.AnyFuture {
882 return asyncConcurrent(userdata, result.len, result_alignment, context, context_alignment, start) orelse {882 return asyncConcurrent(userdata, result.len, result_alignment, context, context_alignment, start) catch {
883 start(context.ptr, result.ptr);883 start(context.ptr, result.ptr);
884 return null;884 return null;
885 };885 };
...@@ -892,14 +892,14 @@ fn asyncConcurrent(...@@ -892,14 +892,14 @@ fn asyncConcurrent(
892 context: []const u8,892 context: []const u8,
893 context_alignment: Alignment,893 context_alignment: Alignment,
894 start: *const fn (context: *const anyopaque, result: *anyopaque) void,894 start: *const fn (context: *const anyopaque, result: *anyopaque) void,
895) ?*std.Io.AnyFuture {895) error{OutOfMemory}!*std.Io.AnyFuture {
896 assert(result_alignment.compare(.lte, Fiber.max_result_align)); // TODO896 assert(result_alignment.compare(.lte, Fiber.max_result_align)); // TODO
897 assert(context_alignment.compare(.lte, Fiber.max_context_align)); // TODO897 assert(context_alignment.compare(.lte, Fiber.max_context_align)); // TODO
898 assert(result_len <= Fiber.max_result_size); // TODO898 assert(result_len <= Fiber.max_result_size); // TODO
899 assert(context.len <= Fiber.max_context_size); // TODO899 assert(context.len <= Fiber.max_context_size); // TODO
900900
901 const event_loop: *EventLoop = @alignCast(@ptrCast(userdata));901 const event_loop: *EventLoop = @alignCast(@ptrCast(userdata));
902 const fiber = Fiber.allocate(event_loop) catch return null;902 const fiber = try Fiber.allocate(event_loop);
903 std.log.debug("allocated {*}", .{fiber});903 std.log.debug("allocated {*}", .{fiber});
904904
905 const closure: *AsyncClosure = .fromFiber(fiber);905 const closure: *AsyncClosure = .fromFiber(fiber);
...@@ -945,7 +945,7 @@ fn asyncParallel(...@@ -945,7 +945,7 @@ fn asyncParallel(
945 context: []const u8,945 context: []const u8,
946 context_alignment: Alignment,946 context_alignment: Alignment,
947 start: *const fn (context: *const anyopaque, result: *anyopaque) void,947 start: *const fn (context: *const anyopaque, result: *anyopaque) void,
948) ?*std.Io.AnyFuture {948) error{OutOfMemory}!*std.Io.AnyFuture {
949 _ = userdata;949 _ = userdata;
950 _ = result_len;950 _ = result_len;
951 _ = result_alignment;951 _ = result_alignment;
lib/std/Io/ThreadPool.zig+6-6
...@@ -220,7 +220,7 @@ fn async(...@@ -220,7 +220,7 @@ fn async(
220 }220 }
221 const pool: *Pool = @alignCast(@ptrCast(userdata));221 const pool: *Pool = @alignCast(@ptrCast(userdata));
222 const cpu_count = pool.cpu_count catch {222 const cpu_count = pool.cpu_count catch {
223 return asyncParallel(userdata, result.len, result_alignment, context, context_alignment, start) orelse {223 return asyncParallel(userdata, result.len, result_alignment, context, context_alignment, start) catch {
224 start(context.ptr, result.ptr);224 start(context.ptr, result.ptr);
225 return null;225 return null;
226 };226 };
...@@ -291,8 +291,8 @@ fn asyncParallel(...@@ -291,8 +291,8 @@ fn asyncParallel(
291 context: []const u8,291 context: []const u8,
292 context_alignment: std.mem.Alignment,292 context_alignment: std.mem.Alignment,
293 start: *const fn (context: *const anyopaque, result: *anyopaque) void,293 start: *const fn (context: *const anyopaque, result: *anyopaque) void,
294) ?*Io.AnyFuture {294) error{OutOfMemory}!*Io.AnyFuture {
295 if (builtin.single_threaded) return null;295 if (builtin.single_threaded) unreachable;
296296
297 const pool: *Pool = @alignCast(@ptrCast(userdata));297 const pool: *Pool = @alignCast(@ptrCast(userdata));
298 const cpu_count = pool.cpu_count catch 1;298 const cpu_count = pool.cpu_count catch 1;
...@@ -300,7 +300,7 @@ fn asyncParallel(...@@ -300,7 +300,7 @@ fn asyncParallel(
300 const context_offset = context_alignment.forward(@sizeOf(AsyncClosure));300 const context_offset = context_alignment.forward(@sizeOf(AsyncClosure));
301 const result_offset = result_alignment.forward(context_offset + context.len);301 const result_offset = result_alignment.forward(context_offset + context.len);
302 const n = result_offset + result_len;302 const n = result_offset + result_len;
303 const closure: *AsyncClosure = @alignCast(@ptrCast(gpa.alignedAlloc(u8, .of(AsyncClosure), n) catch return null));303 const closure: *AsyncClosure = @alignCast(@ptrCast(try gpa.alignedAlloc(u8, .of(AsyncClosure), n)));
304304
305 closure.* = .{305 closure.* = .{
306 .func = start,306 .func = start,
...@@ -324,7 +324,7 @@ fn asyncParallel(...@@ -324,7 +324,7 @@ fn asyncParallel(
324 pool.threads.ensureTotalCapacity(gpa, thread_capacity) catch {324 pool.threads.ensureTotalCapacity(gpa, thread_capacity) catch {
325 pool.mutex.unlock();325 pool.mutex.unlock();
326 closure.free(gpa, result_len);326 closure.free(gpa, result_len);
327 return null;327 return error.OutOfMemory;
328 };328 };
329329
330 pool.run_queue.prepend(&closure.runnable.node);330 pool.run_queue.prepend(&closure.runnable.node);
...@@ -334,7 +334,7 @@ fn asyncParallel(...@@ -334,7 +334,7 @@ fn asyncParallel(
334 assert(pool.run_queue.popFirst() == &closure.runnable.node);334 assert(pool.run_queue.popFirst() == &closure.runnable.node);
335 pool.mutex.unlock();335 pool.mutex.unlock();
336 closure.free(gpa, result_len);336 closure.free(gpa, result_len);
337 return null;337 return error.OutOfMemory;
338 };338 };
339 pool.threads.appendAssumeCapacity(thread);339 pool.threads.appendAssumeCapacity(thread);
340 }340 }