Lockvoker: Add registerInLockSet

We now create the sh_ptr to the copy of a lockvoker object in its
own supplied register method. This enables us to retain type safety
when calling make_shared, by copying the most derived version of
the lockvoker object. Then we can pass in the LockerAndInvokerBase
to the rest of the call chain.
This commit is contained in:
2025-09-30 02:55:25 -04:00
parent 08122c086c
commit ca9eae197f
3 changed files with 17 additions and 9 deletions
+1 -2
View File
@@ -74,9 +74,8 @@ public:
* cleaned up in the qutexQ's std::list destructor -- and that won't * cleaned up in the qutexQ's std::list destructor -- and that won't
* execute any fancy cleanup logic. It'll just clear() out the list. * execute any fancy cleanup logic. It'll just clear() out the list.
*/ */
template <class InvocationTargetT>
void registerInQutexQueues( void registerInQutexQueues(
const typename SerializedAsynchronousContinuation<OriginalCbFnT>::template LockerAndInvoker<InvocationTargetT> &lockvoker); const std::shared_ptr<LockerAndInvokerBase> &lockvoker);
/** /**
* @brief Try to acquire all locks in order; back off if acquisition fails * @brief Try to acquire all locks in order; back off if acquisition fails
+14 -1
View File
@@ -253,6 +253,19 @@ public:
void allowAwakening() void allowAwakening()
{ serializedContinuation.isAwakeOrBeingAwakened.store(false); } { serializedContinuation.isAwakeOrBeingAwakened.store(false); }
/** EXPLANATION:
* Creates a shared_ptr copy of this lockvoker and registers it with
* the serialized continuation's LockSet.
*/
void registerInLockSet()
{
auto sharedLockvoker = std::make_shared<
LockerAndInvoker<InvocationTargetT>>(*this);
serializedContinuation.requiredLocks.registerInQutexQueues(
sharedLockvoker);
}
/** /**
* @brief First wake - register in queues and awaken * @brief First wake - register in queues and awaken
* *
@@ -263,7 +276,7 @@ public:
void firstWake() void firstWake()
{ {
serializedContinuation.isAwakeOrBeingAwakened.store(true); serializedContinuation.isAwakeOrBeingAwakened.store(true);
serializedContinuation.requiredLocks.registerInQutexQueues(*this); registerInLockSet();
// Force awaken since we just set the flag above // Force awaken since we just set the flag above
awaken(true); awaken(true);
} }
+2 -6
View File
@@ -7,9 +7,8 @@ namespace smo {
// These will be explicitly instantiated for the types we need // These will be explicitly instantiated for the types we need
template <class OriginalCbFnT> template <class OriginalCbFnT>
template <class InvocationTargetT>
void LockSet<OriginalCbFnT>::registerInQutexQueues( void LockSet<OriginalCbFnT>::registerInQutexQueues(
const typename SerializedAsynchronousContinuation<OriginalCbFnT>::template LockerAndInvoker<InvocationTargetT> &lockvoker const std::shared_ptr<LockerAndInvokerBase> &lockvoker
) )
{ {
/** EXPLANATION: /** EXPLANATION:
@@ -34,13 +33,10 @@ void LockSet<OriginalCbFnT>::registerInQutexQueues(
* io_service, potentially without being executed if they fail to * io_service, potentially without being executed if they fail to
* acquire all locks. * acquire all locks.
*/ */
auto sharedLockvoker = std::make_shared<
typename SerializedAsynchronousContinuation<OriginalCbFnT>::template LockerAndInvoker<InvocationTargetT>>(lockvoker);
for (auto& lockUsageDesc : locks) for (auto& lockUsageDesc : locks)
{ {
lockUsageDesc.second = lockUsageDesc.first.get().registerInQueue( lockUsageDesc.second = lockUsageDesc.first.get().registerInQueue(
sharedLockvoker); lockvoker);
} }
registeredInQutexQueues = true; registeredInQutexQueues = true;