Repository navigation
v3.0.2 – Fixed stuck I/O awaiters and improved epoll state handling
Release notes:
This release resolves a critical coroutine wake-up issue in the epoll integration layer that caused consistent 2-second stalls on TCP writes and potential hangs on subsequent reads.
🧩 Core Fixes
-
Removed stale I/O flags (
is_writing_now,is_reading_now): these flags caused sockets to skip re-arming EPOLLIN/EPOLLOUT after the first await, resulting in lost wakeups. -
Simplified Awaiter design:
AwaiterWriteandAwaiterReadnow always re-register interest (EPOLL_CTL_MOD) on every newco_await.- Awaiter state is tracked solely via
SocketHeader::first(read waiter) andSocketHeader::second(write waiter). - No more “flag handshake” between awaiters and poller.
-
Poller cleanup: each
EPOLLIN/EPOLLOUTevent now resumes the corresponding coroutine directly and clears the slot atomically; no more dependency onclear_writing()orclear_reading().
⚙️ Behavioral Impact
- Eliminates the consistent ~2000 ms latency observed after connect() due to missed EPOLLOUT.
- Prevents future deadlocks on repeated
async_read()calls in persistent TCP sessions. - Slightly increases
epoll_ctl(EPOLL_CTL_MOD)calls, but ensures strict correctness and deterministic wake-ups under ET mode.
✅ Summary
v3.0.2 focuses on reliability and correctness of coroutine I/O scheduling.
Event re-arming is now explicit and safe, guaranteeing that every await resumes exactly once with no race or delay.