/** * Try to acquire the exclusive lock on meta. * @see #wakeMetaExclusiveLock(Procedure) * @param procedure the procedure trying to acquire the lock * @return true if the procedure has to wait for meta to be available * @deprecated only used for {@link RecoverMetaProcedure}. Should be removed along with * {@link RecoverMetaProcedure}. */ @Deprecated public boolean waitMetaExclusiveLock(Procedure<?> procedure) { schedLock(); try { final LockAndQueue lock = locking.getMetaLock(); if (lock.tryExclusiveLock(procedure)) { removeFromRunQueue(metaRunQueue, getMetaQueue(), () -> procedure + " held exclusive lock"); return false; } waitProcedure(lock, procedure); logLockedResource(LockedResourceType.META, TableName.META_TABLE_NAME.getNameAsString()); return true; } finally { schedUnlock(); } }
private void tryCleanupPeerQueue(String peerId, Procedure<?> procedure) { schedLock(); try { PeerQueue queue = AvlTree.get(peerMap, peerId, PEER_QUEUE_KEY_COMPARATOR); if (queue == null) { return; } final LockAndQueue lock = locking.getPeerLock(peerId); if (queue.isEmpty() && lock.tryExclusiveLock(procedure)) { removeFromRunQueue(peerRunQueue, queue, () -> "clean up peer queue after " + procedure + " completed"); removePeerQueue(peerId); } } finally { schedUnlock(); } }
/** * Try to acquire the exclusive lock on the specified peer. * @see #wakePeerExclusiveLock(Procedure, String) * @param procedure the procedure trying to acquire the lock * @param peerId peer to lock * @return true if the procedure has to wait for the peer to be available */ public boolean waitPeerExclusiveLock(Procedure<?> procedure, String peerId) { schedLock(); try { final LockAndQueue lock = locking.getPeerLock(peerId); if (lock.tryExclusiveLock(procedure)) { removeFromRunQueue(peerRunQueue, getPeerQueue(peerId), () -> procedure + " held exclusive lock"); return false; } waitProcedure(lock, procedure); logLockedResource(LockedResourceType.PEER, peerId); return true; } finally { schedUnlock(); } }
if (!regionLocks[i].tryExclusiveLock(procedure)) { LOG.info("Waiting on xlock for {} held by pid={}", procedure, regionLocks[i].getExclusiveLockProcIdOwner());
private void tryCleanupServerQueue(ServerName serverName, Procedure<?> proc) { schedLock(); try { int index = getBucketIndex(serverBuckets, serverName.hashCode()); ServerQueue node = AvlTree.get(serverBuckets[index], serverName, SERVER_QUEUE_KEY_COMPARATOR); if (node == null) { return; } LockAndQueue lock = locking.getServerLock(serverName); if (node.isEmpty() && lock.tryExclusiveLock(proc)) { removeFromRunQueue(serverRunQueue, node, () -> "clean up server queue after " + proc + " completed"); removeServerQueue(serverName); } } finally { schedUnlock(); } }
/** * Try to acquire the exclusive lock on the specified server. * @see #wakeServerExclusiveLock(Procedure,ServerName) * @param procedure the procedure trying to acquire the lock * @param serverName Server to lock * @return true if the procedure has to wait for the server to be available */ public boolean waitServerExclusiveLock(final Procedure<?> procedure, final ServerName serverName) { schedLock(); try { final LockAndQueue lock = locking.getServerLock(serverName); if (lock.tryExclusiveLock(procedure)) { // In tests we may pass procedures other than ServerProcedureInterface, just pass null if // so. removeFromRunQueue(serverRunQueue, getServerQueue(serverName, procedure instanceof ServerProcedureInterface ? (ServerProcedureInterface) procedure : null), () -> procedure + " held exclusive lock"); return false; } waitProcedure(lock, procedure); logLockedResource(LockedResourceType.SERVER, serverName.getServerName()); return true; } finally { schedUnlock(); } }
@Test public void testHasLockAccess() { Map<Long, NoopProcedure<Void>> procMap = new HashMap<>(); for (long i = 1; i <= 10; i++) { NoopProcedure<Void> proc = new NoopProcedure<>(); proc.setProcId(i); if (i > 1) { proc.setParentProcId(i - 1); proc.setRootProcId(1); } procMap.put(i, proc); } LockAndQueue laq = new LockAndQueue(procMap::get); for (long i = 1; i <= 10; i++) { assertFalse(laq.hasLockAccess(procMap.get(i))); } for (long i = 1; i <= 10; i++) { NoopProcedure<Void> procHasLock = procMap.get(i); laq.tryExclusiveLock(procHasLock); for (long j = 1; j < i; j++) { assertFalse(laq.hasLockAccess(procMap.get(j))); } for (long j = i; j <= 10; j++) { assertTrue(laq.hasLockAccess(procMap.get(j))); } laq.releaseExclusiveLock(procHasLock); } } }
if (queue == null) return true; if (queue.isEmpty() && tableLock.tryExclusiveLock(procedure)) {
/** * Suspend the procedure if the specified namespace is already locked. * @see #wakeNamespaceExclusiveLock(Procedure,String) * @param procedure the procedure trying to acquire the lock * @param namespace Namespace to lock * @return true if the procedure has to wait for the namespace to be available */ public boolean waitNamespaceExclusiveLock(Procedure<?> procedure, String namespace) { schedLock(); try { final LockAndQueue systemNamespaceTableLock = locking.getTableLock(TableProcedureInterface.DUMMY_NAMESPACE_TABLE_NAME); if (!systemNamespaceTableLock.trySharedLock(procedure)) { waitProcedure(systemNamespaceTableLock, procedure); logLockedResource(LockedResourceType.TABLE, TableProcedureInterface.DUMMY_NAMESPACE_TABLE_NAME.getNameAsString()); return true; } final LockAndQueue namespaceLock = locking.getNamespaceLock(namespace); if (!namespaceLock.tryExclusiveLock(procedure)) { systemNamespaceTableLock.releaseSharedLock(); waitProcedure(namespaceLock, procedure); logLockedResource(LockedResourceType.NAMESPACE, namespace); return true; } return false; } finally { schedUnlock(); } }
return true; if (!tableLock.tryExclusiveLock(procedure)) { namespaceLock.releaseSharedLock(); waitProcedure(tableLock, procedure);
@Test public void testHasLockAccess() { Map<Long, NoopProcedure<Void>> procMap = new HashMap<>(); for (long i = 1; i <= 10; i++) { NoopProcedure<Void> proc = new NoopProcedure<>(); proc.setProcId(i); if (i > 1) { proc.setParentProcId(i - 1); proc.setRootProcId(1); } procMap.put(i, proc); } LockAndQueue laq = new LockAndQueue(procMap::get); for (long i = 1; i <= 10; i++) { assertFalse(laq.hasLockAccess(procMap.get(i))); } for (long i = 1; i <= 10; i++) { NoopProcedure<Void> procHasLock = procMap.get(i); laq.tryExclusiveLock(procHasLock); for (long j = 1; j < i; j++) { assertFalse(laq.hasLockAccess(procMap.get(j))); } for (long j = i; j <= 10; j++) { assertTrue(laq.hasLockAccess(procMap.get(j))); } laq.releaseExclusiveLock(procHasLock); } } }