_Lock addLock(long indexId, byte[] key) { _Lock lock = new _Lock(); lock.mIndexId = indexId; lock.mKey = key; lock.mHashCode = _LockManager.hash(indexId, key); lock.mLockManagerNext = mTopLock; mTopLock = lock; return lock; }
deleteGhost(latch); mOwner = null; LatchCondition queueU = mQueueU; addSharedLockOwner(count, locker); } else { addSharedLockOwner(0, locker); LatchCondition queueSX = mQueueSX; if (queueSX != null) { } else if (mLockCount == 0 || !isSharedLockOwner(locker)) { throw new IllegalStateException("_Lock not held");
private void addSharedLockOwner(int count, _LockOwner locker) { count++; Object sharedObj = mSharedLockOwnersObj; if (sharedObj == null) { mSharedLockOwnersObj = locker; } else if (sharedObj instanceof LockOwnerHTEntry[]) { LockOwnerHTEntry[] entries = (LockOwnerHTEntry[]) sharedObj; lockerHTadd(entries, count & 0x7fffffff, locker); } else { // Initial capacity of must be a power of 2. LockOwnerHTEntry[] entries = new LockOwnerHTEntry[8]; lockerHTadd(entries, (_LockOwner) sharedObj); lockerHTadd(entries, locker); mSharedLockOwnersObj = entries; } mLockCount = count; }
/** * @return ACQUIRED, OWNED_SHARED, or null */ private LockResult tryLockShared(_LockOwner locker) { int count = mLockCount; if (count == ~0) { return null; } if (count != 0 && isSharedLockOwner(locker)) { return OWNED_SHARED; } if ((count & 0x7fffffff) >= 0x7ffffffe) { throw new IllegalStateException("Too many shared locks held"); } addSharedLockOwner(count, locker); return ACQUIRED; }
/** * Called with exclusive latch held, which is retained. * * @param latch briefly released and re-acquired for deleting a ghost * @throws IllegalStateException if lock not held */ void unlockToUpgradable(_LockOwner locker, Latch latch) { if (mOwner != locker) { String message = "Exclusive or upgradable lock not held"; if (mLockCount == 0 || !isSharedLockOwner(locker)) { message = "_Lock not held"; } throw new IllegalStateException(message); } if (mLockCount != ~0) { // Already upgradable. return; } deleteGhost(latch); mLockCount = 0x80000000; LatchCondition queueSX = mQueueSX; if (queueSX != null) { queueSX.signalShared(); } }
int index = hash & (entries.length - 1); for (lock = entries[index]; lock != null; lock = lock.mLockManagerNext) { if (lock.matches(indexId, key, hash)) { if (type == TYPE_SHARED) { result = lock.tryLockShared(this, locker, nanosTimeout); break lockNonEx; } else if (type == TYPE_UPGRADABLE) { result = lock.tryLockUpgradable(this, locker, nanosTimeout); break lockNonEx; } else { result = lock.tryLockExclusive(this, locker, nanosTimeout); break lockEx; lock = new _Lock();
deleteGhost(latch); addSharedLockOwner(count, locker); } else { addSharedLockOwner(0, locker); LatchCondition queueSX = mQueueSX; if (queueSX != null) { return; } else if ((mLockCount == 0 || !isSharedLockOwner(locker)) && !isClosed(locker)) { throw new IllegalStateException("Lock not held");
deleteGhost(ht); } else if (sharedObj instanceof LockOwnerHTEntry[]) { LockOwnerHTEntry[] entries = (LockOwnerHTEntry[]) sharedObj; if (lockerHTremove(entries, locker)) { if (count == 2) { mSharedLockOwnersObj = lockerHTgetOne(entries); if (isClosed(locker)) { ht.releaseExclusive(); return;
deleteGhost(latch); mOwner = null; LatchCondition queueU = mQueueU; } else if (sharedObj instanceof LockOwnerHTEntry[]) { LockOwnerHTEntry[] entries = (LockOwnerHTEntry[]) sharedObj; if (lockerHTremove(entries, locker)) { if (count == 2) { mSharedLockOwnersObj = lockerHTgetOne(entries);
/** * Called with exclusive latch held, which is released unless an exception is thrown. * * @param latch briefly released and re-acquired for deleting a ghost * @throws IllegalStateException if lock not held */ void unlockToUpgradable(_LockOwner locker, Latch latch) { if (mOwner != locker) { if (isClosed(locker)) { latch.releaseExclusive(); return; } String message = "Exclusive or upgradable lock not held"; if (mLockCount == 0 || !isSharedLockOwner(locker)) { message = "Lock not held"; } throw new IllegalStateException(message); } if (mLockCount != ~0) { // Already upgradable. latch.releaseExclusive(); return; } deleteGhost(latch); mLockCount = 0x80000000; LatchCondition queueSX = mQueueSX; if (queueSX == null || !queueSX.signalSharedRelease(latch)) { latch.releaseExclusive(); } }
/** * @param lockType TYPE_SHARED, TYPE_UPGRADABLE, or TYPE_EXCLUSIVE */ void detectDeadlock(_Locker locker, int lockType, long nanosTimeout) throws DeadlockException { _DeadlockDetector detector = new _DeadlockDetector(locker); if (detector.scan()) { Object att = findOwnerAttachment(locker, lockType); throw new DeadlockException(nanosTimeout, att, detector.mGuilty, detector.newDeadlockSet(lockType)); } }
/** * Finds or creates a lock. Caller must hold exclusive latch. */ _Lock lockAccess(long indexId, byte[] key, int hash) { _Lock[] entries = mEntries; int index = hash & (entries.length - 1); for (_Lock lock = entries[index]; lock != null; lock = lock.mLockManagerNext) { if (lock.matches(indexId, key, hash)) { return lock; } } if (mSize >= mGrowThreshold) { entries = rehash(entries); index = hash & (entries.length - 1); } _Lock lock = new _Lock(); lock.mIndexId = indexId; lock.mKey = key; lock.mHashCode = hash; lock.mLockManagerNext = entries[index]; // Fence so that the isAvailable method doesn't observe a broken chain. UNSAFE.storeFence(); entries[index] = lock; mSize++; return lock; }
if (mLockCount != 0 && isSharedLockOwner(locker)) { return OWNED_SHARED; LockResult r = tryLockShared(locker); if (r != null) { return r; LockResult r = tryLockShared(locker); if (r != null) { locker.mWaitingFor = null;
/** * Called with any latch held, which is retained. * * @return UNOWNED, OWNED_SHARED, OWNED_UPGRADABLE, or OWNED_EXCLUSIVE */ LockResult check(_LockOwner locker) { int count = mLockCount; return mOwner == locker ? (count == ~0 ? OWNED_EXCLUSIVE : OWNED_UPGRADABLE) : ((count != 0 && isSharedLockOwner(locker)) ? OWNED_SHARED : UNOWNED); }
if (waitingFor != null) { try { waitingFor.detectDeadlock(this, lockType, nanosTimeout); } finally { mWaitingFor = null; : waitingFor.findOwnerAttachment(this, lockType); return new LockTimeoutException(nanosTimeout, att);
private boolean isSharedLockOwner(_LockOwner locker) { Object sharedObj = mSharedLockOwnersObj; if (sharedObj == locker) { return true; } if (sharedObj instanceof LockOwnerHTEntry[]) { return lockerHTcontains((LockOwnerHTEntry[]) sharedObj, locker); } return false; }
final LockResult check(_LockOwner locker, long indexId, byte[] key, int hash) { LockHT ht = getLockHT(hash); ht.acquireShared(); try { _Lock lock = ht.lockFor(indexId, key, hash); return lock == null ? LockResult.UNOWNED : lock.check(locker); } finally { ht.releaseShared(); } }
/** * Returns true if a shared lock can be granted for the given key. Caller must hold the * node latch which contains the key. * * @param locker optional locker */ final boolean isAvailable(_LockOwner locker, long indexId, byte[] key, int hash) { // Note that no LockHT latch is acquired. The current thread is not required to // immediately observe the activity of other threads acting upon the same lock. If // another thread has just acquired an exclusive lock, it must still acquire the node // latch before any changes can be made. _Lock lock = getLockHT(hash).lockFor(indexId, key, hash); return lock == null ? true : lock.isAvailable(locker); }
int index = hash & (entries.length - 1); for (lock = entries[index]; lock != null; lock = lock.mLockManagerNext) { if (lock.matches(indexId, key, hash)) { if (type == TYPE_SHARED) { result = lock.tryLockShared(this, locker, nanosTimeout); break lockNonEx; } else if (type == TYPE_UPGRADABLE) { result = lock.tryLockUpgradable(this, locker, nanosTimeout); break lockNonEx; } else { result = lock.tryLockExclusive(this, locker, nanosTimeout); break lockEx; lock = new _Lock(); lock.setSharedLockOwner(locker); } else { lock.mOwner = locker;
deleteGhost(latch); addSharedLockOwner(count, locker); } else { addSharedLockOwner(0, locker); LatchCondition queueSX = mQueueSX; if (queueSX != null) { return; } else if ((mLockCount == 0 || !isSharedLockOwner(locker)) && !isClosed(locker)) { throw new IllegalStateException("Lock not held");