//! zio: an evented std.Io backend built to beat thread-per-connection under //! ReleaseSafe. see README. //! //! two surfaces: //! - `Zio`: a hybrid std.Io implementation — currently delegates the entire //! vtable to an inner Io.Threaded. evented ops get spliced in as the //! engine grows. NOTE: blocking-style Io networking on the engine requires //! suspending callers (fibers) — that is deliberately NOT in v0, which is //! why Zio delegates net ops today. see relay/docs/evented-runtime-plan.md. const std = @import("std"); const Io = std.Io; pub const net = @import("net.zig"); pub const sched = @import("fiber/sched.zig"); pub const backend = @import("backend.zig"); pub const Sched = sched.Sched; pub const ZioBackend = backend.Zio; pub const poller = @import("poller.zig"); /// hybrid backend: wraps Io.Threaded, exposes a copied vtable so individual /// ops can be overridden without forwarding shims. overridden ops recover /// the Zio via @fieldParentPtr("threaded", ...) since userdata stays /// &self.threaded (the inner Threaded). pub const Zio = struct { threaded: Io.Threaded, vtable: Io.VTable, pub fn init(zio: *Zio, allocator: std.mem.Allocator) void { zio.threaded = .init(allocator, .{}); const inner = zio.threaded.io(); zio.vtable = inner.vtable.*; // overrides land here, e.g.: // zio.vtable.netConnectIp = eventedNetConnectIp; } pub fn deinit(zio: *Zio) void { zio.threaded.deinit(); } pub fn io(zio: *Zio) Io { return .{ .userdata = &zio.threaded, .vtable = &zio.vtable }; } }; test "Zio delegates to Io.Threaded (sleep + clock through copied vtable)" { var zio: Zio = undefined; zio.init(std.testing.allocator); defer zio.deinit(); const io_i = zio.io(); const t0 = Io.Timestamp.now(io_i, .awake); try io_i.sleep(Io.Duration.fromMilliseconds(5), .awake); const t1 = Io.Timestamp.now(io_i, .awake); try std.testing.expect(t0.durationTo(t1).nanoseconds >= 4 * std.time.ns_per_ms); } test { std.testing.refAllDecls(@This()); _ = net; _ = poller; _ = @import("fiber/spike.zig"); _ = @import("fiber/sched.zig"); _ = @import("backend.zig"); }