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.

SwitchMessage

Kqueue.SwitchMessage
const SwitchMessage = struct

File

lib/std/Io/Kqueue.zig:486

Code

const SwitchMessage = struct {
    contexts: Io.fiber.Switch,
    pending_task: PendingTask,

    const PendingTask = union(enum) {
        nothing,
        reschedule,
        recycle: *Fiber,
        register_awaiter: *?*Fiber,
        exit,
    };

    fn handle(message: *const SwitchMessage, k: *Kqueue) void {
        const thread: *Thread = .current();
        thread.current_context = message.contexts.new;
        switch (message.pending_task) {
            .nothing => {},
            .reschedule => if (message.contexts.old != &thread.idle_context) {
                const prev_fiber: *Fiber = @alignCast(@fieldParentPtr("context", message.contexts.old));
                assert(prev_fiber.queue_next == null);
                k.schedule(thread, .{ .head = prev_fiber, .tail = prev_fiber });
            },
            .recycle => |fiber| {
                k.recycle(fiber);
            },
            .register_awaiter => |awaiter| {
                const prev_fiber: *Fiber = @alignCast(@fieldParentPtr("context", message.contexts.old));
                assert(prev_fiber.queue_next == null);
                if (@atomicRmw(?*Fiber, awaiter, .Xchg, prev_fiber, .acq_rel) == Fiber.finished)
                    k.schedule(thread, .{ .head = prev_fiber, .tail = prev_fiber });
            },
            .exit => for (k.threads.allocated[0..@atomicLoad(u32, &k.threads.active, .acquire)]) |*each_thread| {
                const changes = [_]posix.Kevent{
                    .{
                        .ident = 0,
                        .filter = std.c.EVFILT.USER,
                        .flags = std.c.EV.ADD | std.c.EV.ONESHOT,
                        .fflags = std.c.NOTE.TRIGGER,
                        .data = 0,
                        .udata = @backingInt(Completion.UserData.exit),
                    },
                };
                _ = kevent(each_thread.kq_fd, &changes, &.{}, null) catch |err| {
                    // TODO handle EINTR for cancellation purposes
                    @panic(@errorName(err)); // TODO
                };
            },
        }
    }
}