public void stopSystem()

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");
  }