void CEsperEngine::WaitForShutdown (void) // WaitForShutdown // // Waits until all threads have shut down { int i; // Wait for all the reader threads to terminate for (i = 0; i < m_Workers.GetCount(); i++) m_Workers[i]->Wait(); for (i = 0; i < m_Processors.GetCount(); i++) m_Processors[i]->Wait(); // If we get here then SignalShutdown has already been called, which // means that we can no longer add listener threads. CWaitArray Wait; for (i = 0; i < m_Listeners.GetCount(); i++) Wait.Insert(*m_Listeners[i]); Wait.WaitForAll(); }
void CArchonProcess::Run (void) // Run // // This thread will start all engines and continue running // until all engines stop. { int i; if (m_bDebugger) DebugBreak(); // If we could not boot properly, then we stop if (m_iState == stateBootError) return; // Set event indicating that thread should run m_RunEvent.Set(); // Start some threads m_ImportThread.Start(); // Start all engines. At this point we have multiple threads // potentially calling on the IArchonProcessCtx interface // // This allows the engines to start at least one thread. // LATER: Catch errors. for (i = 0; i < m_Engines.GetCount(); i++) m_Engines[i].pEngine->StartRunning(m_RunEvent, m_PauseEvent, m_QuitEvent); // Do stuff now that the module has started OnModuleStart(); // At this point it is safe to call the logging system if (m_bCentralModule) Log(MSG_LOG_INFO, STR_CENTRAL_MODULE_STARTED); else if (!m_bConsoleMode) Log(MSG_LOG_INFO, STR_BOOT_COMPLETE); // If we've in console mode, then run the input loop. CConsoleThread Console(this); if (m_bConsoleMode) Console.Start(); // Loop until we quit. We stop every so often to do clean up // tasks such as garbage collection. CWaitArray Wait; int QUIT_SIGNAL = Wait.Insert(m_QuitSignalEvent); while (true) { int iEvent = Wait.WaitForAny(15000); if (iEvent == QUIT_SIGNAL) break; else if (iEvent == OS_WAIT_TIMEOUT) { if (m_bConsoleMode) Console.OnStartHousekeeping(); CollectGarbage(); SendGlobalMessage(MSG_ARC_HOUSEKEEPING); if (m_bConsoleMode) Console.OnEndHousekeeping(); } } // Some engines still need an explicit call (because they don't have // their own main thread). for (i = 0; i < m_Engines.GetCount(); i++) m_Engines[i].pEngine->SignalShutdown(); // Signal the engines to quit m_QuitEvent.Set(); // We wait until all engines have been shut down for (i = 0; i < m_Engines.GetCount(); i++) m_Engines[i].pEngine->WaitForShutdown(); // Done Shutdown(); }