Post #1953787
2026-04-20 06:43 UTC
Replies (1)
-
@kevinmehall@hachyderm.io 2026-04-20 15:18
@r Well one of the nice things about Rust async is that despite the dominance of Tokio, you don't have to depend on one particular executor or reactor because futures are interoperable. nusb just spawns a thread and runs its own epoll / CFRunLoop / IOCP reactor just like you do, which either triggers Wakers for the async API, or notifies a condvar for the blocking API. It depends on tokio or smol just for the `spawn_blocking` threadpool for the syscalls that don't have an async equivalent. The completion-based IO problem is that Rust async is designed around syscalls that look like `read()`, i.e. buffer data in the kernel that is copied to userspace synchronously within the syscall or else fail with EAGAIN. Things like IOCP, io_uring, or USB that directly access userspace buffers asynchronously need to own rather than borrow the buffer, to avoid unsoundness with mem::forget or even normal cancellation.