void CThreadPool::Shutdown() { _mutex.Acquire(); size_t tcount = m_activeThreads.size() + m_freeThreads.size(); // exit all Log.Debug("ThreadPool", "Shutting down %u threads.", tcount); KillFreeThreads((uint32)m_freeThreads.size()); _threadsToExit += (uint32)m_activeThreads.size(); for(ThreadSet::iterator itr = m_activeThreads.begin(); itr != m_activeThreads.end(); ++itr) { if((*itr)->ExecutionTarget) (*itr)->ExecutionTarget->OnShutdown(); } _mutex.Release(); for(;;) { _mutex.Acquire(); if(m_activeThreads.size() || m_freeThreads.size()) { Log.Debug("ThreadPool", "%u threads remaining...",m_activeThreads.size() + m_freeThreads.size() ); _mutex.Release(); Sleep(1000); continue; } break; } }
void CThreadPool::IntegrityCheck() { _mutex.Acquire(); int32 gobbled = _threadsEaten; if(gobbled < 0) { // this means we requested more threads than we had in the pool last time. // spawn "gobbled" + THREAD_RESERVE extra threads. uint32 new_threads = abs(gobbled) + THREAD_RESERVE; _threadsEaten=0; for(uint32 i = 0; i < new_threads; ++i) StartThread(NULL); Log.Debug("ThreadPool", "IntegrityCheck: (gobbled < 0) Spawning %u threads.", new_threads); } else if(gobbled < THREAD_RESERVE) { // this means while we didn't run out of threads, we were getting damn low. // spawn enough threads to keep the reserve amount up. uint32 new_threads = (THREAD_RESERVE - gobbled); for(uint32 i = 0; i < new_threads; ++i) StartThread(NULL); Log.Debug("ThreadPool", "IntegrityCheck: (gobbled <= 5) Spawning %u threads.", new_threads); } else if(gobbled > THREAD_RESERVE) { // this means we had "excess" threads sitting around doing nothing. // lets kill some of them off. uint32 kill_count = (gobbled - THREAD_RESERVE); KillFreeThreads(kill_count); _threadsEaten -= kill_count; Log.Debug("ThreadPool", "IntegrityCheck: (gobbled > 5) Killing %u threads.", kill_count); } else { // perfect! we have the ideal number of free threads. Log.Debug("ThreadPool", "IntegrityCheck: Perfect!"); } /*if(m_freeThreads.size() < 5) { uint32 j = 5 - m_freeThreads.size(); Log.Debug("ThreadPool", "Spawning %u threads.", j); for(uint32 i = 0; i < j; ++i) StartThread(NULL); }*/ _threadsExitedSinceLastCheck = 0; _threadsRequestedSinceLastCheck = 0; _threadsFreedSinceLastCheck = 0; _mutex.Release(); }
void CThreadPool::Shutdown() { _mutex.Acquire(); size_t tcount = m_activeThreads.size() + m_freeThreads.size(); // exit all LOG_DEBUG("Shutting down %u threads.", tcount); KillFreeThreads((uint32)m_freeThreads.size()); _threadsToExit += (uint32)m_activeThreads.size(); for(std::set< Thread* >::iterator itr = m_activeThreads.begin(); itr != m_activeThreads.end(); ++itr) { Thread* t = *itr; if(t->ExecutionTarget) t->ExecutionTarget->onShutdown(); else t->ControlInterface.Resume(); } _mutex.Release(); for(int i = 0;; i++) { _mutex.Acquire(); if(m_activeThreads.size() || m_freeThreads.size()) { if(i != 0 && m_freeThreads.size() != 0) { /*if we are here then a thread in the free pool checked if it was being shut down just before CThreadPool::Shutdown() was called, but called Suspend() just after KillFreeThreads(). All we need to do is to resume it.*/ Thread* t; ThreadSet::iterator itr; for(itr = m_freeThreads.begin(); itr != m_freeThreads.end(); ++itr) { t = *itr; t->ControlInterface.Resume(); } } LOG_DEBUG("%u active and %u free threads remaining...", m_activeThreads.size(), m_freeThreads.size()); _mutex.Release(); Arcemu::Sleep(1000); continue; } _mutex.Release(); break; } }
void CThreadPool::Stop() { size_t tcount = m_activeThreads.size() + m_freeThreads.size(); KillFreeThreads((uint32)m_freeThreads.size()); Guard lock(_mutex); ThreadSet::iterator itr; while((itr= m_activeThreads.begin())!=m_activeThreads.end()) { if((*itr)->ExecutionTask){ (*itr)->ControlInterface.Join();//wait all active threads finishing working } m_freeThreads.insert(*itr);//insert the idle thread into m_freeThreads set m_activeThreads.erase(m_activeThreads.begin()); } }