bool LockerImpl<IsForMMAPV1>::unlock(ResourceId resId) { LockRequestsMap::Iterator it = _requests.find(resId); if (inAWriteUnitOfWork() && shouldDelayUnlock(it.key(), (it->mode))) { _resourcesToUnlockAtEndOfUnitOfWork.push(it.key()); return false; } return _unlockImpl(&it); }
bool LockerImpl<IsForMMAPV1>::unlock(ResourceId resId) { LockRequestsMap::Iterator it = _requests.find(resId); if (inAWriteUnitOfWork() && _shouldDelayUnlock(it.key(), (it->mode))) { if (!it->unlockPending) { _numResourcesToUnlockAtEndUnitOfWork++; } it->unlockPending++; // unlockPending will only be incremented if a lock is converted and unlock() is called // multiple times on one ResourceId. invariant(it->unlockPending < LockModesCount); return false; } // Don't attempt to unlock twice. This can happen when an interrupted global lock is destructed. if (it.finished()) return false; return _unlockImpl(&it); }
bool LockerImpl<IsForMMAPV1>::unlockGlobal() { if (!unlock(resourceIdGlobal)) { return false; } invariant(!inAWriteUnitOfWork()); LockRequestsMap::Iterator it = _requests.begin(); while (!it.finished()) { // If we're here we should only have one reference to any lock. It is a programming // error for any lock used with multi-granularity locking to have more references than // the global lock, because every scope starts by calling lockGlobal. if (it.key().getType() == RESOURCE_GLOBAL || it.key().getType() == RESOURCE_MUTEX) { it.next(); } else { invariant(_unlockImpl(&it)); } } return true; }