SerialAsyncContin/LockSet: add releaseQutexEarly()

This method allows us to avoid double-release()ing qutexes when we
want to release a qutex early. If we don't use releaseQutexEarly(),
then inside of callOriginalCb when LockSet::release is called, the
Qutex will be release()d a second time.
This commit is contained in:
2025-09-30 22:47:54 -04:00
parent 7ddbde1a2f
commit eb7fe11de4
2 changed files with 59 additions and 17 deletions
+12 -5
View File
@@ -43,6 +43,13 @@ public:
std::unique_ptr<std::forward_list<std::reference_wrapper<Qutex>>>
getAcquiredQutexHistory() const;
/**
* @brief Release a specific qutex early
* @param qutex The qutex to release early
*/
void releaseQutexEarly(Qutex &qutex)
{ requiredLocks.releaseQutexEarly(qutex); }
public:
LockSet<OriginalCbFnT> requiredLocks;
std::atomic<bool> isAwakeOrBeingAwakened{false};
@@ -109,7 +116,7 @@ public:
getLockvokerIteratorForQutex(Qutex& qutex) const override
{
return serializedContinuation.requiredLocks.getLockUsageDesc(
qutex).second;
qutex).iterator;
}
/**
@@ -133,7 +140,7 @@ public:
Qutex& getLockAt(size_t index) const override
{
return serializedContinuation.requiredLocks.locks[index]
.first.get();
.qutex.get();
}
private:
@@ -211,9 +218,9 @@ public:
: serializedContinuation.requiredLocks.locks)
{
if (traceContinuationHistoryForDeadlockOn(
lockUsageDesc.first.get()))
lockUsageDesc.qutex.get()))
{
return std::ref(lockUsageDesc.first.get());
return std::ref(lockUsageDesc.qutex.get());
}
}
return std::nullopt;
@@ -289,7 +296,7 @@ const
// Add this continuation's locks to the held locks list
for (size_t i = 0; i < serializedCont->requiredLocks.locks.size(); ++i)
{
heldLocks->push_front(serializedCont->requiredLocks.locks[i].first);
heldLocks->push_front(serializedCont->requiredLocks.locks[i].qutex);
}
}