libxev

repository·main·Indexed 25 days ago

https://github.com/mitchellh/libxev

A high-performance, cross-platform event loop library written in Zig with a C-compatible API. Designed around the Proactor pattern, it provides a unified abstraction for non-blocking IO, timers, signals, and process management across Linux (io_uring, epoll), macOS (kqueue), and WebAssembly (WASI/browser). It features zero runtime allocations and is dependency-free, relying only on libc for its C library.

Tokens
1.4K
Snippets
5
Records
8
Agent score
36%

What's inside libxev

  1. Overview of libxev

    main

    libxev is a cross-platform event loop providing a unified abstraction for non-blocking IO, timers, signals, and events. It supports macOS (kqueue), Linux (io_uring and epoll), and WebAssembly (WASI/browser). It uses a Proactor API pattern, where work is submitted to the loop and the caller is notified upon completion rather than readiness.

    Key characteristics:

    • Zero runtime allocations: Predictable performance and suitable for embedded environments.
    • High-level and Low-level APIs: High-level APIs are platform-agnostic and recommended; low-level APIs provide platform-specific escape hatches for maximum performance.
    • Dependency-free: The C library depends only on libc, making cross-compilation easy.
  2. Install libxev in a Zig project

    main

    To use libxev as a dependency in a Zig project (version 0.11+), add it to your build.zig.zon and configure your build.zig to expose the module.

    // build.zig.zon
    .{
        .name = "my-project",
        .version = "0.0.0",
        .dependencies = .{
            .libxev = .{
                .url = "https://github.com/mitchellh/libxev/archive/<git-ref-here>.tar.gz",
                .hash = "12208070233b17de6be05e32af096a6760682b48598323234824def41789e993432c",
            },
        },
    }
    // build.zig
    const xev = b.dependency("libxev", .{ .target = target, .optimize = optimize });
    exe.addModule("xev", xev.module("xev"));
  3. Build libxev from source

    main

    Build the full library using zig build install. This outputs an FHS-compatible directory in zig-out. You can specify a custom output directory using the --prefix flag.

    Requirements:

    • Zig 0.16 (stable releases only)

    Note: libxev has no other build dependencies.

  4. Run libxev tests

    main

    Run tests for the current host platform:

    zig build test

    To run tests for WASI (requires wasmtime):

    zig build test -Dtarget=wasm32-wasi -Dwasmtime

    To cross-compile tests for another platform (e.g., macOS from Linux):

    zig build -Dtarget=aarch64-macos -Dinstall-tests
  5. Build and run libxev examples

    main

    To build a specific example from the examples/ directory, use the -Dexample-name flag with the filename (including extension).

    $ zig build -Dexample-name=_basic.zig
    $ zig-out/bin/example-basic
  6. Run a simple timer in Zig

    main

    This example demonstrates how to initialize a loop, create a timer, and run it for 5 seconds using the libxev Zig API.

    const xev = @import("xev");
    
    pub fn main() !void {
        var loop = try xev.Loop.init(.{});
        defer loop.deinit();
    
        const w = try xev.Timer.init();
        defer w.deinit();
    
        // 5s timer
        var c: xev.Completion = undefined;
        w.run(&loop, &c, 5000, void, null, &timerCallback);
    
        try loop.run(.until_done);
    }
    
    fn timerCallback(
        userdata: ?*void,
        loop: *xev.Loop,
        c: *xev.Completion,
        result: xev.Timer.RunError!void,
    ) xev.CallbackAction {
       _ = userdata;
       _ = loop;
       _ = c;
       _ = result catch unreachable;
       return .disarm;
    }
  7. Run a simple timer in C

    main

    This example demonstrates how to initialize a loop, create a timer, and run it for 5 seconds using the libxev C API.

    #include <stddef.h>
    #include <stdio.h>
    #include <xev.h>
    
    xev_cb_action timerCallback(xev_loop* loop, xev_completion* c, int result, void *userdata) {
        return XEV_DISARM;
    }
    
    int main(void) {
        xev_loop loop;
        if (xev_loop_init(&loop) != 0) {
            printf("xev_loop_init failure\n");
            return 1;
        }
    
        xev_watcher w;
        if (xev_timer_init(&w) != 0) {
            return 1;
        }
    
        xev_completion c;
        xev_timer_run(&w, &loop, &c, 5000, NULL, &timerCallback);
    
        xev_loop_run(&loop, XEV_RUN_UNTIL_DONE);
    
        xev_timer_deinit(&w);
        xev_loop_deinit(&loop);
        return 0;
    }
  8. Access libxev documentation

    main

    Documentation is currently provided via man pages, examples, and code comments.

    Man Pages

    • xev(7): Overview of the entire library.
    • xev-zig(7): Overview of the Zig API.
    • xev-c(7): Overview of the C API.
    • Specific API functions (e.g., xev_loop_init(3)) are also available.

    To generate man pages locally, you must have scdoc installed:

    zig build -Dman-pages
    man zig-out/share/man/man7/xev.7