feature. See also
. The project being documented here (as the example) is the Zig library itself.
Threaded.async
fn async(
userdata: ?*anyopaque,
result: []u8,
result_alignment: Alignment,
context: []const u8,
context_alignment: Alignment,
start: *const fn (context: *const anyopaque, result: *anyopaque) void,
) ?*Io.AnyFuture
File
Code
fn async(
userdata: ?*anyopaque,
result: []u8,
result_alignment: Alignment,
context: []const u8,
context_alignment: Alignment,
start: *const fn (context: *const anyopaque, result: *anyopaque) void,
) ?*Io.AnyFuture {
const t: *Threaded = @ptrCast(@alignCast(userdata));
if (builtin.single_threaded) {
start(context.ptr, result.ptr);
return null;
}
const gpa = t.allocator;
const future = Future.create(gpa, result.len, result_alignment, context, context_alignment, start) catch |err| switch (err) {
error.OutOfMemory => {
start(context.ptr, result.ptr);
return null;
},
};
mutexLock(&t.mutex);
const busy_count = t.busy_count;
if (busy_count >= @backingInt(t.async_limit)) {
mutexUnlock(&t.mutex);
future.destroy(gpa);
start(context.ptr, result.ptr);
return null;
}
t.busy_count = busy_count + 1;
const pool_size = t.wait_group.value();
if (pool_size - busy_count == 0) {
t.wait_group.start();
const thread = std.Thread.spawn(.{ .stack_size = t.stack_size }, worker, .{t}) catch {
t.wait_group.finish();
t.busy_count = busy_count;
mutexUnlock(&t.mutex);
future.destroy(gpa);
start(context.ptr, result.ptr);
return null;
};
thread.detach();
}
t.run_queue.prepend(&future.runnable.node);
mutexUnlock(&t.mutex);
condSignal(&t.cond);
return @ptrCast(future);
}