-
Notifications
You must be signed in to change notification settings - Fork 74
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f5977bd
commit 2127b0f
Showing
2 changed files
with
211 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
const std = @import("std"); | ||
const builtin = @import("builtin"); | ||
|
||
pub const Xev = @import("xev.zig").Xev; | ||
|
||
/// System-specific interfaces. Note that they are always pub for | ||
/// all systems but if you reference them and force them to be analyzed | ||
/// the proper system APIs must exist. Due to Zig's lazy analysis, if you | ||
/// don't use any interface it will NOT be compiled (yay!). | ||
pub const IO_Uring = Xev(.io_uring, @import("backend/io_uring.zig")); | ||
pub const Epoll = Xev(.epoll, @import("backend/epoll.zig")); | ||
pub const Kqueue = Xev(.kqueue, @import("backend/kqueue.zig")); | ||
pub const WasiPoll = Xev(.wasi_poll, @import("backend/wasi_poll.zig")); | ||
pub const IOCP = Xev(.iocp, @import("backend/iocp.zig")); | ||
|
||
/// Generic thread pool implementation. | ||
pub const ThreadPool = @import("ThreadPool.zig"); | ||
|
||
/// This stream (lowercase s) can be used as a namespace to access | ||
/// Closeable, Writeable, Readable, etc. so that custom streams | ||
/// can be constructed. | ||
pub const stream = @import("watcher/stream.zig"); | ||
|
||
/// The backend types. | ||
pub const Backend = enum { | ||
io_uring, | ||
epoll, | ||
kqueue, | ||
wasi_poll, | ||
iocp, | ||
|
||
/// Returns a recommend default backend from inspecting the system. | ||
pub fn default() Backend { | ||
return @as(?Backend, switch (builtin.os.tag) { | ||
.linux => .io_uring, | ||
.ios, .macos => .kqueue, | ||
.wasi => .wasi_poll, | ||
.windows => .iocp, | ||
else => null, | ||
}) orelse { | ||
@compileLog(builtin.os); | ||
@compileError("no default backend for this target"); | ||
}; | ||
} | ||
|
||
/// Returns the Api (return value of Xev) for the given backend type. | ||
pub fn Api(comptime self: Backend) type { | ||
return switch (self) { | ||
.io_uring => IO_Uring, | ||
.epoll => Epoll, | ||
.kqueue => Kqueue, | ||
.wasi_poll => WasiPoll, | ||
.iocp => IOCP, | ||
}; | ||
} | ||
}; | ||
|
||
pub const backend = Backend.default(); | ||
|
||
pub const Sys = backend.Api().Sys; | ||
|
||
const loop = @import("loop.zig"); | ||
|
||
/// The core loop APIs. | ||
pub const Loop = Sys.Loop; | ||
pub const Completion = Sys.Completion; | ||
pub const Result = Sys.Result; | ||
pub const ReadBuffer = Sys.ReadBuffer; | ||
pub const WriteBuffer = Sys.WriteBuffer; | ||
pub const Options = loop.Options; | ||
pub const RunMode = loop.RunMode; | ||
pub const CallbackAction = loop.CallbackAction; | ||
pub const CompletionState = loop.CompletionState; | ||
|
||
/// Error types | ||
pub const AcceptError = Sys.AcceptError; | ||
pub const CancelError = Sys.CancelError; | ||
pub const CloseError = Sys.CloseEror; | ||
pub const ConnectError = Sys.ConnectError; | ||
pub const ShutdownError = Sys.ShutdownError; | ||
pub const WriteError = Sys.WriteError; | ||
pub const ReadError = Sys.ReadError; | ||
|
||
const Self = @This(); | ||
|
||
/// The high-level helper interfaces that make it easier to perform | ||
/// common tasks. These may not work with all possible Loop implementations. | ||
pub const Async = @import("watcher/async.zig").Async(Self); | ||
pub const File = @import("watcher/file.zig").File(Self); | ||
pub const Process = @import("watcher/process.zig").Process(Self); | ||
pub const Stream = stream.GenericStream(Self); | ||
pub const Timer = @import("watcher/timer.zig").Timer(Self); | ||
pub const TCP = @import("watcher/tcp.zig").TCP(Self); | ||
pub const UDP = @import("watcher/udp.zig").UDP(Self); | ||
|
||
/// The callback of the main Loop operations. Higher level interfaces may | ||
/// use a different callback mechanism. | ||
pub const Callback = *const fn ( | ||
userdata: ?*anyopaque, | ||
loop: *Loop, | ||
completion: *Completion, | ||
result: Result, | ||
) CallbackAction; | ||
|
||
pub const noopCallback = Sys.noopCallback; | ||
|
||
test { | ||
// Tested on all platforms | ||
_ = @import("heap.zig"); | ||
_ = @import("queue.zig"); | ||
_ = @import("queue_mpsc.zig"); | ||
_ = ThreadPool; | ||
|
||
// Test the C API | ||
if (builtin.os.tag != .wasi) _ = @import("c_api.zig"); | ||
|
||
// OS-specific tests | ||
switch (builtin.os.tag) { | ||
.linux => { | ||
_ = Epoll; | ||
_ = IO_Uring; | ||
_ = @import("linux/timerfd.zig"); | ||
}, | ||
|
||
.wasi => { | ||
//_ = WasiPoll; | ||
_ = @import("backend/wasi_poll.zig"); | ||
}, | ||
|
||
.windows => { | ||
_ = @import("backend/iocp.zig"); | ||
}, | ||
|
||
else => {}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
const Backend = @import("lib.zig").Backend; | ||
|
||
pub fn Xev(comptime be: Backend, comptime T: type) type { | ||
return struct { | ||
const Self = @This(); | ||
const loop = @import("loop.zig"); | ||
|
||
/// The backend that this is. This is supplied at comptime so | ||
/// it is up to the caller to say the right thing. This lets custom | ||
/// implementations also "quack" like an implementation. | ||
pub const backend = be; | ||
|
||
/// The core loop APIs. | ||
pub const Loop = T.Loop; | ||
pub const Completion = T.Completion; | ||
pub const Result = T.Result; | ||
pub const ReadBuffer = T.ReadBuffer; | ||
pub const WriteBuffer = T.WriteBuffer; | ||
pub const Options = loop.Options; | ||
pub const RunMode = loop.RunMode; | ||
pub const CallbackAction = loop.CallbackAction; | ||
pub const CompletionState = loop.CompletionState; | ||
|
||
/// Error types | ||
pub const AcceptError = T.AcceptError; | ||
pub const CancelError = T.CancelError; | ||
pub const CloseError = T.CloseError; | ||
pub const ConnectError = T.ConnectError; | ||
pub const ShutdownError = T.ShutdownError; | ||
pub const WriteError = T.WriteError; | ||
pub const ReadError = T.ReadError; | ||
|
||
/// The high-level helper interfaces that make it easier to perform | ||
/// common tasks. These may not work with all possible Loop implementations. | ||
pub const Async = @import("watcher/async.zig").Async(Self); | ||
pub const File = @import("watcher/file.zig").File(Self); | ||
pub const Process = @import("watcher/process.zig").Process(Self); | ||
pub const Stream = @import("watcher/stream.zig").GenericStream(Self); | ||
pub const Timer = @import("watcher/timer.zig").Timer(Self); | ||
pub const TCP = @import("watcher/tcp.zig").TCP(Self); | ||
pub const UDP = @import("watcher/udp.zig").UDP(Self); | ||
|
||
/// The callback of the main Loop operations. Higher level interfaces may | ||
/// use a different callback mechanism. | ||
pub const Callback = *const fn ( | ||
userdata: ?*anyopaque, | ||
loop: *Loop, | ||
completion: *Completion, | ||
result: Result, | ||
) CallbackAction; | ||
|
||
/// A way to access the raw type. | ||
pub const Sys = T; | ||
|
||
/// A callback that does nothing and immediately disarms. This | ||
/// implements xev.Callback and is the default value for completions. | ||
pub fn noopCallback( | ||
_: ?*anyopaque, | ||
_: *Loop, | ||
_: *Completion, | ||
_: Result, | ||
) CallbackAction { | ||
return .disarm; | ||
} | ||
|
||
test { | ||
@import("std").testing.refAllDecls(@This()); | ||
} | ||
|
||
test "completion is zero-able" { | ||
const c: Completion = .{}; | ||
_ = c; | ||
} | ||
}; | ||
} |