GitShow/mitchellh/libxev
mitchellh

libxev

libxev is a cross-platform, high-performance event loop that provides abstractions for non-blocking IO, timers, events, and more and works on Linux (io_uring or epoll), macOS (kqueue), and Wasm + WASI. Available as both a Zig and C API.

by mitchellh
asynccepollio-uringkqueuewasiwebassemblyzig
Star on GitHubFork

Zig

3.6k stars191 forks38 contributorsQuiet · 2mo agoSince 2023MIT

Meet the team

See all 38 on GitHub →
mitchellh
mitchellh476 contributions
dependabot[bot]Bot
dependabot[bot]23 contributions
Corendos
Corendos15 contributions
charlesrocket
charlesrocket10 contributions
ianic
ianic5 contributions
steeve
steeve5 contributions
recursiveGecko
recursiveGecko5 contributions
linuxy
linuxy5 contributions

Languages

View on GitHub →
Zig98%
CSS0.9%
C++0.6%
Nix0.3%
JavaScript0.1%
TypeScript0.1%

Commit activity

Last 12 weeks · 0 commits

Full graph →

Community health

2 of 6 standards met

Community profile →
42
✓README✓License○Contributing○Code of Conduct○Issue Template○PR Template

Recent PRs & issues

Quiet · Last activity 2mo ago
See all on GitHub →
bryanjeal
kqueue: fix tick(0) EV_DELETE flush, rearm state, and submit queue corruptionOpenPR

Three fixes for the kqueue backend, each with a reproducing test: 1. now flushes pending EV_DELETE changes before returning. When a disarm occurs in the event-processing path, the EV_DELETE was queued but exited before flushing it to the kernel, leaving a stale filter with a dangling udata pointer. Related to PR #209. 2. Completions that return without kqueue registration (close, shutdown, no-threadpool fallback) now set state to before re-entering the submissions queue. Previously the stale state caused to route through (cancellation) instead of (resubmit). Related to PR #170. 3. Defensive before pushing kevent-returned completions to the completions queue in . Prevents the queue.zig assertion failure when a completion is present in multiple queues concurrently. Fixes issue #169. 10 tests added (all fail without their respective fixes): tick(0) EV_DELETE flush (6 tests including a synchronous reproduction of the race path via cross-pipe callback write) rearm state for non-kqueue completions (1 test) queue re-enqueue invariants (3 tests)

bryanjeal · 1d ago
endel
kqueue: keep a rearmed completion active when submit() reported itOpenPR

When a completion's fd is already ready at submission time, the call in returns its event, and the callback runs from the completion queue in . If that callback returns , the kqueue filter stays registered, but the completion is left in the state. Anything that relies on that state then misbehaves. For example, a cancel sees a finished completion and does nothing, so the callback keeps firing after the owner has cancelled it, and possibly freed it. Reproducer A pipe that is readable before the read is submitted. The callback rearms once, then the read is cancelled and more data is written: On (macOS): With this change: We hit this in a server whose accept and recv completions rearm. Under load, it showed up as log lines and callbacks running on completions that had already been cancelled. Fix In the completion-queue path of , a completion that was (still registered) and rearms is put back to , with its stale result cleared, instead of being left . Completions that were never registered keep the existing resubmit path. The same reproducer is added as a regression test. It fails on and passes here, and passes (60/60) on macOS. Relation to #224 #224 also touches the branch, but for the other case: completions that return without being registered with kqueue (close, shutdown, thread pool fallback). Those need so that starts them again. This PR covers completions that are still registered. The two changes are complementary; whichever lands second needs a small rebase on that line. Disclosure: the fix, the test and this description were written with AI assistance (Claude Code).

endel · 1d ago
NonMirror
epoll: ignore events for completions that are no longer activeOpenPR

Summary The epoll backend's dispatch loop invokes a completion's callback for every kernel event it receives, without checking that the completion is still outstanding. The submit path already guards on state (, ), but dispatch does not. When a completion is retired — disarmed, cancelled, or already dispatched earlier in the same batch — while a stale event for its former registration is still in that batch, its callback runs a second time. Impact For a queued write this is fatal. 's generated callback () opens with: under a comment asserting the queue cannot be empty. On the second invocation the queue is empty, and in the is unchecked, producing a null dereference. This is the crash tracked in #234: Ghostty 1.3.1 pins and, with , SIGSEGVs on its IO thread at address (, ). The same build aborts at under . Fix Only completions are legitimately registered with epoll, so any other state in the event batch is stale and must be dropped: The change is deliberately minimal: it does not touch the active counter (that was already adjusted when the completion was retired) and leaves the path intact. Testing libxev's own test suite gives identical results with and without the patch, in both Debug and ReleaseSafe — i.e. no regression in the completion state machine (add → dispatch → rearm/disarm → cancel → cancel-after-complete) that the guard touches: The 4 skips are platform-gated ( checks: macOS/WASI/Windows and one x86_64 case), not failures, and are the same on both builds. Filtering to (94 matching tests) likewise gives 91/94 passed, 3 skipped, identically on stock and patched. This suite does not reproduce #234 on its own — both builds pass it. It is evidence of non-regression, not an independent reproduction. Ghostty reproducer (end-to-end) Built Ghostty 1.3.1 (ReleaseFast, , ) against libxev , stock vs. this patch, and ran the #234 reproducer (). Epoll was confirmed active in every run via . Stock failures are exactly the #234 crash — thread , , , and the faulting instruction which matches the epoll / layout described in #234. The reproducer is a race (stock fired in roughly 2 in 5 runs), so the table is a rate comparison rather than a deterministic reproduction. No missed wakeups, hangs, or other failures were observed in the patched runs. Limitations Does not address the fd-reuse case in #230, where a genuinely completion receives an event belonging to a previous registration. Assumes the completion's memory is still valid when the stale event is dispatched. That holds for the case but is not guaranteed in general; a full fix may need lifetime tracking rather than a state read. Relation to existing work Addresses #234, the epoll member of the completion-reuse class alongside #169, #227, and #224 (kqueue). #237's cancellation/dup-fd changes are complementary but, as noted in #234, insufficient on their own.

NonMirror · 1d ago
Structured data for AI agents

Repository: mitchellh/libxev. Description: libxev is a cross-platform, high-performance event loop that provides abstractions for non-blocking IO, timers, events, and more and works on Linux (io_uring or epoll), macOS (kqueue), and Wasm + WASI. Available as both a Zig and C API. Stars: 3582, Forks: 191. Primary language: Zig. Languages: Zig (98%), CSS (0.9%), C++ (0.6%), Nix (0.3%), JavaScript (0.1%). License: MIT. Topics: async, c, epoll, io-uring, kqueue, wasi, webassembly, zig. Open PRs: 26, open issues: 41. Last activity: 2mo ago. Community health: 42%. Top contributors: mitchellh, dependabot[bot], Corendos, charlesrocket, ianic, steeve, recursiveGecko, linuxy, kcbanner, rockorager and others.

·@ofershap

Replace github.com with gitshow.dev