Add quitter<T> stop-aware task type#237
Conversation
quitter<T> is a coroutine task type identical to task<T> except it provides transparent cancellation. When the stop token is triggered, transform_awaiter::await_resume intercepts the stop before the coroutine body sees the result, throwing a sentinel exception that unwinds through RAII destructors to final_suspend. The coroutine author writes zero cancellation-handling code. New files: - quitter.hpp: quitter<T> class template - detail/stop_requested_exception.hpp: sentinel exception type - test/unit/quitter.cpp: 17 tests covering normal completion, exception propagation, stop interception at initial_suspend and during I/O, chain propagation, RAII verification, when_all/when_any integration with quitter children, timer cancellation, echo server shutdown, task/quitter mixing, and move semantics - example/quitter-shutdown: 4 concurrent workers doing simulated I/O, Ctrl+C stops all workers, RAII cleanup runs, shutdown latency printed (~100us) Modified: - run_async.hpp: fix task frame leak in make_trampoline by moving destroy before invoke (prevents leak when invoke throws) - capy.hpp: add quitter.hpp include Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughThe changes introduce Changes
Sequence Diagram(s)sequenceDiagram
participant User as User/Signal
participant SigHandler as Signal Handler
participant StopSrc as stop_source
participant Workers as Worker Coroutines
participant StopToken as stop_token
participant Resources as resource_guard
participant Main as main()
User ->> SigHandler: SIGINT/SIGTERM
SigHandler ->> StopSrc: request_stop()
StopSrc ->> StopToken: marks stop requested
Workers ->> StopToken: check stop_requested() at suspension
alt Stop Requested
Workers ->> Workers: throw stop_requested_exception
Workers ->> Resources: destructor (cleanup)
Resources ->> Main: increment cleanup_count
Workers ->> Main: coroutine completes
else Continue
Workers ->> Workers: co_await delay(...)
Workers ->> Workers: process work
end
Main ->> Main: latch.wait() for all workers
Main ->> Main: print results & latency
Estimated Code Review Effort🎯 4 (Complex) | ⏱️ ~60 minutes 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)
📝 Coding Plan
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 Tip You can make CodeRabbit's review stricter and more nitpicky using the `assertive` profile, if that's what you prefer.Change the |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
include/boost/capy/quitter.hpp (1)
71-84: Consider adding a usage example to the class javadoc.Per coding guidelines, type documentation should include
@par Examplewith a code block showing typical usage. A brief snippet would help users understand the stop-token integration pattern.📝 Suggested addition
`@par` Example `@code` capy::quitter<int> fetch_data() { auto [ec, data] = co_await async_read(...); // If stop_token triggered, we never reach here — RAII runs. co_return process(data); } // Launch with stop token std::stop_source src; run_async(ex, src.get_token())(fetch_data()); // Later: src.request_stop(); `@endcode`🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@include/boost/capy/quitter.hpp` around lines 71 - 84, Add a short usage example to the quitter<T> class javadoc by appending an "@par Example" section that demonstrates typical stop-token integration: show a minimal coroutine function returning capy::quitter<int> (or quitter<> for void) that uses co_await (e.g., awaiting async_read) and co_return, and show launching it with a std::stop_source and passing src.get_token() to the runner; reference the class name quitter and its promise_type/stop-token behavior in the prose so readers can correlate the example with the documented stopped behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@include/boost/capy/quitter.hpp`:
- Around line 71-84: Add a short usage example to the quitter<T> class javadoc
by appending an "@par Example" section that demonstrates typical stop-token
integration: show a minimal coroutine function returning capy::quitter<int> (or
quitter<> for void) that uses co_await (e.g., awaiting async_read) and
co_return, and show launching it with a std::stop_source and passing
src.get_token() to the runner; reference the class name quitter and its
promise_type/stop-token behavior in the prose so readers can correlate the
example with the documented stopped behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: d42c9dba-185f-42ea-9f09-eb754c590100
⛔ Files ignored due to path filters (1)
test/unit/quitter.cppis excluded by!**/test/**
📒 Files selected for processing (7)
example/CMakeLists.txtexample/quitter-shutdown/CMakeLists.txtexample/quitter-shutdown/quitter_shutdown.cppinclude/boost/capy.hppinclude/boost/capy/detail/stop_requested_exception.hppinclude/boost/capy/ex/run_async.hppinclude/boost/capy/quitter.hpp
|
An automated preview of the documentation is available at https://237.capy.prtest3.cppalliance.org/index.html If more commits are pushed to the pull request, the docs will rebuild at the same URL. 2026-03-19 22:41:52 UTC |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #237 +/- ##
===========================================
+ Coverage 92.11% 92.39% +0.28%
===========================================
Files 166 168 +2
Lines 9144 9327 +183
===========================================
+ Hits 8423 8618 +195
+ Misses 721 709 -12
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 7 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
quitter is a coroutine task type identical to task except it provides transparent cancellation. When the stop token is triggered, transform_awaiter::await_resume intercepts the stop before the coroutine body sees the result, throwing a sentinel exception that unwinds through RAII destructors to final_suspend. The coroutine author writes zero cancellation-handling code.
New files:
Modified:
Summary by CodeRabbit
New Features
quittercoroutine task type enabling responsive shutdown with automatic stop-token awareness, allowing coroutines to cleanly terminate when stop is requestedBug Fixes