Skip to content

refactor: give up all work in shutdown() and destroy services once - #463

Merged
sgerbino merged 1 commit into
cppalliance:developfrom
sgerbino:pr/shutdown-once
Oct 20, 2026
Merged

sgerbino merged 1 commit into
cppalliance:developfrom
sgerbino:pr/shutdown-once

Conversation

@sgerbino

@sgerbino sgerbino commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

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 repeat destroy():

  • thread_pool and blocking_context drain until the queue is empty, destroy the services once, and drain once more for stray work a destructor posts anyway.
  • No service may be created after destroy() returns, since ~execution_context would destroy it after the derived context's members. Debug builds now assert this. The repeated destroy() 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 in shutdown(); a service's own thread posting during shutdown() is fully drained.

Resolves #461

@cppalliance-bot

cppalliance-bot commented Oct 19, 2026 •

Copy link
Copy Markdown

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

@cppalliance-bot

cppalliance-bot commented Oct 19, 2026 •

Copy link
Copy Markdown

GCOVR code coverage report https://463.capy.prtest3.cppalliance.org/gcovr/index.html
LCOV code coverage report https://463.capy.prtest3.cppalliance.org/genhtml/index.html
Coverage Diff Report https://463.capy.prtest3.cppalliance.org/diff-report/index.html

Build time: 2026-10-20 15:15:19 UTC

@codecov

codecov Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.46%. Comparing base (ef63862) to head (0a38296).
⚠️ Report is 3 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@             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     
Flag Coverage Δ
linux 98.46% <ø> (+0.05%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
include/boost/capy/ex/execution_context.hpp 100.00% <ø> (ø)
include/boost/capy/ex/thread_pool.hpp 100.00% <ø> (ø)
src/ex/execution_context.cpp 100.00% <100.00%> (ø)
src/ex/thread_pool.cpp 99.33% <100.00%> (-0.01%) ⬇️
src/test/run_blocking.cpp 97.64% <100.00%> (-0.06%) ⬇️

... and 6 files with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ef63862...0a38296. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

mvandeberg
mvandeberg previously approved these changes Oct 19, 2026
@sgerbino
sgerbino force-pushed the pr/shutdown-once branch 3 times, most recently from 6c32731 to 57445a8 Compare October 20, 2026 14:35
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.
@sgerbino
sgerbino merged commit 61f6ddc into cppalliance:develop Oct 20, 2026
41 checks passed
@sgerbino
sgerbino deleted the pr/shutdown-once branch October 20, 2026 17:32
@github-project-automation github-project-automation Bot moved this from Backlog to Done in Beast2 Oct 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Give up all work in shutdown() and destroy services once

3 participants