feature. See also
. The project being documented here (as the example) is the Zig library itself.
Uring.CancelRegion
const CancelRegion = struct
File
Code
const CancelRegion = struct {
fiber: *Fiber,
status: Fiber.CancelStatus,
fn init() CancelRegion {
const fiber = Thread.current().currentFiber();
return .{
.fiber = fiber,
.status = .{
.requested = fiber.cancel_protection.check() == .unblocked,
.awaiting = .nothing,
},
};
}
fn initBlocked() CancelRegion {
return .{
.fiber = Thread.current().currentFiber(),
.status = .{ .requested = false, .awaiting = .nothing },
};
}
fn deinit(cancel_region: *CancelRegion) void {
if (cancel_region.status.requested) {
@branchHint(.likely);
_ = cancel_region.fiber.cancel_status.changeAwaiting(
cancel_region.status.awaiting,
.nothing,
);
}
cancel_region.* = undefined;
}
fn await(cancel_region: *CancelRegion, awaiting: Fiber.CancelStatus.Awaiting) Io.Cancelable!void {
if (!cancel_region.status.requested) {
@branchHint(.unlikely);
return;
}
const status: Fiber.CancelStatus = .{ .requested = true, .awaiting = awaiting };
if (cancel_region.fiber.cancel_status.changeAwaiting(
cancel_region.status.awaiting,
status.awaiting,
)) {
@branchHint(.unlikely);
cancel_region.fiber.cancel_protection.acknowledge();
cancel_region.status = .unrequested;
return error.Canceled;
}
cancel_region.status = status;
}
fn awaitIoUring(cancel_region: *CancelRegion) Io.Cancelable!*Thread {
const thread: *Thread = .current();
try cancel_region.await(.fromIoUringFd(thread.io_uring.fd));
return thread;
}
fn completion(cancel_region: *const CancelRegion) Completion {
return cancel_region.fiber.resultPointer(Completion).*;
}
fn errno(cancel_region: *const CancelRegion) linux.E {
return cancel_region.completion().errno();
}
const Sync = struct {
cancel_region: CancelRegion,
fn init(ev: *Evented) Io.Cancelable!Sync {
if (ev.sync_limit) |*sync_limit| try sync_limit.wait(ev.io());
return .{ .cancel_region = .init() };
}
fn initBlocked(ev: *Evented) Sync {
if (ev.sync_limit) |*sync_limit| sync_limit.waitUncancelable(ev.io());
return .{ .cancel_region = .initBlocked() };
}
fn deinit(sync: *Sync, ev: *Evented) void {
sync.cancel_region.deinit();
if (ev.sync_limit) |*sync_limit| sync_limit.post(ev.io());
}
const Maybe = union(enum) {
cancel_region: CancelRegion,
sync: Sync,
fn deinit(maybe: *Maybe, ev: *Evented) void {
switch (maybe.*) {
.cancel_region => |*cancel_region| cancel_region.deinit(),
.sync => |*sync| sync.deinit(ev),
}
}
fn enterSync(maybe: *Maybe, ev: *Evented) Io.Cancelable!*Sync {
switch (maybe.*) {
.cancel_region => |cancel_region| {
if (ev.sync_limit) |*sync_limit| try sync_limit.wait(ev.io());
maybe.* = .{ .sync = .{ .cancel_region = cancel_region } };
},
.sync => {},
}
return &maybe.sync;
}
fn leaveSync(maybe: *Maybe, ev: *Evented) void {
switch (maybe.*) {
.cancel_region => {},
.sync => |sync| {
if (ev.sync_limit) |*sync_limit| sync_limit.post(ev.io());
maybe.* = .{ .cancel_region = sync.cancel_region };
},
}
}
fn cancelRegion(maybe: *Maybe) *CancelRegion {
return switch (maybe.*) {
.cancel_region => |*cancel_region| cancel_region,
.sync => |*sync| &sync.cancel_region,
};
}
};
};
}