/** * Note: If target size is zero, caller MUST pop and discard the block. Otherwise, the * block size will be zero, which is illegal. */ void unlockToSavepoint(_Locker locker, int targetSize) { int size = mSize; if (size > targetSize) { _Lock[] locks = mLocks; _LockManager manager = locker.mManager; size--; long mask = 1L << size; long upgrades = mUpgrades; while (true) { _Lock lock = locks[size]; if ((upgrades & mask) != 0) { manager.unlockToUpgradable(locker, lock); } else { manager.unlock(locker, lock); } locks[size] = null; if (size == targetSize) { break; } size--; mask >>>= 1; } mUpgrades = upgrades & ~(~0L << size); mSize = size; } }
/** * Note: If target size is zero, caller MUST pop and discard the block. Otherwise, the * block size will be zero, which is illegal. */ void unlockToSavepoint(_Locker locker, int targetSize) { int size = mSize; if (size > targetSize) { _Lock[] locks = mLocks; _LockManager manager = locker.mManager; size--; long mask = 1L << size; long upgrades = mUpgrades; while (true) { _Lock lock = locks[size]; if ((upgrades & mask) != 0) { manager.unlockToUpgradable(locker, lock); } else { manager.unlock(locker, lock); } locks[size] = null; if (size == targetSize) { break; } size--; mask >>>= 1; } mUpgrades = upgrades & ~(~0L << size); mSize = size; } }
/** * Note: If target size is zero, caller MUST pop and discard the block. Otherwise, the * block size will be zero, which is illegal. */ void unlockToSavepoint(_Locker locker, int targetSize) { int size = mSize; if (size > targetSize) { _Lock[] locks = mLocks; _LockManager manager = locker.mManager; size--; long mask = (1L << 63) >>> size; long upgrades = mUpgrades; while (true) { _Lock lock = locks[size]; if ((upgrades & mask) != 0) { manager.unlockToUpgradable(locker, lock); } else { manager.unlock(locker, lock); } locks[size] = null; if (size == targetSize) { break; } size--; mask <<= 1; } mUpgrades = upgrades & ~(~0L >>> size); mSize = size; } }
void unlockLast(_Locker locker) { int size = mSize - 1; long upgrades = mUpgrades; long mask = 1L << size; if ((upgrades & mask) != 0) { throw new IllegalStateException("Cannot unlock non-immediate upgrade"); } _Lock[] locks = mLocks; locker.mManager.unlock(locker, locks[size]); // Only pop lock if unlock succeeded. locks[size] = null; if (size == 0) { locker.mTailBlock = mPrev; mPrev = null; } else { mUpgrades &= upgrades & ~mask; mSize = size; } }
void unlockLast(_Locker locker) { int size = mSize - 1; long upgrades = mUpgrades; long mask = 1L << size; if ((upgrades & mask) != 0) { throw new IllegalStateException("Cannot unlock non-immediate upgrade"); } _Lock[] locks = mLocks; locker.mManager.unlock(locker, locks[size]); // Only pop lock if unlock succeeded. locks[size] = null; if (size == 0) { locker.mTailBlock = mPrev; mPrev = null; } else { mUpgrades &= upgrades & ~mask; mSize = size; } }
/** * Fully releases last lock acquired, within the current scope. If the last * lock operation was an upgrade, for a lock not immediately acquired, * unlock is not allowed. Instead, an IllegalStateException is thrown. * * <p><i>Note: This method is intended for advanced use cases.</i> Also, the current * implementation does not accurately track scopes. It may permit an unlock operation to * cross a scope boundary, which has undefined behavior. * * @throws IllegalStateException if no locks held, or if unlocking a * non-immediate upgrade */ public final void unlock() { Object tailObj = mTailBlock; if (tailObj == null) { throw new IllegalStateException("No locks held"); } if (tailObj instanceof _Lock) { mTailBlock = null; mManager.unlock(this, (_Lock) tailObj); } else { ((Block) tailObj).unlockLast(this); } }
/** * Fully releases the last lock or group acquired, within the current scope. If the last * lock operation was an upgrade, for a lock not immediately acquired, unlock is not * allowed. Instead, an IllegalStateException is thrown. * * <p><i>Note: This method is intended for advanced use cases.</i> * * @throws IllegalStateException if no locks held, or if crossing a scope boundary, or if * unlocking a non-immediate upgrade */ public final void unlock() { Object tailObj = mTailBlock; if (tailObj == null) { throw new IllegalStateException("No locks held"); } if (tailObj instanceof _Lock) { ParentScope parent = mParentScope; if (parent != null && parent.mTailBlock == tailObj) { throw new IllegalStateException("Cannot cross a scope boundary"); } mTailBlock = null; mManager.unlock(this, (_Lock) tailObj); } else { Block.unlockLast((Block) tailObj, this); } }
/** * Fully releases last lock acquired, within the current scope. If the last * lock operation was an upgrade, for a lock not immediately acquired, * unlock is not allowed. Instead, an IllegalStateException is thrown. * * <p><i>Note: This method is intended for advanced use cases.</i> Also, the current * implementation does not accurately track scopes. It may permit an unlock operation to * cross a scope boundary, which has undefined behavior. * * @throws IllegalStateException if no locks held, or if unlocking a * non-immediate upgrade */ public final void unlock() { Object tailObj = mTailBlock; if (tailObj == null) { throw new IllegalStateException("No locks held"); } if (tailObj instanceof _Lock) { mTailBlock = null; mManager.unlock(this, (_Lock) tailObj); } else { ((Block) tailObj).unlockLast(this); } }
block.parentCheck(locker, lock); locker.mManager.unlock(locker, lock);
mManager.unlock(this, (_Lock) tailObj); mTailBlock = null; } else {
mManager.unlock(this, (_Lock) tailObj); mTailBlock = null; } else {
mManager.unlock(this, (_Lock) tailObj); mTailBlock = null; } else {