fn requestCancel(fiber: *Fiber, ev: *Evented) void {
const cancel_status = @atomicRmw(
Fiber.CancelStatus,
&fiber.cancel_status,
.Or,
.{ .requested = true, .awaiting = @fromBackingInt(@intCast(0)) },
.acquire,
);
assert(!cancel_status.requested);
switch (cancel_status.awaiting) {
.nothing => {},
.group => {
// The awaiter received a cancelation request while awaiting a group,
// so propagate the cancelation to the group.
if (fiber.status.awaiting_group.cancel(ev, null)) {
fiber.status = .{ .queue_next = null };
_ = ev.schedule(.current(), .{ .head = fiber, .tail = fiber });
}
},
_ => |awaiting| {
const awaiting_io_uring_fd = awaiting.toIoUringFd();
const thread: *Thread = .current();
thread.enqueue().* = if (thread.io_uring.fd == awaiting_io_uring_fd) .{
.opcode = .ASYNC_CANCEL,
.flags = linux.IOSQE_CQE_SKIP_SUCCESS,
.ioprio = 0,
.fd = 0,
.off = 0,
.addr = @intFromPtr(fiber),
.len = 0,
.rw_flags = 0,
.user_data = @backingInt(Completion.Userdata.wakeup),
.buf_index = 0,
.personality = 0,
.splice_fd_in = 0,
.addr3 = 0,
.resv = 0,
} else .{
.opcode = .MSG_RING,
.flags = linux.IOSQE_CQE_SKIP_SUCCESS,
.ioprio = 0,
.fd = awaiting_io_uring_fd,
.off = @intFromPtr(fiber) | 0b01,
.addr = @backingInt(linux.IORING_MSG_RING_COMMAND.DATA),
.len = 0,
.rw_flags = 0,
.user_data = @backingInt(Completion.Userdata.cleanup),
.buf_index = 0,
.personality = 0,
.splice_fd_in = 0,
.addr3 = 0,
.resv = 0,
};
},
}
}