Skip to content

Commit 7e21459

Browse files
author
winger
committed
add libxev to vendor
1 parent 25b6918 commit 7e21459

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

82 files changed

+31503
-0
lines changed

vendor/libxev/.envrc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# If we are a computer with nix-shell available, then use that to setup
2+
# the build environment with exactly what we need.
3+
if has nix; then
4+
use nix
5+
fi

vendor/libxev/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.zig-cache
2+
zig-out

vendor/libxev/LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2023 Mitchell Hashimoto
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

vendor/libxev/README.md

Lines changed: 315 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,315 @@
1+
# libxev
2+
3+
libxev is a cross-platform event loop. libxev provides a unified event loop
4+
abstraction for non-blocking IO, timers, signals, events, and more that
5+
works on macOS, Windows, Linux, and WebAssembly (browser and WASI). It is
6+
written in [Zig](https://ziglang.org/) but exports a C-compatible API (which
7+
further makes it compatible with any language out there that can communicate
8+
with C APIs).
9+
10+
**Project Status: 🐲 Unstable, alpha-ish quality.** The feature list is quite
11+
good across multiple platforms, but there are plenty of missing features.
12+
The project hasn't been well tested in real-world environments and there
13+
are lots of low-hanging fruit for performance optimization. I'm not promising
14+
any API compatibility at this point, either. If you want a production ready,
15+
high quality, generalized event loop implementation check out
16+
[libuv](https://libuv.org/), libev, etc.
17+
18+
**Why a new event loop library?** A few reasons. One, I think Zig lacks
19+
a generalized event loop comparable to libuv in features ("generalized"
20+
being a key word here). Two, I wanted to build a library like this around
21+
the design patterns of [io_uring](https://unixism.net/loti/what_is_io_uring.html),
22+
even mimicking its style on top of other OS primitives (
23+
[credit to this awesome blog post](https://tigerbeetle.com/blog/a-friendly-abstraction-over-iouring-and-kqueue/)).
24+
Three, I wanted an event loop library that could build to WebAssembly
25+
(both WASI and freestanding) and that didn't really fit well
26+
into the goals of API style of existing libraries without bringing in
27+
something super heavy like Emscripten. The motivation for this library
28+
primarily though is scratching my own itch!
29+
30+
## Features
31+
32+
**Cross-platform.** Linux (`io_uring` and `epoll`), macOS (`kqueue`),
33+
WebAssembly + WASI (`poll_oneoff`, threaded and non-threaded runtimes).
34+
(Windows support is planned and coming soon)
35+
36+
**[Proactor API](https://en.wikipedia.org/wiki/Proactor_pattern).** Work
37+
is submitted to the libxev event loop and the caller is notified of
38+
work _completion_, as opposed to work _readiness_.
39+
40+
**Zero runtime allocations.** This helps make runtime performance more
41+
predictable and makes libxev well suited for embedded environments.
42+
43+
**Timers, TCP, UDP, Files, Processes.** High-level platform-agnostic APIs for
44+
interacting with timers, TCP/UDP sockets, files, processes, and more. For
45+
platforms that don't support async IO, the file operations are automatically
46+
scheduled to a thread pool.
47+
48+
**Generic Thread Pool (Optional).** You can create a generic thread pool,
49+
configure its resource utilization, and use this to perform custom background
50+
tasks. The thread pool is used by some backends to do non-blocking tasks that
51+
don't have reliable non-blocking APIs (such as local file operations with
52+
`kqueue`). The thread pool can be shared across multiple threads and event
53+
loops to optimize resource utilization.
54+
55+
**Low-level and High-Level API.** The high-level API is platform-agnostic
56+
but has some opinionated behavior and limited flexibility. The high-level
57+
API is recommended but the low-level API is always an available escape hatch.
58+
The low-level API is platform-specific and provides a mechanism for libxev
59+
users to squeeze out maximum performance. The low-level API is _just enough
60+
abstraction_ above the OS interface to make it easier to use without
61+
sacrificing noticable performance.
62+
63+
**Tree Shaking (Zig).** This is a feature of Zig, but substantially benefits
64+
libraries such as libxev. Zig will only include function calls and features
65+
that you actually use. If you don't use a particular kind of high-level
66+
watcher (such as UDP sockets), then the functionality related to that
67+
abstraction is not compiled into your final binary at all. This lets libxev
68+
support optional "nice-to-have" functionality that may be considered
69+
"bloat" in some cases, but the end user doesn't have to pay for it.
70+
71+
**Dependency-free.** libxev has no dependencies other than the built-in
72+
OS APIs at runtime. The C library depends on libc. This makes it very
73+
easy to cross-compile.
74+
75+
### Roadmap
76+
77+
There are plenty of missing features that I still want to add:
78+
79+
* Pipe high-level API
80+
* Signal handlers
81+
* Filesystem events
82+
* Windows backend
83+
* Freestanding WebAssembly support via an external event loop (i.e. the browser)
84+
85+
And more...
86+
87+
### Performance
88+
89+
There is plenty of room for performance improvements, and I want to be
90+
fully clear that I haven't done a lot of optimization work. Still,
91+
performance is looking good. I've tried to port many of
92+
[libuv benchmarks](https://github.com/libuv/libuv) to use the libxev
93+
API.
94+
95+
I won't post specific benchmark results until I have a better
96+
environment to run them in. As a _very broad generalization_,
97+
you shouldn't notice a slowdown using libxev compared to other
98+
major event loops. This may differ on a feature-by-feature basis, and
99+
if you can show really poor performance in an issue I'm interested
100+
in resolving it!
101+
102+
## Example
103+
104+
The example below shows an identical program written in Zig and in C
105+
that uses libxev to run a single 5s timer. This is almost silly how
106+
simple it is but is meant to just convey the overall feel of the library
107+
rather than a practical use case.
108+
109+
<table>
110+
<tr>
111+
<td> Zig </td> <td> C </td>
112+
</tr>
113+
<tr>
114+
<td>
115+
116+
```zig
117+
const xev = @import("xev");
118+
119+
pub fn main() !void {
120+
var loop = try xev.Loop.init(.{});
121+
defer loop.deinit();
122+
123+
const w = try xev.Timer.init();
124+
defer w.deinit();
125+
126+
// 5s timer
127+
var c: xev.Completion = undefined;
128+
w.run(&loop, &c, 5000, void, null, &timerCallback);
129+
130+
try loop.run(.until_done);
131+
}
132+
133+
fn timerCallback(
134+
userdata: ?*void,
135+
loop: *xev.Loop,
136+
c: *xev.Completion,
137+
result: xev.Timer.RunError!void,
138+
) xev.CallbackAction {
139+
_ = userdata;
140+
_ = loop;
141+
_ = c;
142+
_ = result catch unreachable;
143+
return .disarm;
144+
}
145+
```
146+
147+
</td>
148+
<td>
149+
150+
```zig
151+
#include <stddef.h>
152+
#include <stdio.h>
153+
#include <xev.h>
154+
155+
xev_cb_action timerCallback(xev_loop* loop, xev_completion* c, int result, void *userdata) {
156+
return XEV_DISARM;
157+
}
158+
159+
int main(void) {
160+
xev_loop loop;
161+
if (xev_loop_init(&loop) != 0) {
162+
printf("xev_loop_init failure\n");
163+
return 1;
164+
}
165+
166+
xev_watcher w;
167+
if (xev_timer_init(&w) != 0) {
168+
printf("xev_timer_init failure\n");
169+
return 1;
170+
}
171+
172+
xev_completion c;
173+
xev_timer_run(&w, &loop, &c, 5000, NULL, &timerCallback);
174+
175+
xev_loop_run(&loop, XEV_RUN_UNTIL_DONE);
176+
177+
xev_timer_deinit(&w);
178+
xev_loop_deinit(&loop);
179+
return 0;
180+
}
181+
```
182+
</td>
183+
</tr>
184+
</table>
185+
186+
## Installation (Zig)
187+
188+
**These instructions are for Zig downstream users only.** If you are
189+
using the C API to libxev, see the "Build" section.
190+
191+
This package works with the Zig package manager introduced in Zig 0.11.
192+
Create a `build.zig.zon` file like this:
193+
194+
```zig
195+
.{
196+
.name = "my-project",
197+
.version = "0.0.0",
198+
.dependencies = .{
199+
.libxev = .{
200+
.url = "https://github.com/mitchellh/libxev/archive/<git-ref-here>.tar.gz",
201+
.hash = "12208070233b17de6be05e32af096a6760682b48598323234824def41789e993432c",
202+
},
203+
},
204+
}
205+
```
206+
207+
And in your `build.zig`:
208+
209+
```zig
210+
const xev = b.dependency("libxev", .{ .target = target, .optimize = optimize });
211+
exe.addModule("xev", xev.module("xev"));
212+
```
213+
214+
## Documentation
215+
216+
🚧 Documentation is a work-in-progress. 🚧
217+
218+
Currently, documentation is available in three forms: **man pages**,
219+
**examples**, and **code comments.** In the future, I plan on writing detailed
220+
guides and API documentation in website form, but that isn't currently
221+
available.
222+
223+
### Man Pages
224+
225+
The man pages are relatively detailed! `xev(7)` will
226+
give you a good overview of the entire library. `xev-zig(7)` and
227+
`xev-c(7)` will provide overviews of the Zig and C API, respectively.
228+
From there, API-specifc man pages such as `xev_loop_init(3)` are
229+
available. This is the best documentation currently.
230+
231+
There are multiple ways to browse the man pages. The most immediately friendly
232+
is to just browse the raw man page sources in the `docs/` directory in
233+
your web browser. The man page source is a _markdown-like_ syntax so it
234+
renders _okay_ in your browser via GitHub.
235+
236+
Another approach is to run `zig build -Dman-pages` and the man pages
237+
will be available in `zig-out`. This requires
238+
[scdoc](https://git.sr.ht/~sircmpwn/scdoc)
239+
to be installed (this is available in most package managers).
240+
Once you've built the man pages, you can render them by path:
241+
242+
```
243+
$ man zig-out/share/man/man7/xev.7
244+
```
245+
246+
And the final approach is to install libxev via your favorite package
247+
manager (if and when available), which should hopefully put your man pages
248+
into your man path, so you can just do `man 7 xev`.
249+
250+
### Examples
251+
252+
There are examples available in the `examples/` folder. The examples are
253+
available in both C and Zig, and you can tell which one is which using
254+
the file extension.
255+
256+
To build an example, use the following:
257+
258+
```
259+
$ zig build -Dexample-name=_basic.zig
260+
...
261+
$ zig-out/bin/example-basic
262+
...
263+
```
264+
265+
The `-Dexample-name` value should be the filename including the extension.
266+
267+
### Code Comments
268+
269+
The Zig code is well commented. If you're comfortable reading code comments
270+
you can find a lot of insight within them. The source is in the `src/`
271+
directory.
272+
273+
# Build
274+
275+
Build requires the installation of the latest [Zig nightly](https://ziglang.org/download/).
276+
**libxev has no other build dependencies.**
277+
278+
Once installed, `zig build install` on its own will build the full library and output
279+
a [FHS-compatible](https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard)
280+
directory in `zig-out`. You can customize the output directory with the
281+
`--prefix` flag.
282+
283+
## Tests
284+
285+
libxev has a large and growing test suite. To run the tests for the current
286+
platform:
287+
288+
```sh
289+
$ zig build test
290+
...
291+
```
292+
293+
This will run all the tests for all the supported features for the current
294+
host platform. For example, on Linux this will run both the full io_uring
295+
and epoll test suite.
296+
297+
**You can build and run tests for other platforms** by cross-compiling the
298+
test executable, copying it to a target machine and executing it. For example,
299+
the below shows how to cross-compile and build the tests for macOS from Linux:
300+
301+
```sh
302+
$ zig build -Dtarget=aarch64-macos -Dinstall-tests
303+
...
304+
305+
$ file zig-out/bin/xev-test
306+
zig-out/bin/xev-test: Mach-O 64-bit arm64 executable
307+
```
308+
309+
**WASI is a special-case.** You can run tests for WASI if you have
310+
[wasmtime](https://wasmtime.dev/) installed:
311+
312+
```
313+
$ zig build test -Dtarget=wasm32-wasi -Dwasmtime
314+
...
315+
```

0 commit comments

Comments
 (0)