summaryrefslogtreecommitdiff
path: root/exercises/092_async8.zig
diff options
context:
space:
mode:
authorChris Boesch <chrboesch@noreply.codeberg.org>2026-04-03 19:32:53 +0200
committerChris Boesch <chrboesch@noreply.codeberg.org>2026-04-03 19:32:53 +0200
commit5307b2a338a92130bc498fb1dc7d21a9fd1b0db4 (patch)
tree51279ca4fbd7bd90294dd563640c12a8c25c79c6 /exercises/092_async8.zig
parent3056a2b5442f2f1ec58db3f3493109064ad2a2a5 (diff)
parentf6a6798c8b6b813bd2ceee81db276e05327a76e0 (diff)
Merge pull request 'revival of the async-io functions' (#383) from asyncIo into main
Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/383
Diffstat (limited to 'exercises/092_async8.zig')
-rw-r--r--exercises/092_async8.zig62
1 files changed, 62 insertions, 0 deletions
diff --git a/exercises/092_async8.zig b/exercises/092_async8.zig
new file mode 100644
index 0000000..10921c3
--- /dev/null
+++ b/exercises/092_async8.zig
@@ -0,0 +1,62 @@
+//
+// Tasks often need to communicate! Io provides Queue for this —
+// a bounded, thread-safe channel for passing data between tasks:
+//
+// var backing: [16]u32 = undefined;
+// var queue: std.Io.Queue(u32) = .init(&backing);
+//
+// // Producer task:
+// try queue.putOne(io, value); // blocks if queue is full
+//
+// // Consumer task:
+// const val = try queue.getOne(io); // blocks if queue is empty
+//
+// When the producer is done, it calls queue.close(io) to signal
+// that no more data is coming. After that, getOne() will return
+// error.Closed once the queue is drained.
+//
+// This is the classic producer/consumer pattern — one task
+// generates work, another processes it, and the queue handles
+// all the synchronization automatically.
+//
+// Fix this program: the producer sends numbers 1..10, the
+// consumer sums them up. The expected sum is 55.
+//
+const std = @import("std");
+const print = std.debug.print;
+
+pub fn main(init: std.process.Init) !void {
+ const io = init.io;
+
+ var backing: [4]u32 = undefined;
+ var queue: std.Io.Queue(u32) = .init(&backing);
+
+ var group: std.Io.Group = .init;
+
+ group.async(io, producer, .{ io, &queue });
+ group.async(io, consumer, .{ io, &queue });
+
+ try group.await(io);
+}
+
+fn producer(io: std.Io, queue: *std.Io.Queue(u32)) void {
+ // Send numbers 1 through 10 into the queue.
+ for (1..11) |i| {
+ // What Queue method sends a single element, blocking if full?
+ queue.???(io, @intCast(i)) catch return;
+ }
+ // Signal that we're done sending.
+ queue.close(io);
+}
+
+fn consumer(io: std.Io, queue: *std.Io.Queue(u32)) void {
+ var sum: u32 = 0;
+ while (true) {
+ const value = queue.getOne(io) catch |err| switch (err) {
+ error.Closed => break,
+ error.Canceled => return,
+ };
+ sum += value;
+ }
+ print("Sum of 1..10 = {}\n", .{sum});
+}