diff --git a/docs/design/qutexes.md b/docs/design/qutexes.md index 0648d11..935feb7 100644 --- a/docs/design/qutexes.md +++ b/docs/design/qutexes.md @@ -374,12 +374,17 @@ public: */ if (nRequiredLocks == 1) { + bool ret=false; + if (tryingLockvoker == &queue.front()) { currOwner = tryingLockvoker; - lock.release(); - return true; + ret = true; } + + ret = false; + lock.release(); + return ret; } auto rIt = queue.rbegin(); @@ -494,6 +499,22 @@ public: lock.release(); + /** EXPLANATION: + * Why should this never happen? Well, if we were at the front of the queue + * and we failed to acquire the lock, we should have been rotated away from + * the front. On the other hand, if we were not at the front of the queue + * and we failed to acquire the lock, then we weren't at the front of the + * queue to begin with. + * The exception is if the queue has only one item in it. + * + * Hence there ought to be no way for the failedAcquirer to be at the front + * of the queue at this point UNLESS the queue has only one item in it. + */ + if (newFront == failedAcquirer && nQItems > 1) + { + throw; + } + /** EXPLANATION: * We should always awaken whoever is at the front of the queue, even if * we didn't rotate. Why? Consider this scenario: @@ -521,7 +542,7 @@ public: * itself. This can happen if, for example a multi-locking lockvoker * is backing off of a qutex within which it's the only waiter. */ - if (newFront != failedAcquirer) { + if (nQItems > 1) { wakeUp(newFront); } }