in geode-core/src/main/java/org/apache/geode/distributed/internal/locks/DLockGrantor.java [3415:3590]
public void run() {
final boolean isDebugEnabled_DLS = logger.isTraceEnabled(LogMarker.DLS_VERBOSE);
DistributedLockStats stats = grantor.dlock.getStats();
boolean recalcTimeToWait = false;
while (!shutdown) {
if (stopper.isCancelInProgress()) {
break; // done
}
try {
// go into wait if we know we have no timeouts or expires for a while
synchronized (lock) { // synchronized
if (recalcTimeToWait || requireTimeToWait) {
recalcTimeToWait = false;
long nextTS = Math.min(nextExpire, nextTimeout);
nextExpire = Long.MAX_VALUE;
nextTimeout = Long.MAX_VALUE;
if (nextTS != Long.MAX_VALUE || requireTimeToWait) {
requireTimeToWait = false;
long now = now();
// fix bug 39355 by using current timeToWait if smaller
long newTimeToWait = nextTS - now;
if (requireTimeToWait) {
timeToWait = Math.min(timeToWait, newTimeToWait);
} else {
timeToWait = newTimeToWait;
}
if (timeToWait < 0) {
timeToWait = 0;
}
if (isDebugEnabled_DLS) {
logger.trace(LogMarker.DLS_VERBOSE,
"DLockGrantorThread will wait for {} ms. nextExpire={} nextTimeout={} now={}",
timeToWait, nextExpire, nextTimeout, now);
}
} else {
timeToWait = Long.MAX_VALUE;
if (isDebugEnabled_DLS) {
logger.trace(LogMarker.DLS_VERBOSE,
"DLockGrantorThread will wait until rescheduled.");
}
}
}
if (timeToWait > 0) {
if (isDebugEnabled_DLS) {
logger.trace(LogMarker.DLS_VERBOSE,
"DLockGrantorThread is about to wait for {} ms.", timeToWait);
}
if (timeToWait != Long.MAX_VALUE) {
expectedWakeupTimeStamp = now() + timeToWait;
if (expectedWakeupTimeStamp < 0) {
// overflow
expectedWakeupTimeStamp = Long.MAX_VALUE;
}
} else {
expectedWakeupTimeStamp = Long.MAX_VALUE;
}
if (expectedWakeupTimeStamp == Long.MAX_VALUE) {
while (!goIntoWait) {
waiting = true;
lock.wait(); // spurious wakeup ok
waiting = false;
}
} else {
long timeToWaitThisTime = timeToWait;
for (;;) {
waiting = true;
lock.wait(timeToWaitThisTime); // spurious wakeup ok
waiting = false;
if (goIntoWait) {
break; // out of for loop
}
timeToWaitThisTime = expectedWakeupTimeStamp - now();
if (timeToWaitThisTime <= 0) {
break; // out of for loop
}
}
}
if (isDebugEnabled_DLS) {
logger.trace(LogMarker.DLS_VERBOSE, "DLockGrantorThread has woken up...");
}
if (shutdown) {
break;
}
// if goIntoWait, continue back around and enter wait again
if (goIntoWait) {
goIntoWait = false;
continue;
}
}
} // synchronized
long statStart = stats.startGrantorThread();
try {
Collection grants = grantor.snapshotGrantTokens();
// TASK: expire and grant locks
if (shutdown) {
return;
}
if (isDebugEnabled_DLS) {
logger.trace(LogMarker.DLS_VERBOSE,
"DLockGrantorThread about to expireAndGrantLocks...");
}
{
long smallestExpire = grantor.expireAndGrantLocks(grants.iterator());
synchronized (lock) {
if (smallestExpire < nextExpire) {
nextExpire = smallestExpire;
}
}
}
long timing = stats.endGrantorThreadExpireAndGrantLocks(statStart);
// TASK: timeout waiting requests
if (shutdown) {
return;
}
if (isDebugEnabled_DLS) {
logger.trace(LogMarker.DLS_VERBOSE,
"DLockGrantorThread about to handleRequestTimeouts...");
}
{
long smallestRequestTimeout = grantor.handleRequestTimeouts(grants.iterator());
long smallestSuspendTimeout = grantor.handleSuspendTimeouts();
synchronized (lock) {
if (smallestRequestTimeout < nextTimeout) {
nextTimeout = smallestRequestTimeout;
}
if (smallestSuspendTimeout < nextTimeout) {
nextTimeout = smallestSuspendTimeout;
}
}
}
timing = stats.endGrantorThreadHandleRequestTimeouts(timing);
// TASK: remove unused tokens
if (shutdown) {
return;
}
if (isDebugEnabled_DLS) {
logger.trace(LogMarker.DLS_VERBOSE,
"DLockGrantorThread about to removeUnusedGrants...");
}
grantor.removeUnusedGrants(grants.iterator());
stats.endGrantorThreadRemoveUnusedTokens(timing);
} catch (CancelException e) {
// so, exit then.
} finally {
recalcTimeToWait = true;
stats.endGrantorThread(statStart);
}
} catch (LockGrantorDestroyedException ex) {
shutdown = true;
return;
} catch (InterruptedException e) {
// shutdown probably interrupted us
// Not necessary to reset the interrupt bit, we're going to go
// away of our own accord.
if (shutdown) {
// ok to ignore since this thread will now shutdown
} else {
logger.warn("DLockGrantorThread was unexpectedly interrupted",
e);
// do not set interrupt flag since this thread needs to resume
stopper.checkCancelInProgress(e);
}
}
}
}