11//
22// ThreadPool.cpp
33//
4- // $Id: //poco/1.2/Foundation/src/ThreadPool.cpp#1 $
4+ // $Id: //poco/1.2/Foundation/src/ThreadPool.cpp#2 $
55//
66// Library: Foundation
77// Package: Threading
@@ -66,13 +66,13 @@ class PooledThread: public Runnable
6666private:
6767 volatile bool _idle;
6868 volatile time_t _idleTime;
69- Runnable* _pTarget;
70- std::string _name;
71- Thread _thread;
72- Event _targetReady;
73- Event _targetCompleted;
74- Event _started;
75- FastMutex _mutex;
69+ Runnable* _pTarget;
70+ std::string _name;
71+ Thread _thread;
72+ Event _targetReady;
73+ Event _targetCompleted;
74+ Event _started;
75+ FastMutex _mutex;
7676};
7777
7878
@@ -146,10 +146,7 @@ int PooledThread::idleTime()
146146{
147147 FastMutex::ScopedLock lock (_mutex);
148148
149- if (_idle)
150- return (int ) (time (NULL ) - _idleTime);
151- else
152- return 0 ;
149+ return (int ) (time (NULL ) - _idleTime);
153150}
154151
155152
@@ -214,11 +211,10 @@ void PooledThread::run()
214211 {
215212 ErrorHandler::handle ();
216213 }
217- _mutex. lock ();
218- _idle = true ;
214+ FastMutex::ScopedLock lock (_mutex );
215+ _pTarget = 0 ;
219216 _idleTime = time (NULL );
220- _pTarget = 0 ;
221- _mutex.unlock ();
217+ _idle = true ;
222218 _targetCompleted.set ();
223219 ThreadLocalStorage::clear ();
224220 _thread.setName (_name);
@@ -238,7 +234,8 @@ ThreadPool::ThreadPool(int minCapacity, int maxCapacity, int idleTime):
238234 _minCapacity (minCapacity),
239235 _maxCapacity (maxCapacity),
240236 _idleTime (idleTime),
241- _serial (0 )
237+ _serial (0 ),
238+ _age (0 )
242239{
243240 poco_assert (minCapacity >= 1 && maxCapacity >= minCapacity && idleTime > 0 );
244241
@@ -256,7 +253,8 @@ ThreadPool::ThreadPool(const std::string& name, int minCapacity, int maxCapacity
256253 _minCapacity (minCapacity),
257254 _maxCapacity (maxCapacity),
258255 _idleTime (idleTime),
259- _serial (0 )
256+ _serial (0 ),
257+ _age (0 )
260258{
261259 poco_assert (minCapacity >= 1 && maxCapacity >= minCapacity && idleTime > 0 );
262260
@@ -383,29 +381,51 @@ void ThreadPool::collect()
383381
384382void ThreadPool::housekeep ()
385383{
386- bool moreThreads = true ;
387- while (moreThreads && _threads.size () > _minCapacity)
384+ if (_threads.size () <= _minCapacity)
385+ return ;
386+
387+ ThreadVec idleThreads;
388+ ThreadVec expiredThreads;
389+ ThreadVec activeThreads;
390+ idleThreads.reserve (_threads.size ());
391+ activeThreads.reserve (_threads.size ());
392+
393+ for (ThreadVec::iterator it = _threads.begin (); it != _threads.end (); ++it)
388394 {
389- moreThreads = false ;
390- for (ThreadVec::iterator it = _threads.begin (); it != _threads.end (); ++it)
395+ if ((*it)->idle ())
391396 {
392- if ((*it)->idleTime () >= _idleTime)
393- {
394- (*it)->release ();
395- _threads.erase (it);
396- moreThreads = true ;
397- break ;
398- }
397+ if ((*it)->idleTime () < _idleTime)
398+ idleThreads.push_back (*it);
399+ else
400+ expiredThreads.push_back (*it);
401+ }
402+ else activeThreads.push_back (*it);
403+ }
404+ int n = (int ) activeThreads.size ();
405+ int limit = (int ) idleThreads.size () + n;
406+ if (limit < _minCapacity) limit = _minCapacity;
407+ idleThreads.insert (idleThreads.end (), expiredThreads.begin (), expiredThreads.end ());
408+ _threads.clear ();
409+ for (ThreadVec::iterator it = idleThreads.begin (); it != idleThreads.end (); ++it)
410+ {
411+ if (n < limit)
412+ {
413+ _threads.push_back (*it);
414+ ++n;
399415 }
416+ else (*it)->release ();
400417 }
418+ _threads.insert (_threads.end (), activeThreads.begin (), activeThreads.end ());
419+ _age = 0 ;
401420}
402421
403422
404423PooledThread* ThreadPool::getThread ()
405424{
406425 FastMutex::ScopedLock lock (_mutex);
407426
408- housekeep ();
427+ if (++_age == 32 )
428+ housekeep ();
409429
410430 PooledThread* pThread = 0 ;
411431 for (ThreadVec::iterator it = _threads.begin (); !pThread && it != _threads.end (); ++it)
@@ -420,10 +440,7 @@ PooledThread* ThreadPool::getThread()
420440 _threads.push_back (pThread);
421441 pThread->start ();
422442 }
423- else
424- {
425- throw NoThreadAvailableException ();
426- }
443+ else throw NoThreadAvailableException ();
427444 }
428445 pThread->activate ();
429446 return pThread;
0 commit comments