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-10-02 16:30:59-07:00
log25b2954c0c86145948834b31b8edb88aeb4d40a0
treee0bf949171ec7b5f20323e2aca93c679f47669c1
parent9fd1ecb348f25dd56f09a6bd10022554a87bb6da

std.Io: fix error handling and asyncParallel docs


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

lib/std/Io.zig+10-10
...@@ -593,7 +593,7 @@ pub const VTable = struct {...@@ -593,7 +593,7 @@ pub const VTable = struct {
593 context: []const u8,593 context: []const u8,
594 context_alignment: std.mem.Alignment,594 context_alignment: std.mem.Alignment,
595 start: *const fn (context: *const anyopaque, result: *anyopaque) void,595 start: *const fn (context: *const anyopaque, result: *anyopaque) void,
596 ) ?*AnyFuture,596 ) error{OutOfMemory}!*AnyFuture,
597 /// Returning `null` indicates resource allocation failed.597 /// Returning `null` indicates resource allocation failed.
598 ///598 ///
599 /// Thread-safe.599 /// Thread-safe.
...@@ -606,7 +606,7 @@ pub const VTable = struct {...@@ -606,7 +606,7 @@ pub const VTable = struct {
606 context: []const u8,606 context: []const u8,
607 context_alignment: std.mem.Alignment,607 context_alignment: std.mem.Alignment,
608 start: *const fn (context: *const anyopaque, result: *anyopaque) void,608 start: *const fn (context: *const anyopaque, result: *anyopaque) void,
609 ) ?*AnyFuture,609 ) error{OutOfMemory}!*AnyFuture,
610 /// Executes `start` asynchronously in a manner such that it cleans itself610 /// Executes `start` asynchronously in a manner such that it cleans itself
611 /// up. This mode does not support results, await, or cancel.611 /// up. This mode does not support results, await, or cancel.
612 ///612 ///
...@@ -1220,7 +1220,7 @@ pub fn asyncConcurrent(...@@ -1220,7 +1220,7 @@ pub fn asyncConcurrent(
1220 }1220 }
1221 };1221 };
1222 var future: Future(Result) = undefined;1222 var future: Future(Result) = undefined;
1223 future.any_future = io.vtable.asyncConcurrent(1223 future.any_future = try io.vtable.asyncConcurrent(
1224 io.userdata,1224 io.userdata,
1225 @sizeOf(Result),1225 @sizeOf(Result),
1226 .of(Result),1226 .of(Result),
...@@ -1231,14 +1231,14 @@ pub fn asyncConcurrent(...@@ -1231,14 +1231,14 @@ pub fn asyncConcurrent(
1231 return future;1231 return future;
1232}1232}
12331233
1234/// Calls `function` with `args`, such that the return value of the function is1234/// Simultaneously calls `function` with `args` while passing control flow back
1235/// not guaranteed to be available until `await` is called, while simultaneously1235/// to the caller. The return value of the function is not guaranteed to be
1236/// passing control flow back to the caller.1236/// available until `await` is called.
1237///1237///
1238/// This has the strongest guarantees of all async family functions, placing1238/// This has the strongest guarantees of all async family functions, placing
1239/// the most restrictions on what kind of `Io` implementations are supported.1239/// the most restrictions on what kind of `Io` implementations are supported.
1240/// By calling `asyncConcurrent` instead, one allows, for example,1240/// By calling `asyncConcurrent` instead, one allows, for example, stackful
1241/// stackful single-threaded non-blocking I/O.1241/// single-threaded non-blocking I/O.
1242///1242///
1243/// See also:1243/// See also:
1244/// * `asyncConcurrent`1244/// * `asyncConcurrent`
...@@ -1258,9 +1258,9 @@ pub fn asyncParallel(...@@ -1258,9 +1258,9 @@ pub fn asyncParallel(
1258 }1258 }
1259 };1259 };
1260 var future: Future(Result) = undefined;1260 var future: Future(Result) = undefined;
1261 future.any_future = io.vtable.asyncConcurrent(1261 future.any_future = try io.vtable.asyncParallel(
1262 io.userdata,1262 io.userdata,
1263 @ptrCast((&future.result)[0..1]),1263 @sizeOf(Result),
1264 .of(Result),1264 .of(Result),
1265 @ptrCast((&args)[0..1]),1265 @ptrCast((&args)[0..1]),
1266 .of(Args),1266 .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 }