mirror of
https://github.com/latentPrion/libspinscale.git
synced 2026-06-23 19:48:32 +00:00
Nursery: Don't pass exceptions to main loop
This commit is contained in:
@@ -190,11 +190,10 @@ nursery.openAdmission();
|
|||||||
|
|
||||||
auto lease = nursery.getNewSlotLease();
|
auto lease = nursery.getNewSlotLease();
|
||||||
lease.getSyncCanceler().startAcceptingWork();
|
lease.getSyncCanceler().startAcceptingWork();
|
||||||
std::exception_ptr &exceptionStorage = lease.getExceptionStorage();
|
|
||||||
lease.setOnSettledHook(
|
lease.setOnSettledHook(
|
||||||
[&exceptionStorage]()
|
[](std::exception_ptr &exceptionPtr)
|
||||||
{
|
{
|
||||||
sscl::co::NonViralCompletion nvc(exceptionStorage);
|
sscl::co::NonViralCompletion nvc(exceptionPtr);
|
||||||
nvc.checkAndRethrowException();
|
nvc.checkAndRethrowException();
|
||||||
});
|
});
|
||||||
lease.fillSlot(
|
lease.fillSlot(
|
||||||
@@ -221,10 +220,9 @@ all slots have retired naturally and throw if admission is still open.
|
|||||||
`Slot::Lease` is commit-required: an uncommitted lease removes its reservation on
|
`Slot::Lease` is commit-required: an uncommitted lease removes its reservation on
|
||||||
destruction. `fillSlot()` takes an invoker factory (deferred construction) because
|
destruction. `fillSlot()` takes an invoker factory (deferred construction) because
|
||||||
non-viral coroutines may complete synchronously during invoker construction.
|
non-viral coroutines may complete synchronously during invoker construction.
|
||||||
The factory may capture `lease` by reference; `setOnSettledHook()` may not.
|
The factory may capture `lease` by reference; `setOnSettledHook()` may not
|
||||||
The hook runs after the lease is destroyed, so capture slot-owned state such as
|
capture `lease` itself. The nursery passes the slot's `exceptionPtr` into the
|
||||||
`lease.getExceptionStorage()` (a reference to the slot's `exceptionPtr`), not
|
hook at retirement.
|
||||||
`lease` itself.
|
|
||||||
`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.
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <iostream>
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
@@ -116,7 +115,8 @@ public:
|
|||||||
sscl::SyncCancelerForAsyncWork &getSyncCanceler()
|
sscl::SyncCancelerForAsyncWork &getSyncCanceler()
|
||||||
{ return slot.syncCanceler; }
|
{ return slot.syncCanceler; }
|
||||||
|
|
||||||
void setOnSettledHook(std::function<void()> hook)
|
void setOnSettledHook(
|
||||||
|
std::function<void(std::exception_ptr &exceptionPtr)> hook)
|
||||||
{
|
{
|
||||||
if (slot.leaseStatus != SlotLeaseStatus::RESERVED)
|
if (slot.leaseStatus != SlotLeaseStatus::RESERVED)
|
||||||
{
|
{
|
||||||
@@ -214,7 +214,7 @@ public:
|
|||||||
std::exception_ptr exceptionPtr = nullptr;
|
std::exception_ptr exceptionPtr = nullptr;
|
||||||
sscl::SyncCancelerForAsyncWork syncCanceler;
|
sscl::SyncCancelerForAsyncWork syncCanceler;
|
||||||
std::unique_ptr<detail::MemberInvokerBase> memberInvoker;
|
std::unique_ptr<detail::MemberInvokerBase> memberInvoker;
|
||||||
std::function<void()> onSettledHook;
|
std::function<void(std::exception_ptr &exceptionPtr)> onSettledHook;
|
||||||
};
|
};
|
||||||
|
|
||||||
void openAdmission()
|
void openAdmission()
|
||||||
@@ -411,6 +411,8 @@ private:
|
|||||||
void retireSlot(Slot &slot)
|
void retireSlot(Slot &slot)
|
||||||
{
|
{
|
||||||
std::function<void()> waiterToInvoke;
|
std::function<void()> waiterToInvoke;
|
||||||
|
std::function<void(std::exception_ptr &exceptionPtr)> onSettledHook;
|
||||||
|
std::exception_ptr settledExceptionPtr;
|
||||||
|
|
||||||
{
|
{
|
||||||
sscl::SpinLock::Guard guard(s.lock);
|
sscl::SpinLock::Guard guard(s.lock);
|
||||||
@@ -430,33 +432,23 @@ private:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
settledExceptionPtr = slot.exceptionPtr;
|
||||||
if (slot.onSettledHook) { slot.onSettledHook(); }
|
if (settledExceptionPtr) {
|
||||||
}
|
|
||||||
catch (const std::exception &e)
|
|
||||||
{
|
|
||||||
std::cerr
|
|
||||||
<< "NonViralTaskNursery: onSettled hook exception: "
|
|
||||||
<< e.what() << std::endl;
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
std::cerr
|
|
||||||
<< "NonViralTaskNursery: onSettled hook unknown exception"
|
|
||||||
<< std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (slot.exceptionPtr) {
|
|
||||||
slot.settlementStatus = SlotSettlementStatus::EXCEPTION_THROWN;
|
slot.settlementStatus = SlotSettlementStatus::EXCEPTION_THROWN;
|
||||||
} else {
|
} else {
|
||||||
slot.settlementStatus = SlotSettlementStatus::COMPLETED;
|
slot.settlementStatus = SlotSettlementStatus::COMPLETED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onSettledHook = std::move(slot.onSettledHook);
|
||||||
slot.leaseStatus = SlotLeaseStatus::RETIRED;
|
slot.leaseStatus = SlotLeaseStatus::RETIRED;
|
||||||
slot.memberInvoker.reset();
|
slot.memberInvoker.reset();
|
||||||
waiterToInvoke = takeDrainWaiterIfDrainedUnlocked();
|
waiterToInvoke = takeDrainWaiterIfDrainedUnlocked();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (onSettledHook) {
|
||||||
|
onSettledHook(settledExceptionPtr);
|
||||||
|
}
|
||||||
|
|
||||||
if (waiterToInvoke) { waiterToInvoke(); }
|
if (waiterToInvoke) { waiterToInvoke(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user