mirror of
https://codeberg.org/ziglings/exercises.git
synced 2026-06-10 17:09:59 +00:00
new async exercise
This commit is contained in:
15
build.zig
15
build.zig
@@ -1161,13 +1161,20 @@ const exercises = [_]Exercise{
|
|||||||
},
|
},
|
||||||
.{
|
.{
|
||||||
.main_file = "092_async9.zig",
|
.main_file = "092_async9.zig",
|
||||||
.output = "",
|
.output =
|
||||||
.skip = true,
|
\\Main thread continues...
|
||||||
|
\\Computing on a separate thread!
|
||||||
|
\\Main thread done waiting.
|
||||||
|
\\Result: 123
|
||||||
|
, // pay attention to the comma
|
||||||
},
|
},
|
||||||
.{
|
.{
|
||||||
.main_file = "093_async10.zig",
|
.main_file = "093_async10.zig",
|
||||||
.output = "",
|
.output =
|
||||||
.skip = true,
|
\\Starting critical section...
|
||||||
|
\\Critical section completed safely.
|
||||||
|
\\Task result: All data saved.
|
||||||
|
, // pay attention to the comma
|
||||||
},
|
},
|
||||||
.{
|
.{
|
||||||
.main_file = "094_async_quiz.zig",
|
.main_file = "094_async_quiz.zig",
|
||||||
|
|||||||
67
exercises/093_async10.zig
Normal file
67
exercises/093_async10.zig
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
//
|
||||||
|
// In exercise 088, we learned that cancellation happens at
|
||||||
|
// "cancellation points" — any Io function that can return
|
||||||
|
// error.Canceled.
|
||||||
|
//
|
||||||
|
// But sometimes a task has a critical section that MUST NOT
|
||||||
|
// be interrupted — for example, writing a consistent state
|
||||||
|
// to disk, or completing a transaction.
|
||||||
|
//
|
||||||
|
// Io provides CancelProtection for this:
|
||||||
|
//
|
||||||
|
// const old = io.swapCancelProtection(.blocked);
|
||||||
|
// defer _ = io.swapCancelProtection(old);
|
||||||
|
//
|
||||||
|
// // In this block, NO Io function will return error.Canceled.
|
||||||
|
// // The cancel request is held until protection is restored.
|
||||||
|
//
|
||||||
|
// There are two states:
|
||||||
|
// .unblocked — normal: cancellation points can fire (default)
|
||||||
|
// .blocked — protected: error.Canceled is never returned
|
||||||
|
//
|
||||||
|
// There's also io.checkCancel() — a pure cancellation point
|
||||||
|
// that does nothing except return error.Canceled if a cancel
|
||||||
|
// request is pending. Useful in long CPU-bound loops.
|
||||||
|
//
|
||||||
|
// And io.recancel() — re-arms a consumed cancel request so
|
||||||
|
// the NEXT cancellation point will fire again.
|
||||||
|
//
|
||||||
|
// Fix this program so the critical section completes even
|
||||||
|
// when the task is canceled.
|
||||||
|
//
|
||||||
|
const std = @import("std");
|
||||||
|
const print = std.debug.print;
|
||||||
|
|
||||||
|
pub fn main(init: std.process.Init) !void {
|
||||||
|
const io = init.io;
|
||||||
|
|
||||||
|
var future = io.async(importantTask, .{io});
|
||||||
|
|
||||||
|
// Give the task time to start and enter its critical section.
|
||||||
|
io.sleep(std.Io.Duration.fromMilliseconds(300), .awake) catch {};
|
||||||
|
|
||||||
|
// Cancel while the task is in its protected section.
|
||||||
|
const result = future.cancel(io);
|
||||||
|
print("Task result: {s}\n", .{result});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn importantTask(io: std.Io) []const u8 {
|
||||||
|
print("Starting critical section...\n", .{});
|
||||||
|
|
||||||
|
// Protect this section from cancellation.
|
||||||
|
// What method swaps the cancel protection state?
|
||||||
|
const old = io.???(. blocked);
|
||||||
|
defer _ = io.???(old);
|
||||||
|
|
||||||
|
// This sleep will NOT return error.Canceled even though
|
||||||
|
// we get canceled during it — protection is active!
|
||||||
|
io.sleep(std.Io.Duration.fromMilliseconds(600), .awake) catch |err| switch (err) {
|
||||||
|
error.Canceled => {
|
||||||
|
// This should never happen while protected!
|
||||||
|
return "ERROR: canceled during critical section!";
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
print("Critical section completed safely.\n", .{});
|
||||||
|
return "All data saved.";
|
||||||
|
}
|
||||||
13
patches/patches/093_async10.patch
Normal file
13
patches/patches/093_async10.patch
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
--- exercises/093_async10.zig 2026-04-03 14:25:16.600025924 +0200
|
||||||
|
+++ answers/093_async10.zig 2026-04-03 14:24:56.192615893 +0200
|
||||||
|
@@ -50,8 +50,8 @@
|
||||||
|
|
||||||
|
// Protect this section from cancellation.
|
||||||
|
// What method swaps the cancel protection state?
|
||||||
|
- const old = io.???(. blocked);
|
||||||
|
- defer _ = io.???(old);
|
||||||
|
+ const old = io.swapCancelProtection(.blocked);
|
||||||
|
+ defer _ = io.swapCancelProtection(old);
|
||||||
|
|
||||||
|
// This sleep will NOT return error.Canceled even though
|
||||||
|
// we get canceled during it — protection is active!
|
||||||
Reference in New Issue
Block a user