in framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/system/CrawlerAgent.java [494:791]
public void stopSystem(IThreadContext threadContext)
throws ManifoldCFException
{
Logging.root.info("Shutting down pull-agent...");
while (jobDeleteThread != null || startupThread != null || startDeleteThread != null ||
jobStartThread != null || stufferThread != null ||
finisherThread != null || notificationThread != null || workerThreads != null || expireStufferThread != null || expireThreads != null ||
deleteStufferThread != null || deleteThreads != null ||
cleanupStufferThread != null || cleanupThreads != null ||
jobResetThread != null || seedingThread != null || idleCleanupThread != null || assessmentThread != null || setPriorityThread != null || historyCleanupThread != null)
{
// Send an interrupt to all threads that are still there.
// In theory, this only needs to be done once. In practice, I have seen cases where the thread loses track of the fact that it has been
// interrupted (which may be a JVM bug - who knows?), but in any case there's no harm in doing it again.
if (historyCleanupThread != null)
{
historyCleanupThread.interrupt();
}
if (setPriorityThread != null)
{
setPriorityThread.interrupt();
}
if (jobStartThread != null)
{
jobStartThread.interrupt();
}
if (jobDeleteThread != null)
{
jobDeleteThread.interrupt();
}
if (startupThread != null)
{
startupThread.interrupt();
}
if (startDeleteThread != null)
{
startDeleteThread.interrupt();
}
if (stufferThread != null)
{
stufferThread.interrupt();
}
if (expireStufferThread != null)
{
expireStufferThread.interrupt();
}
if (finisherThread != null)
{
finisherThread.interrupt();
}
if (notificationThread != null)
{
notificationThread.interrupt();
}
if (workerThreads != null)
{
int i = 0;
while (i < workerThreads.length)
{
Thread workerThread = workerThreads[i++];
if (workerThread != null)
workerThread.interrupt();
}
}
if (expireThreads != null)
{
int i = 0;
while (i < expireThreads.length)
{
Thread expireThread = expireThreads[i++];
if (expireThread != null)
expireThread.interrupt();
}
}
if (cleanupStufferThread != null)
{
cleanupStufferThread.interrupt();
}
if (cleanupThreads != null)
{
int i = 0;
while (i < cleanupThreads.length)
{
Thread cleanupThread = cleanupThreads[i++];
if (cleanupThread != null)
cleanupThread.interrupt();
}
}
if (deleteStufferThread != null)
{
deleteStufferThread.interrupt();
}
if (deleteThreads != null)
{
int i = 0;
while (i < deleteThreads.length)
{
Thread deleteThread = deleteThreads[i++];
if (deleteThread != null)
deleteThread.interrupt();
}
}
if (jobResetThread != null)
{
jobResetThread.interrupt();
}
if (seedingThread != null)
{
seedingThread.interrupt();
}
if (idleCleanupThread != null)
{
idleCleanupThread.interrupt();
}
if (assessmentThread != null)
{
assessmentThread.interrupt();
}
// Now, wait for all threads to die.
try
{
ManifoldCF.sleep(1000L);
}
catch (InterruptedException e)
{
}
// Check to see which died.
if (historyCleanupThread != null)
{
if (!historyCleanupThread.isAlive())
historyCleanupThread = null;
}
if (setPriorityThread != null)
{
if (!setPriorityThread.isAlive())
setPriorityThread = null;
}
if (jobDeleteThread != null)
{
if (!jobDeleteThread.isAlive())
jobDeleteThread = null;
}
if (startupThread != null)
{
if (!startupThread.isAlive())
startupThread = null;
}
if (startDeleteThread != null)
{
if (!startDeleteThread.isAlive())
startDeleteThread = null;
}
if (jobStartThread != null)
{
if (!jobStartThread.isAlive())
jobStartThread = null;
}
if (stufferThread != null)
{
if (!stufferThread.isAlive())
stufferThread = null;
}
if (expireStufferThread != null)
{
if (!expireStufferThread.isAlive())
expireStufferThread = null;
}
if (finisherThread != null)
{
if (!finisherThread.isAlive())
finisherThread = null;
}
if (notificationThread != null)
{
if (!notificationThread.isAlive())
notificationThread = null;
}
if (workerThreads != null)
{
int i = 0;
boolean isAlive = false;
while (i < workerThreads.length)
{
Thread workerThread = workerThreads[i];
if (workerThread != null)
{
if (!workerThread.isAlive())
workerThreads[i] = null;
else
isAlive = true;
}
i++;
}
if (!isAlive)
workerThreads = null;
}
if (expireThreads != null)
{
int i = 0;
boolean isAlive = false;
while (i < expireThreads.length)
{
Thread expireThread = expireThreads[i];
if (expireThread != null)
{
if (!expireThread.isAlive())
expireThreads[i] = null;
else
isAlive = true;
}
i++;
}
if (!isAlive)
expireThreads = null;
}
if (cleanupStufferThread != null)
{
if (!cleanupStufferThread.isAlive())
cleanupStufferThread = null;
}
if (cleanupThreads != null)
{
int i = 0;
boolean isAlive = false;
while (i < cleanupThreads.length)
{
Thread cleanupThread = cleanupThreads[i];
if (cleanupThread != null)
{
if (!cleanupThread.isAlive())
cleanupThreads[i] = null;
else
isAlive = true;
}
i++;
}
if (!isAlive)
cleanupThreads = null;
}
if (deleteStufferThread != null)
{
if (!deleteStufferThread.isAlive())
deleteStufferThread = null;
}
if (deleteThreads != null)
{
int i = 0;
boolean isAlive = false;
while (i < deleteThreads.length)
{
Thread deleteThread = deleteThreads[i];
if (deleteThread != null)
{
if (!deleteThread.isAlive())
deleteThreads[i] = null;
else
isAlive = true;
}
i++;
}
if (!isAlive)
deleteThreads = null;
}
if (jobResetThread != null)
{
if (!jobResetThread.isAlive())
jobResetThread = null;
}
if (seedingThread != null)
{
if (!seedingThread.isAlive())
seedingThread = null;
}
if (idleCleanupThread != null)
{
if (!idleCleanupThread.isAlive())
idleCleanupThread = null;
}
if (assessmentThread != null)
{
if (!assessmentThread.isAlive())
assessmentThread = null;
}
}
// Threads are down; release connectors
RepositoryConnectorPoolFactory.make(threadContext).flushUnusedConnectors();
NotificationConnectorPoolFactory.make(threadContext).flushUnusedConnectors();
numWorkerThreads = 0;
numDeleteThreads = 0;
numExpireThreads = 0;
Logging.root.info("Pull-agent successfully shut down");
}