ThreadPool.h

Go to the documentation of this file.
00001 //
00002 //  Copyright (c) 2003-2006 by Autodesk, Inc.
00003 //
00004 //  By using this code, you are agreeing to the terms and conditions of
00005 //  the License Agreement included in the documentation for this code.
00006 //
00007 //  AUTODESK MAKES NO WARRANTIES, EXPRESS OR IMPLIED,
00008 //  AS TO THE CORRECTNESS OF THIS CODE OR ANY DERIVATIVE
00009 //  WORKS WHICH INCORPORATE IT.
00010 //
00011 //  AUTODESK PROVIDES THE CODE ON AN "AS-IS" BASIS
00012 //  AND EXPLICITLY DISCLAIMS ANY LIABILITY, INCLUDING
00013 //  CONSEQUENTIAL AND INCIDENTAL DAMAGES FOR ERRORS,
00014 //  OMISSIONS, AND OTHER PROBLEMS IN THE CODE.
00015 //
00016 //  Use, duplication, or disclosure by the U.S. Government is subject to
00017 //  restrictions set forth in FAR 52.227-19 (Commercial Computer Software
00018 //  Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) (Rights in Technical
00019 //  Data and Computer Software), as applicable.
00020 //
00021 
00022 #ifndef _DWFCORE_THREAD_POOL_H
00023 #define _DWFCORE_THREAD_POOL_H
00024 
00025 
00031 
00032 
00033 #include "dwfcore/Core.h"
00034 #include "dwfcore/STL.h"
00035 #include "dwfcore/Exception.h"
00036 #include "dwfcore/Synchronization.h"
00037 
00038 
00039 
00040 namespace DWFCore
00041 {
00042 
00043 
00061 class DWFThreadWorker
00062 {
00063 
00064 public:
00065 
00071     _DWFCORE_API
00072     virtual ~DWFThreadWorker()
00073         throw()
00074     {;}
00075 
00086     _DWFCORE_API
00087     virtual void begin()
00088         throw() = 0;
00089 
00103     _DWFCORE_API
00104     virtual void suspend()
00105         throw()
00106     {;}
00107 
00121     _DWFCORE_API
00122     virtual void resume()
00123         throw()
00124     {;}
00125 
00126 protected:
00127 
00133     _DWFCORE_API
00134     DWFThreadWorker()
00135         throw()
00136     {;}
00137 };
00138 
00157 class DWFThreadPool : virtual public DWFCoreMemory
00158 {
00159 
00160 public:
00161 
00174     class Controller : virtual public DWFCoreMemory
00175     {
00176 
00177     public:
00178 
00184         _DWFCORE_API 
00185         ~Controller()
00186             throw();
00187 
00198         _DWFCORE_API
00199         void end()
00200             throw( DWFException );
00201 
00209         _DWFCORE_API
00210         DWFThread::teState suspend()
00211             throw( DWFException );
00212 
00220         _DWFCORE_API
00221         DWFThread::teState resume()
00222             throw( DWFException );
00223 
00224     private:
00225         friend class DWFThreadPool;
00226 
00227         //
00228         // Constructor
00229         //
00230         _DWFCORE_API
00231         Controller( DWFThread&     rThread,
00232                     DWFThreadPool& rPool )
00233             throw();
00234 
00235         //
00236         // Not Implemented
00237         //
00238         Controller( const Controller& );
00239         Controller& operator=( const Controller& );
00240 
00241     private:
00242 
00243         DWFThread&     _rThread;
00244         DWFThreadPool& _rPool;
00245     };
00246 
00247 
00248 public:
00249 
00255     _DWFCORE_API
00256     DWFThreadPool()
00257         throw();
00258 
00264     _DWFCORE_API
00265     ~DWFThreadPool()
00266         throw();
00267 
00275     _DWFCORE_API
00276     void init( unsigned int nThreads )
00277         throw( DWFException );
00278 
00287     _DWFCORE_API
00288     DWFThreadPool::Controller* run( DWFThreadWorker& rWorker )
00289         throw( DWFException );
00290 
00291 private:
00292     friend class DWFThread;
00293 
00294     //
00295     //
00296     //
00297     DWFThread* _acquireThread()
00298         throw( DWFException );
00299 
00300     //
00301     //
00302     //
00303     void _returnThread( DWFThread* pThread )
00304         throw( DWFException );
00305 
00306     //
00307     // Internal API for Controllers
00308     //
00309 private:
00310 
00311     //
00312     // Request the running worker to end
00313     // Returns the run state of the worker after processing the call
00314     // It will be possible to make a request that is not honored
00315     //
00316     void _end( DWFThread* pThread )
00317         throw( DWFException );
00318 
00319     //
00320     // Request the running worker to suspend itself
00321     // Returns the run state of the worker after processing the call
00322     // It will be possible to make a request that is not honored
00323     //
00324     DWFThread::teState _suspend( DWFThread& rThread )
00325         throw();
00326 
00327     //
00328     // Request the suspended worker to resume running
00329     // Returns the run state of the worker after processing the call
00330     // It will be possible to make a request that is not honored
00331     //
00332     DWFThread::teState _resume( DWFThread& rThread )
00333         throw();
00334 
00335 private:
00336 
00337     class _Monitor : public DWFThreadWorker
00338                    , virtual public DWFCoreMemory
00339     {
00340     public:
00341 
00342         _Monitor()
00343             throw()
00344             : _bRun( true )
00345             , _oRequestSignal()
00346             , _oResponseSignal()
00347             , _oRequestMutex()
00348             , _pThread( NULL )
00349             , _eRequest( DWFThread::eNone )
00350         {
00351             _oRequestMutex.init();
00352             _oRequestSignal.init();
00353             _oResponseSignal.init();
00354         }
00355 
00356         virtual ~_Monitor()
00357             throw()
00358         {
00359             _oRequestMutex.destroy();
00360             _oRequestSignal.destroy();
00361             _oResponseSignal.destroy();
00362         }
00363 
00364         void begin()
00365             throw();
00366 
00367         void finish()
00368             throw();
00369 
00370         bool request( DWFThread&         rThread,
00371                       DWFThread::teState eRequest,
00372                       unsigned int       nMilliseconds )
00373             throw();
00374 
00375     private:
00376 
00377         bool               _bRun;
00378         DWFSignal          _oRequestSignal;
00379         DWFSignal          _oResponseSignal;
00380         DWFThreadMutex     _oRequestMutex;
00381 
00382         DWFThread*         _pThread;
00383         DWFThread::teState _eRequest;
00384 
00385     private:
00386 
00387         _Monitor( const _Monitor& );
00388         _Monitor& operator=( const _Monitor& );
00389     };
00390 
00391 private:
00392 
00393     bool                _bInit;
00394 
00395     vector<DWFThread*>  _oThreads;
00396     queue<DWFThread*>   _oThreadQueue;
00397     DWFThreadMutex*     _pQueueMutex;
00398     DWFSemaphore*       _pQueueSemaphore;
00399 
00400     _Monitor            _oMonitor;
00401     DWFThread*          _pMonitorThread;
00402 
00403 private:
00404 
00405     //
00406     // Not Implemented
00407     //
00408     DWFThreadPool( const DWFThreadPool& );
00409     DWFThreadPool& operator=( const DWFThreadPool& );
00410 };
00411 
00412 
00413 }
00414 
00415 #endif

Generated on Tue Jan 6 22:39:29 2009 for Autodesk DWF Core Library by  doxygen 1.4.5