Expand description
Pywaker provides a GIL-free way to wake up Python event loops from Rust. This is accomplished by writing a single byte to a “self pipe” for every wake up. The corresponding read-side FD is added to the Python-side event loop.
The approach does not add overhead in uncontended scenarios:
| Approach | Mean | Notes |
|----------------------|--------|---------------------------------|
| FD-based | ~48 µs | No GIL acquisition on Rust side |
| call_soon_threadsafe | ~56 µs | Acquires GIL on Rust side |
| Pure Python | ~44 µs | Baseline for comparison |§Implementation notes
event creates a pipe(2), and wakeup events are implemented by writing a single
byte into the pipe. The Python (read side) event registers the read fd into its
asyncio event loop. Thus the pipe acts as a notification queue. When the fd becomes
readable, the python event drains the pipe and then sets an asyncio.Event to notify
any waiters.
The reader side is always single threaded (it is bound to a specific event loop), and thus free of race conditions. This is because all read operations occur within a single asyncio event loop, which processes events sequentially on one thread, eliminating the possibility of concurrent access to the read side of the pipe.
Structs§
Functions§
- event
- Create a new event, returning the (Rust only)
Waker, and a PythonPyEvent, intended for passing to Python code. - register_
python_ bindings