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

Dispatch.SwitchMessage
const SwitchMessage = struct

File

lib/std/Io/Dispatch.zig:626

Code

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

    const PendingTask = union(enum) {
        nothing,
        await: *Fiber,
        activate: c.dispatch.object_t,
        @"resume": c.dispatch.object_t,
        group_await: Group,
        group_cancel: Group,
        mutex_wait: *Mutex.Waiter,
        futex_wait: *Futex.Waiter,
        futex_wake: *Futex.Waker,
        sleep_wait: *SleepWaiter,
        after: c.dispatch.time_t,
        destroy,
        exit,
    };

    fn handle(message: *const SwitchMessage, ev: *Evented) void {
        const thread: *Thread = .current();
        thread.current_context = message.contexts.new;
        switch (message.pending_task) {
            .nothing => {},
            .await => |awaiting| {
                const awaiter: *Fiber = @alignCast(@fieldParentPtr("context", message.contexts.old));
                if (@atomicRmw(?*Fiber, &awaiting.link.awaiter, .Xchg, awaiter, .acq_rel) ==
                    Fiber.finished) ev.queue.async(awaiter, &Fiber.@"resume");
            },
            .activate => |object| object.activate(),
            .@"resume" => |object| object.@"resume"(),
            .group_await => |group| {
                const fiber: *Fiber = @alignCast(@fieldParentPtr("context", message.contexts.old));
                if (group.await(ev, fiber)) ev.queue.async(fiber, &Fiber.@"resume");
            },
            .group_cancel => |group| {
                const fiber: *Fiber = @alignCast(@fieldParentPtr("context", message.contexts.old));
                if (group.cancel(ev, fiber)) ev.queue.async(fiber, &Fiber.@"resume");
            },
            .mutex_wait => |waiter| {
                waiter.sleeper =
                    .init(ev.queue, @alignCast(@fieldParentPtr("context", message.contexts.old)));
                switch (waiter.sleeper.fiber.cancel_protection.check()) {
                    .unblocked => {},
                    .blocked => waiter.cancelable = .blocked,
                }
                waiter.mutex.queue.async(waiter, &Mutex.Waiter.add);
            },
            .futex_wait => |waiter| {
                waiter.sleeper =
                    .init(ev.queue, @alignCast(@fieldParentPtr("context", message.contexts.old)));
                switch (waiter.sleeper.fiber.cancel_protection.check()) {
                    .unblocked => {},
                    .blocked => waiter.cancelable = .blocked,
                }
                waiter.futex.queue.async(waiter, &Futex.Waiter.add);
            },
            .futex_wake => |waker| {
                waker.sleeper =
                    .init(ev.queue, @alignCast(@fieldParentPtr("context", message.contexts.old)));
                waker.futex.queue.async(waker, &Futex.Waker.remove);
            },
            .sleep_wait => |waiter| {
                waiter.sleeper =
                    .init(ev.queue, @alignCast(@fieldParentPtr("context", message.contexts.old)));
                const queue = waiter.cancelable.queue;
                switch (waiter.sleeper.fiber.cancel_protection.check()) {
                    .unblocked => {},
                    .blocked => waiter.cancelable = .blocked,
                }
                queue.async(waiter, &SleepWaiter.start);
            },
            .after => |when| {
                const fiber: *Fiber = @alignCast(@fieldParentPtr("context", message.contexts.old));
                when.after(ev.queue, fiber, &Fiber.@"resume");
            },
            .destroy => {
                const fiber: *Fiber = @alignCast(@fieldParentPtr("context", message.contexts.old));
                fiber.destroy(ev);
            },
            .exit => _ = ev.exit_semaphore.signal(),
        }
    }
}