/** * Wake the procedures waiting for meta. * @see #waitMetaExclusiveLock(Procedure) * @param procedure the procedure releasing the lock * @deprecated only used for {@link RecoverMetaProcedure}. Should be removed along with * {@link RecoverMetaProcedure}. */ @Deprecated public void wakeMetaExclusiveLock(Procedure<?> procedure) { schedLock(); try { final LockAndQueue lock = locking.getMetaLock(); lock.releaseExclusiveLock(procedure); addToRunQueue(metaRunQueue, getMetaQueue(), () -> procedure + " released exclusive lock"); int waitingCount = wakeWaitingProcedures(lock); wakePollIfNeeded(waitingCount); } finally { schedUnlock(); } }
/** * Wake the procedures waiting for the specified peer * @see #waitPeerExclusiveLock(Procedure, String) * @param procedure the procedure releasing the lock * @param peerId the peer that has the exclusive lock */ public void wakePeerExclusiveLock(Procedure<?> procedure, String peerId) { schedLock(); try { final LockAndQueue lock = locking.getPeerLock(peerId); if (lock.releaseExclusiveLock(procedure)) { addToRunQueue(peerRunQueue, getPeerQueue(peerId), () -> procedure + " released exclusive lock"); int waitingCount = wakeWaitingProcedures(lock); wakePollIfNeeded(waitingCount); } } finally { schedUnlock(); } }
/** * Wake the procedures waiting for the specified server * @see #waitServerExclusiveLock(Procedure,ServerName) * @param procedure the procedure releasing the lock * @param serverName the server that has the exclusive lock */ public void wakeServerExclusiveLock(final Procedure<?> procedure, final ServerName serverName) { schedLock(); try { final LockAndQueue lock = locking.getServerLock(serverName); // Only SCP will acquire/release server lock so do not need to check the return value here. lock.releaseExclusiveLock(procedure); // In tests we may pass procedures other than ServerProcedureInterface, just pass null if // so. addToRunQueue(serverRunQueue, getServerQueue(serverName, procedure instanceof ServerProcedureInterface ? (ServerProcedureInterface) procedure : null), () -> procedure + " released exclusive lock"); int waitingCount = wakeWaitingProcedures(lock); wakePollIfNeeded(waitingCount); } finally { schedUnlock(); } }
hasLock = false; while (i-- > 0) { regionLocks[i].releaseExclusiveLock(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); } } }
if (regionLock.releaseExclusiveLock(procedure)) { if (!regionLock.isWaitingQueueEmpty()) {
/** * Wake the procedures waiting for the specified namespace * @see #waitNamespaceExclusiveLock(Procedure,String) * @param procedure the procedure releasing the lock * @param namespace the namespace that has the exclusive lock */ public void wakeNamespaceExclusiveLock(final Procedure<?> procedure, final String namespace) { schedLock(); try { final LockAndQueue namespaceLock = locking.getNamespaceLock(namespace); final LockAndQueue systemNamespaceTableLock = locking.getTableLock(TableProcedureInterface.DUMMY_NAMESPACE_TABLE_NAME); int waitingCount = 0; if (namespaceLock.releaseExclusiveLock(procedure)) { waitingCount += wakeWaitingProcedures(namespaceLock); } if (systemNamespaceTableLock.releaseSharedLock()) { addToRunQueue(tableRunQueue, getTableQueue(TableProcedureInterface.DUMMY_NAMESPACE_TABLE_NAME), () -> procedure + " released namespace exclusive lock"); waitingCount += wakeWaitingProcedures(systemNamespaceTableLock); } wakePollIfNeeded(waitingCount); } finally { schedUnlock(); } }
/** * Wake the procedures waiting for the specified table * @param procedure the procedure releasing the lock * @param table the name of the table that has the exclusive lock */ public void wakeTableExclusiveLock(final Procedure<?> procedure, final TableName table) { schedLock(); try { final LockAndQueue namespaceLock = locking.getNamespaceLock(table.getNamespaceAsString()); final LockAndQueue tableLock = locking.getTableLock(table); int waitingCount = 0; if (tableLock.releaseExclusiveLock(procedure)) { waitingCount += wakeWaitingProcedures(tableLock); } if (namespaceLock.releaseSharedLock()) { waitingCount += wakeWaitingProcedures(namespaceLock); } addToRunQueue(tableRunQueue, getTableQueue(table), () -> procedure + " released the exclusive lock"); wakePollIfNeeded(waitingCount); } 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); } } }