Repository navigation
refactor: give up all work in shutdown() and destroy services once - #463
Conversation
|
An automated preview of the documentation is available at https://463.capy.prtest3.cppalliance.org/index.html If more commits are pushed to the pull request, the docs will rebuild at the same URL. 2026-10-20 15:04:34 UTC |
|
GCOVR code coverage report https://463.capy.prtest3.cppalliance.org/gcovr/index.html Build time: 2026-10-20 15:15:19 UTC |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #463 +/- ##
===========================================
+ Coverage 98.43% 98.46% +0.02%
===========================================
Files 137 137
Lines 7297 7293 -4
===========================================
- Hits 7183 7181 -2
+ Misses 114 112 -2
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 6 files with indirect coverage changes Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
b722f6e to
f2578fb
Compare
6c32731 to
57445a8
Compare
A context's destructor repeated destroy() and its drain until the drain found nothing, so a service could post from its destructor at any depth and the context still cleaned up after it. Services now give up all their work in shutdown(), joining any threads they own there, and do not post from their destructors. thread_pool and blocking_context drain until the queue is empty, which also takes the work of any service an unwound chain creates, since it is shut down as it is created. They then destroy the services once, and drain one last time for stray work a destructor posts anyway. No service may be created after destroy() returns: ~execution_context would destroy it after the derived context's members it may still reach. Debug builds now check this. The service documentation said shutdown() must not block; it now allows joining the service's own threads. The execution_context documentation, the custom executor guide and the two executor examples describe the same order.
57445a8 to
0a38296
Compare
Services now give up all their work in
shutdown()and do not post from their destructors. With that rule, a context's teardown no longer needs to repeatdestroy():thread_poolandblocking_contextdrain until the queue is empty, destroy the services once, and drain once more for stray work a destructor posts anyway.destroy()returns, since~execution_contextwould destroy it after the derived context's members. Debug builds now assert this. The repeateddestroy()used to tolerate service destructors posting at any depth; that is no longer supported.shutdown()may block to wait for work the service already started, such as threads it owns or operations it submitted to the system. The docs said it must not block, which contradicted giving up all work.Services that follow the rule tear down exactly as before. This is a contract change, not a behavior fix; cppalliance/corosio#401 relies on it.
Tests: work given up by a service created during the drain is destroyed before the earlier services; creating a service after
destroy(), including through nested destructor posts, aborts in debug builds; the strand service gives up every queue inshutdown(); a service's own thread posting duringshutdown()is fully drained.Resolves #461