in geode-core/src/main/java/org/apache/geode/internal/admin/remote/RemoteGfManagerAgent.java [1232:1349]
public void run() {
/* Used to check whether there were pendingJoins before waiting */
boolean noPendingJoins = false;
OUTER: while (!shutDown) {
SystemFailure.checkFailure();
try {
if (!agent.isListening()) {
shutDown();
}
noPendingJoins = agent.pendingJoins.isEmpty();
if (noPendingJoins && logger.isDebugEnabled()) {
logger.debug("Pausing as there are no pending joins ... ");
}
// if paused OR no pendingJoins then just wait...
if (paused || noPendingJoins) {
if (logger.isTraceEnabled(DM_VERBOSE)) {
logger.trace(DM_VERBOSE, "JoinProcessor is about to wait...");
}
synchronized (lock) {
lock.wait();
}
}
if (logger.isTraceEnabled(DM_VERBOSE)) {
logger.trace(DM_VERBOSE, "JoinProcessor has woken up...");
}
if (paused) {
continue;
}
// if no join was already in process or if aborted, get a new one...
if (id == null) {
List pendingJoinsRef = agent.pendingJoins;
if (logger.isTraceEnabled(DM_VERBOSE)) {
logger.trace(DM_VERBOSE, "JoinProcessor pendingJoins: {}", pendingJoinsRef.size());
}
if (!pendingJoinsRef.isEmpty()) {
id = (InternalDistributedMember) pendingJoinsRef.get(0);
if (logger.isTraceEnabled(DM_VERBOSE)) {
logger.trace(DM_VERBOSE, "JoinProcessor got a membership event for {}", id);
}
}
}
if (paused) {
continue;
}
// process the join...
if (id != null) {
if (logger.isTraceEnabled(DM_VERBOSE)) {
logger.trace(DM_VERBOSE, "JoinProcessor handling join for {}", id);
}
try {
agent.handleJoined(id);
} finally {
id = null;
}
}
} catch (CancelException e) {
// we're done!
shutDown = true; // for safety
break;
} catch (InterruptedException e) {
// When this thread is "paused", it is interrupted
if (logger.isTraceEnabled(DM_VERBOSE)) {
logger.trace(DM_VERBOSE, "JoinProcessor has been interrupted...");
}
if (shutDown) {
break;
}
if (paused || noPendingJoins) {
/*
* JoinProcessor waits when: 1. this.paused is set to true 2. There are no pending joins
*
* If the JoinProcessor is interrupted when it was waiting due to second reason, it
* should still continue after catching InterruptedException. From code, currently,
* JoinProcessor is interrupted through JoinProcessor.abort() method which is called
* when a member departs as part of cancelPendingJoin().
*/
if (logger.isDebugEnabled()) {
logger.debug("JoinProcessor was interrupted when it was paused, now resuming ...", e);
}
noPendingJoins = false;
continue;
}
break; // Panic!
} catch (OperationCancelledException ex) {
if (logger.isTraceEnabled(DM_VERBOSE)) {
logger.trace(DM_VERBOSE, "join cancelled by departure");
}
} catch (VirtualMachineError err) {
SystemFailure.initiateFailure(err);
// If this ever returns, rethrow the error. We're poisoned
// now, so don't let this thread continue.
throw err;
} catch (Throwable e) {
// Whenever you catch Error or Throwable, you must also
// catch VirtualMachineError (see above). However, there is
// _still_ a possibility that you are dealing with a cascading
// error condition, so you also need to check to see if the JVM
// is still usable:
SystemFailure.checkFailure();
for (Throwable cause = e.getCause(); cause != null; cause = cause.getCause()) {
if (cause instanceof InterruptedException) {
if (logger.isTraceEnabled(DM_VERBOSE)) {
logger.trace(DM_VERBOSE, "JoinProcessor has been interrupted...");
}
continue OUTER;
}
}
logger.error("JoinProcessor caught exception...", e);
}
}
}