Conversation
📝 WalkthroughWalkthroughConsolidates epoll readiness and op handling: descriptor mutex is acquired unconditionally and connect/read/write ops are processed or reassigned under the guard; EAGAIN/EWOULDBLOCK is normalized, cancellations post/finish deterministically, and completed ops are moved to a local queue for scheduling. Changes
Sequence Diagram(s)mermaid Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
No actionable comments were generated in the recent review. 🎉 Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
An automated preview of the documentation is available at https://116.corosio.prtest3.cppalliance.org/index.html If more commits are pushed to the pull request, the docs will rebuild at the same URL. 2026-02-10 01:51:17 UTC |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@src/corosio/src/detail/epoll/sockets.cpp`:
- Around line 376-395: The do_write_io retry loop misses a cancellation check
after it re-parks the operation into desc_state_.write_op: after the block that
sets desc_state_.write_ready = false / desc_state_.write_op = &op and breaks,
add the same cancellation-check performed elsewhere (check op.cancelled or
whatever cancellation flag the code uses, and if cancelled call svc_.post(&op)
and svc_.work_finished() then return) so we don't skip handling a cancellation
when we re-park the write; locate the logic around op.perform_io(), op.errn,
svc_.post, svc_.work_finished, and desc_state_.write_op in do_write_io and
insert the check immediately after re-parking/breaking from the retry loop.
- Around line 287-306: The read retry loop that calls op.perform_io() and then
parks the operation by setting desc_state_.read_op = &op lacks the same
cancellation check used in the non-perform_now path; before returning after
breaking out of that loop (i.e., after desc_state_.read_op is set and control
would hit the return), check op.cancelled and if true, clear
desc_state_.read_op, call svc_.post(&op) and svc_.work_finished() (matching the
cancellation handling used elsewhere), then return; update the logic around the
loop that sets desc_state_.read_op to mirror the cancel-handling in the other
path so cancelled ops are completed immediately.
- Around line 187-206: After the loop that sets desc_state_.connect_op = &op and
breaks, add the same cancellation re-check used in the non-perform_now path:
after parking the op (when op.errn was EAGAIN/EWOULDBLOCK and
desc_state_.write_ready was false) check op.cancelled under the same
locking/claiming logic and, if cancelled, clear desc_state_.connect_op, post the
op to svc_ and call svc_.work_finished() (or otherwise reclaim/complete the
operation) before returning std::noop_coroutine(); this mirrors the cancel()
claim semantics and prevents stuck ops—look for the connect handling around
op.perform_io(), desc_state_.connect_op and the cancel()/op.cancelled logic to
copy the behavior exactly.
🧹 Nitpick comments (1)
src/corosio/src/detail/epoll/sockets.cpp (1)
187-205: Consider extracting the duplicated retry-loop logic into a helper.All three retry loops (connect, read, write) follow an identical structure:
for(;;)→perform_io()→ check errn → post/finish or re-check readiness → park or continue. The only differences are the readiness flag name (write_ready/read_ready) and the op slot (connect_op/read_op/write_op). A small template or lambda helper taking the flag and slot as parameters would eliminate the triplication and reduce the risk of one path diverging from the others (as demonstrated by the cancellation gap above).Also applies to: 287-305, 376-394
|
GCOVR code coverage report https://116.corosio.prtest3.cppalliance.org/gcovr/index.html Build time: 2026-02-10 01:54:13 UTC |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/corosio/src/detail/epoll/scheduler.cpp`:
- Around line 238-255: The error-only drain currently runs only when err && !(ev
& (EPOLLIN | EPOLLOUT)) which can leave write/connect ops stranded if EPOLLERR
arrives with partial direction flags; change the logic that handles err to
unconditionally drain and complete any pending read_op, write_op, and connect_op
when err is set (i.e., check if (err) and for each of read_op, write_op,
connect_op call complete(err, 0) and push via std::exchange as done today), so
all directions are cleared defensively while preserving the existing completion
semantics and use of local_ops.
Move perform_io() calls inside the per-descriptor mutex in both the scheduler dispatch (descriptor_state::operator()()) and the initiator perform-now paths (connect, do_read_io, do_write_io, accept). This eliminates race windows by construction, removing the 3-phase lock-claim/unlock-IO/lock-repark pattern, the perform_now boolean, and separate post-park cancel re-checks.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## develop #116 +/- ##
===========================================
+ Coverage 79.70% 80.14% +0.43%
===========================================
Files 65 65
Lines 5661 5640 -21
===========================================
+ Hits 4512 4520 +8
+ Misses 1149 1120 -29
... and 3 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
Summary by CodeRabbit
Bug Fixes
Chores