Nursery: Capture onSettledCb before fillSlot in launch()

This commit is contained in:
2026-06-09 10:55:33 -04:00
parent 5689ac3914
commit 656aae37c8
2 changed files with 22 additions and 18 deletions
+15 -17
View File
@@ -188,23 +188,19 @@ entry from ordinary code (HTTP handlers, timers, shutdown sequences), not for
sscl::co::NonViralTaskNursery nursery; sscl::co::NonViralTaskNursery nursery;
nursery.openAdmission(); nursery.openAdmission();
auto lease = nursery.getNewSlotLease(); nursery.launch(
lease.getSyncCanceler().startAcceptingWork(); [](sscl::co::NonViralTaskNursery::Slot::Lease &lease)
lease.setOnSettledHook(
[](std::exception_ptr &exceptionPtr)
{
sscl::co::NonViralCompletion nvc(exceptionPtr);
nvc.checkAndRethrowException();
});
lease.fillSlot(
[&lease]()
{ {
return component.someNonViralCReq( return component.someNonViralCReq(
lease.getExceptionStorage(), lease.getExceptionStorage(),
lease.getCallerLambda(), lease.getCallerLambda(),
lease.getSyncCanceler()); lease.getSyncCanceler());
},
[](std::exception_ptr &exceptionPtr)
{
sscl::co::NonViralCompletion nvc(exceptionPtr);
nvc.checkAndRethrowException();
}); });
lease.commit();
nursery.requestCancelOnAll(); nursery.requestCancelOnAll();
nursery.closeAdmission(); nursery.closeAdmission();
@@ -217,12 +213,14 @@ completion callbacks run. Call `closeAdmission()` explicitly before
`asyncAwaitAllSettlements()` or `syncAwaitAllSettlements()`; those APIs wait until `asyncAwaitAllSettlements()` or `syncAwaitAllSettlements()`; those APIs wait until
all slots have retired naturally and throw if admission is still open. all slots have retired naturally and throw if admission is still open.
`Slot::Lease` is commit-required: an uncommitted lease removes its reservation on `launch(factory, onSettledHook)` registers a non-null hook before `fillSlot()`.
destruction. `fillSlot()` takes an invoker factory (deferred construction) because Omit the hook (default `nullptr`) when no settlement callback is needed.
non-viral coroutines may complete synchronously during invoker construction. `Slot::Lease` is commit-required: an uncommitted lease removes its
The factory may capture `lease` by reference; `setOnSettledHook()` may not reservation on destruction. `fillSlot()` takes an invoker factory (deferred
capture `lease` itself. The nursery passes the slot's `exceptionPtr` into the construction) because non-viral coroutines may complete synchronously during
hook at retirement. invoker construction. The factory may capture `lease` by reference;
`setOnSettledHook()` and the hook passed to `launch()` may not capture `lease`
itself. The nursery passes the slot's `exceptionPtr` into the hook at retirement.
`Slot::Handle` is an opaque slot pointer valid only while the slot remains in the `Slot::Handle` is an opaque slot pointer valid only while the slot remains in the
nursery. nursery.
+7 -1
View File
@@ -343,10 +343,16 @@ public:
} }
template <class InvokerFactory> template <class InvokerFactory>
Slot::Handle launch(InvokerFactory &&factory) Slot::Handle launch(
InvokerFactory &&factory,
std::function<void(std::exception_ptr &exceptionPtr)> onSettledHook =
nullptr)
{ {
auto lease = getNewSlotLease(); auto lease = getNewSlotLease();
lease.getSyncCanceler().startAcceptingWork(); lease.getSyncCanceler().startAcceptingWork();
if (onSettledHook) {
lease.setOnSettledHook(std::move(onSettledHook));
}
lease.fillSlot( lease.fillSlot(
[&factory, &lease]() [&factory, &lease]()
{ {