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.

callFn

Performs implementation-agnostic thread setup (maybeAttachSignalStack), then calls the given thread entry point f with args and handles the result.

Thread.callFn
fn callFn(comptime f: anytype, args: anytype) switch (Impl)

File

lib/std/Thread.zig:401

Code

fn callFn(comptime f: anytype, args: anytype) switch (Impl) {
    WindowsThreadImpl => windows.NTSTATUS,
    LinuxThreadImpl => u8,
    PosixThreadImpl => ?*anyopaque,
    else => unreachable,
} {
    maybeAttachSignalStack();

    const default_value = switch (Impl) {
        WindowsThreadImpl => .SUCCESS,
        LinuxThreadImpl => 0,
        PosixThreadImpl => null,
        else => unreachable,
    };
    const bad_fn_ret = "expected return type of startFn to be 'u8', 'noreturn', '!noreturn', 'void', or '!void'";

    switch (@typeInfo(@typeInfo(@TypeOf(f)).@"fn".return_type.?)) {
        .noreturn => {
            @call(.auto, f, args);
        },
        .void => {
            @call(.auto, f, args);
            return default_value;
        },
        .int => |info| {
            if (info.bits != 8) {
                @compileError(bad_fn_ret);
            }

            const status = @call(.auto, f, args);
            switch (Impl) {
                WindowsThreadImpl => return @fromBackingInt(@intCast(status)),
                LinuxThreadImpl => return status,
                // pthreads don't support exit status, ignore value
                PosixThreadImpl => return default_value,
                else => unreachable,
            }
        },
        .error_union => |info| {
            switch (info.payload) {
                void, noreturn => {
                    @call(.auto, f, args) catch |err| {
                        std.debug.print("error: {s}\n", .{@errorName(err)});
                        if (@errorReturnTrace()) |trace| {
                            std.debug.dumpErrorReturnTrace(trace);
                        }
                    };

                    return default_value;
                },
                else => {
                    @compileError(bad_fn_ret);
                },
            }
        },
        else => {
            @compileError(bad_fn_ret);
        },
    }
}