kqueue/epoll: make cancel() reliable when ops complete inline#132
kqueue/epoll: make cancel() reliable when ops complete inline#132sgerbino merged 1 commit intocppalliance:developfrom
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds per-descriptor deferred-cancellation flags and integrates them into epoll and kqueue read/write and cancel paths so cancellations requested when an operation isn't currently parked are recorded and applied when the next operation parks or advances. Changes
Sequence Diagram(s)sequenceDiagram
participant Caller
participant Descriptor as descriptor_state
participant Op
participant Scheduler
Caller->>Descriptor: cancel(read/write) -- op not parked
Descriptor-->>Descriptor: set read_cancel_pending / write_cancel_pending
Note right of Descriptor: pending flag recorded
Caller->>Op: submit read/write op
Op->>Descriptor: park (desc_state_.read_op / write_op = &op)
Descriptor-->>Op: detect pending flag, clear flag
Op->>Op: mark cancelled
Op->>Scheduler: post cancelled op / signal completion
Scheduler->>Caller: resume with cancelled result
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches🧪 Generate unit tests (beta)
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 |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #132 +/- ##
===========================================
+ Coverage 80.81% 81.21% +0.39%
===========================================
Files 64 64
Lines 5557 5685 +128
===========================================
+ Hits 4491 4617 +126
- Misses 1066 1068 +2
... and 11 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
|
An automated preview of the documentation is available at https://132.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-12 17:16:10 UTC |
|
GCOVR code coverage report https://132.corosio.prtest3.cppalliance.org/gcovr/index.html Build time: 2026-02-11 23:16:25 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 270-276: The epoll cancel_pending code paths clear the pending
flag and post the op without marking it cancelled, causing EOF instead of
cancelled for a subsequent operation; update each cancel_pending consumption
site that uses desc_state_.read_cancel_pending /
desc_state_.write_cancel_pending (the four occurrences around the read/write
cancel handling) to call op.request_cancel() (or set op.cancelled.store(true,
...)) before svc_.post(&op) and svc_.work_finished() so the posted operation is
correctly marked cancelled (mirror the kqueue do_read_io behavior).
- Around line 705-712: The cancel path currently sets
desc_state_.read_cancel_pending/write_cancel_pending unconditionally (e.g., in
cancel() where it checks read_op != &rd_ and write_op != &wr_), causing stale
pending flags to leak to later operations; update the logic to only set the
pending flag when the operation is actually parked (guard with a check that
desc_state_.read_op != nullptr / desc_state_.write_op != nullptr before setting
read_cancel_pending/write_cancel_pending) and also clear any pending flags at
the start of new operations in read_some and write_some (after acquiring the
same mutex) so a previously set flag cannot spuriously cancel an unrelated
subsequent op; apply the same fix to cancel_single_op() and ensure the rd_/wr_
claim paths still exchange and preserve behavior.
In `@src/corosio/src/detail/kqueue/sockets.cpp`:
- Around line 713-720: The else branches unconditionally set
desc_state_.read_cancel_pending / desc_state_.write_cancel_pending whenever
read_op != &rd_ or write_op != &wr_, which can mark a cancel for a future
unrelated operation; instead only set those cancel_pending flags if there is an
active operation to cancel (i.e. when the operation slot actually holds a
different op), or clear/reset the flags at the start of a new operation; locate
the logic around desc_state_, compare read_op and write_op against rd_ and wr_
(and the rd_claimed/wr_claimed handling) and change the else paths to check that
an operation is present before setting read_cancel_pending/write_cancel_pending,
or ensure do_read_io/do_write_io clear the pending flags at operation start to
avoid consuming a stale flag.
389e374 to
c28a986
Compare
Add cancel_pending flags to descriptor_state so cancellation intent persists across speculative I/O completions, matching IOCP's CancelIoEx semantics. Symmetry
c28a986 to
ca7de00
Compare
Add cancel_pending flags to descriptor_state so cancellation intent persists across speculative I/O completions, matching IOCP's CancelIoEx semantics. Removes the shutdown(SHUT_WR) workaround from fc73eee.
Summary by CodeRabbit