feature. See also
. The project being documented here (as the example) is the Zig library itself.
Threaded.AlertableSyscall
const AlertableSyscall = struct
File
Code
const AlertableSyscall = struct {
thread: ?*Thread,
comptime {
assert(is_windows);
}
fn start() Io.Cancelable!AlertableSyscall {
const thread = Thread.current orelse return .{ .thread = null };
switch (thread.cancel_protection) {
.blocked => return .{ .thread = null },
.unblocked => {},
}
const old_status = thread.status.fetchOr(.{
.cancelation = @fromBackingInt(@intCast(0b010)),
.awaitable = .null,
}, .monotonic);
switch (old_status.cancelation) {
.parked => unreachable,
.blocked => unreachable,
.blocked_alertable => unreachable,
.blocked_canceling => unreachable,
.blocked_alertable_canceling => unreachable,
.none => return .{ .thread = thread },
.canceling => {
thread.status.store(.{ .cancelation = .canceled, .awaitable = old_status.awaitable }, .monotonic);
return error.Canceled;
},
.canceled => return .{ .thread = null },
}
}
fn checkCancel(s: AlertableSyscall) Io.Cancelable!void {
comptime assert(is_windows);
const thread = s.thread orelse return;
const old_status = thread.status.fetchOr(.{
.cancelation = @fromBackingInt(@intCast(0b010)),
.awaitable = .null,
}, .monotonic);
switch (old_status.cancelation) {
.none => unreachable,
.parked => unreachable,
.blocked => unreachable,
.blocked_canceling => unreachable,
.canceling => unreachable,
.canceled => unreachable,
.blocked_alertable => {},
.blocked_alertable_canceling => {
thread.status.store(.{ .cancelation = .canceled, .awaitable = old_status.awaitable }, .monotonic);
return error.Canceled;
},
}
}
fn finish(s: AlertableSyscall) void {
comptime assert(is_windows);
const thread = s.thread orelse return;
switch (thread.status.fetchXor(.{
.cancelation = @fromBackingInt(@intCast(0b010)),
.awaitable = .null,
}, .monotonic).cancelation) {
.none => unreachable,
.parked => unreachable,
.blocked => unreachable,
.blocked_canceling => unreachable,
.canceling => unreachable,
.canceled => unreachable,
.blocked_alertable => {},
.blocked_alertable_canceling => {},
}
}
fn fail(s: AlertableSyscall, err: anytype) @TypeOf(err) {
s.finish();
return err;
}
fn ntstatusBug(s: AlertableSyscall, status: windows.NTSTATUS) Io.UnexpectedError {
@branchHint(.cold);
s.finish();
return windows.statusBug(status);
}
fn unexpectedNtstatus(s: AlertableSyscall, status: windows.NTSTATUS) Io.UnexpectedError {
@branchHint(.cold);
s.finish();
return windows.unexpectedStatus(status);
}
}