Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

Cancelable

Dispatch.Cancelable
const Cancelable = struct

File

lib/std/Io/Dispatch.zig:716

Code

const Cancelable = struct {
    required_align: void align(2) = {},
    queue: c.dispatch.queue_t,
    cancel: c.dispatch.function_t,

    const fn_ptr_align = std.meta.alignment(c.dispatch.function_t);
    const is_blocked: c.dispatch.function_t = @ptrFromInt(fn_ptr_align * 1);
    const is_requested: c.dispatch.function_t = @ptrFromInt(fn_ptr_align * 2);

    const blocked: Cancelable = .{ .queue = undefined, .cancel = is_blocked };

    const RequestedError = error{CancelRequested};

    fn enter(cancelable: *Cancelable, fiber: *Fiber) RequestedError!void {
        const function = cancelable.cancel;
        assert(function != is_requested);
        if (function == is_blocked) {
            @branchHint(.unlikely);
            return;
        }
        if (@cmpxchgStrong(
            Fiber.CancelStatus,
            &fiber.cancel_status,
            .{ .requested = false, .awaiting = .nothing },
            .{ .requested = false, .awaiting = .fromCancelable(cancelable) },
            .release,
            .monotonic,
        )) |cancel_status| {
            assert(cancel_status.requested and cancel_status.awaiting == .nothing);
            cancelable.cancel = is_requested;
            return error.CancelRequested;
        }
    }

    fn leave(cancelable: *Cancelable, fiber: *Fiber) RequestedError!void {
        const function = cancelable.cancel;
        assert(function != is_requested);
        if (function == is_blocked) {
            @branchHint(.unlikely);
            return;
        }
        const cancel_status = @atomicRmw(Fiber.CancelStatus, &fiber.cancel_status, .And, .{
            .requested = true,
            .awaiting = .nothing,
        }, .monotonic);
        assert(cancel_status.awaiting.toCancelable() == cancelable);
        if (cancel_status.requested) return error.CancelRequested;
    }

    fn async(cancelable: *Cancelable) void {
        const function = cancelable.cancel;
        assert(function != is_blocked and function != is_requested);
        cancelable.queue.async(cancelable, function);
    }

    fn requested(cancelable: *Cancelable, fiber: *Fiber) void {
        const function = cancelable.cancel;
        assert(function != is_blocked and function != is_requested);
        assert(@atomicLoad(Fiber.CancelStatus, &fiber.cancel_status, .monotonic) == Fiber.CancelStatus{
            .requested = true,
            .awaiting = .fromCancelable(cancelable),
        });
        cancelable.cancel = is_requested;
        @atomicStore(Fiber.CancelStatus, &fiber.cancel_status, .{
            .requested = true,
            .awaiting = .nothing,
        }, .monotonic);
    }

    fn acknowledge(cancelable: *Cancelable, fiber: *Fiber) Io.Cancelable!void {
        if (cancelable.cancel == is_requested) {
            @branchHint(.unlikely);
            fiber.cancel_protection.acknowledge();
            return error.Canceled;
        }
    }
}