Thread_Pool.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //=============================================================================
00004 /**
00005  *  @file    Thread_Pool.h
00006  *
00007  *  $Id: Thread_Pool.h 78627 2007-06-28 08:50:01Z johnnyw $
00008  *
00009  *  @author Irfan Pyarali
00010  *  @author Johnny Willemsen
00011  */
00012 // ===================================================================
00013 
00014 #ifndef TAO_THREAD_POOL_H
00015 #define TAO_THREAD_POOL_H
00016 
00017 #include /**/ "ace/pre.h"
00018 #include "tao/orbconf.h"
00019 
00020 #if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
00021 
00022 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00023 # pragma once
00024 #endif /* ACE_LACKS_PRAGMA_ONCE */
00025 
00026 #include "tao/RTCORBA/RTCORBA_includeC.h"
00027 #include "ace/Hash_Map_Manager.h"
00028 #include "tao/Thread_Lane_Resources.h"
00029 #include "tao/New_Leader_Generator.h"
00030 #include "ace/Task.h"
00031 #include "ace/Null_Mutex.h"
00032 
00033 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00034 
00035 class TAO_Thread_Lane;
00036 
00037 /**
00038  * @class TAO_RT_New_Leader_Generator
00039  *
00040  * @brief Class for creating dynamic threads.
00041  *
00042  * \nosubgrouping
00043  *
00044  **/
00045 class TAO_RTCORBA_Export TAO_RT_New_Leader_Generator
00046   : public TAO_New_Leader_Generator
00047 {
00048 public:
00049 
00050   /// Constructor.
00051   TAO_RT_New_Leader_Generator (TAO_Thread_Lane &lane);
00052 
00053   /// Leader/Follower class uses this method to notify the system that
00054   /// we are out of leaders.
00055   void no_leaders_available (void);
00056 
00057 private:
00058 
00059   /// Lane associated with this leader generator.
00060   TAO_Thread_Lane &lane_;
00061 };
00062 
00063 /**
00064  * @class TAO_Thread_Pool_Threads
00065  *
00066  * @brief Class representing a static thread running in a thread lane.
00067  *
00068  * \nosubgrouping
00069  *
00070  **/
00071 class TAO_Thread_Pool_Threads : public ACE_Task_Base
00072 {
00073 public:
00074 
00075   /// Constructor.
00076   TAO_Thread_Pool_Threads (TAO_Thread_Lane &lane);
00077 
00078   /// Method executed when a thread is spawned.
00079   int svc (void);
00080 
00081   /// Accessor to the lane to which this thread belongs to.
00082   TAO_Thread_Lane &lane (void) const;
00083 
00084   /// Set TSS resources for the current thread.
00085   static void set_tss_resources (TAO_ORB_Core &orb_core,
00086                                  TAO_Thread_Lane &thread_lane);
00087 
00088 protected:
00089   /// Do the real work
00090   virtual int run (TAO_ORB_Core &orb_core);
00091 
00092   /// Lane to which this thread belongs to.
00093   TAO_Thread_Lane &lane_;
00094 };
00095 
00096 /**
00097  * @class TAO_Dynamic_Thread_Pool_Threads
00098  *
00099  * @brief Class representing a dynamic thread running in a thread lane.
00100  *
00101  * \nosubgrouping
00102  *
00103  **/
00104 class TAO_Dynamic_Thread_Pool_Threads : public TAO_Thread_Pool_Threads
00105 {
00106 public:
00107   /// Constructor.
00108   TAO_Dynamic_Thread_Pool_Threads (TAO_Thread_Lane &lane);
00109 
00110 protected:
00111   /// Do the real work
00112   virtual int run (TAO_ORB_Core &orb_core);
00113 };
00114 
00115 class TAO_Thread_Pool;
00116 
00117 /**
00118  * @class TAO_Thread_Lane
00119  *
00120  * @brief Class representing the thread lane inside a thread pool.
00121  *
00122  * \nosubgrouping
00123  *
00124  **/
00125 class TAO_RTCORBA_Export TAO_Thread_Lane
00126 {
00127 public:
00128 
00129   /// Constructor.
00130   TAO_Thread_Lane (TAO_Thread_Pool &pool,
00131                    CORBA::ULong id,
00132                    CORBA::Short lane_priority,
00133                    CORBA::ULong static_threads,
00134                    CORBA::ULong dynamic_threads,
00135                    ACE_Time_Value const &dynamic_thread_idle_timeout);
00136 
00137   /// Destructor.
00138   ~TAO_Thread_Lane (void);
00139 
00140   /// Open the lane.
00141   void open (void);
00142 
00143   /// Finalize the resources.
00144   void finalize (void);
00145 
00146   /// Shutdown the reactor.
00147   void shutdown_reactor (void);
00148 
00149   /// Wait for threads to exit.
00150   void wait (void);
00151 
00152   /// Does @a mprofile belong to us?
00153   int is_collocated (const TAO_MProfile &mprofile);
00154 
00155   /// Create the static threads - only called once.
00156   int create_static_threads (void);
00157 
00158   /// Mark that this lane is shutting down, we then don't create any
00159   /// dynamic threads anymore. When the pool is shutting down the leader
00160   /// follower loop is called which can cause a request to create a
00161   /// new dynamic thread but we shouldn't create a new one.
00162   void shutting_down (void);
00163 
00164   /// Called by the TAO_RT_New_Leader_Generator to request a new dynamic
00165   /// thread.
00166   /**
00167    * It can be that no thread can be created because the number of
00168    * threads is equal to the maximum we can have or the Thread Lane
00169    * is shutting down.
00170    * @retval true A new thread is created
00171    * @retval false No thread could be created
00172    */
00173   bool new_dynamic_thread (void);
00174 
00175   /// @name Accessors
00176   // @{
00177 
00178   TAO_Thread_Pool &pool (void) const;
00179   CORBA::ULong id (void) const;
00180 
00181   CORBA::Short lane_priority (void) const;
00182   CORBA::ULong static_threads (void) const;
00183   CORBA::ULong dynamic_threads (void) const;
00184 
00185   CORBA::ULong current_threads (void) const;
00186 
00187   CORBA::Short native_priority (void) const;
00188 
00189   TAO_Thread_Lane_Resources &resources (void);
00190 
00191   ACE_Time_Value const &dynamic_thread_idle_timeout (void) const;
00192   // @}
00193 
00194 private:
00195 
00196   /// Validate lane's priority and map it to a native value.
00197   void validate_and_map_priority (void);
00198 
00199   int create_threads_i (TAO_Thread_Pool_Threads &thread_pool,
00200                         CORBA::ULong number_of_threads,
00201                         long thread_flags);
00202 
00203   /// Create @a number_of_threads of dynamic threads.  Can be called
00204   /// multiple times.
00205   int create_dynamic_threads (CORBA::ULong number_of_threads);
00206 
00207   /// The Thread Pool to which this lane belongs.
00208   TAO_Thread_Pool &pool_;
00209 
00210   /// The id of this lane
00211   CORBA::ULong const id_;
00212 
00213   CORBA::Short lane_priority_;
00214 
00215   /// This boolean is set when we are shutting down, then we will not create
00216   /// any new dynamic threads
00217   bool shutdown_;
00218 
00219   /// Number of static threads
00220   CORBA::ULong const static_threads_number_;
00221 
00222   /// Maximum number of threads we are allowed to create
00223   CORBA::ULong const dynamic_threads_number_;
00224 
00225   /// Array with all static threads
00226   TAO_Thread_Pool_Threads static_threads_;
00227 
00228   /// Array with all dynamic threads
00229   TAO_Dynamic_Thread_Pool_Threads dynamic_threads_;
00230 
00231   TAO_RT_New_Leader_Generator new_thread_generator_;
00232 
00233   TAO_Thread_Lane_Resources resources_;
00234 
00235   CORBA::Short native_priority_;
00236 
00237   ACE_Time_Value const dynamic_thread_idle_timeout_;
00238 
00239   /// Lock to guard all members of the lane
00240   mutable ACE_SYNCH_MUTEX lock_;
00241 };
00242 
00243 class TAO_Thread_Pool_Manager;
00244 
00245 /**
00246  * @class TAO_Thread_Pool
00247  *
00248  * @brief Class representing the thread pool inside a thread pool
00249  * manager.
00250  *
00251  * \nosubgrouping
00252  *
00253  **/
00254 class TAO_RTCORBA_Export TAO_Thread_Pool
00255 {
00256 public:
00257 
00258   /// Constructor (for pools without lanes).
00259   TAO_Thread_Pool (TAO_Thread_Pool_Manager &manager,
00260                    CORBA::ULong id,
00261                    CORBA::ULong stack_size,
00262                    CORBA::ULong static_threads,
00263                    CORBA::ULong dynamic_threads,
00264                    CORBA::Short default_priority,
00265                    CORBA::Boolean allow_request_buffering,
00266                    CORBA::ULong max_buffered_requests,
00267                    CORBA::ULong max_request_buffer_size,
00268                    ACE_Time_Value const &dynamic_thread_idle_timeout);
00269 
00270   /// Constructor (for pools with lanes).
00271   TAO_Thread_Pool (TAO_Thread_Pool_Manager &manager,
00272                    CORBA::ULong id,
00273                    CORBA::ULong stack_size,
00274                    const RTCORBA::ThreadpoolLanes &lanes,
00275                    CORBA::Boolean allow_borrowing,
00276                    CORBA::Boolean allow_request_buffering,
00277                    CORBA::ULong max_buffered_requests,
00278                    CORBA::ULong max_request_buffer_size,
00279                    ACE_Time_Value const &dynamic_thread_idle_timeout);
00280 
00281   /// Destructor.
00282   ~TAO_Thread_Pool (void);
00283 
00284   /// Open the pool.
00285   void open (void);
00286 
00287   /// Finalize the resources.
00288   void finalize (void);
00289 
00290   /// Shutdown the reactor.
00291   void shutdown_reactor (void);
00292 
00293   /// Wait for threads to exit.
00294   void wait (void);
00295 
00296   /// Mark this thread pool that we are shutting down.
00297   void shutting_down (void);
00298 
00299   /// Does @a mprofile belong to us?
00300   int is_collocated (const TAO_MProfile &mprofile);
00301 
00302   /// Create the static threads - only called once.
00303   int create_static_threads (void);
00304 
00305   /// Check if this thread pool has (explicit) lanes.
00306   bool with_lanes (void) const;
00307 
00308   /// @name Accessors
00309   // @{
00310 
00311   TAO_Thread_Pool_Manager &manager (void) const;
00312   CORBA::ULong id (void) const;
00313 
00314   CORBA::ULong stack_size (void) const;
00315   CORBA::Boolean allow_borrowing (void) const;
00316   CORBA::Boolean allow_request_buffering (void) const;
00317   CORBA::ULong max_buffered_requests (void) const;
00318   CORBA::ULong max_request_buffer_size (void) const;
00319 
00320   TAO_Thread_Lane **lanes (void);
00321   CORBA::ULong number_of_lanes (void) const;
00322 
00323   // @}
00324 
00325 private:
00326 
00327   TAO_Thread_Pool_Manager &manager_;
00328   CORBA::ULong id_;
00329 
00330   CORBA::ULong stack_size_;
00331   CORBA::Boolean allow_borrowing_;
00332   CORBA::Boolean allow_request_buffering_;
00333   CORBA::ULong max_buffered_requests_;
00334   CORBA::ULong max_request_buffer_size_;
00335   ACE_Time_Value const dynamic_thread_idle_timeout_;
00336 
00337   TAO_Thread_Lane **lanes_;
00338   CORBA::ULong number_of_lanes_;
00339   bool with_lanes_;
00340 };
00341 
00342 class TAO_ORB_Core;
00343 
00344 /**
00345  * @class TAO_Thread_Pool_Manager
00346  *
00347  * @brief Class for managing thread pools.
00348  *
00349  * \nosubgrouping
00350  *
00351  **/
00352 class TAO_RTCORBA_Export TAO_Thread_Pool_Manager
00353 {
00354 public:
00355 
00356   /// Constructor.
00357   TAO_Thread_Pool_Manager (TAO_ORB_Core &orb_core);
00358 
00359   /// Destructor.
00360   ~TAO_Thread_Pool_Manager (void);
00361 
00362   /// Finalize the resources.
00363   void finalize (void);
00364 
00365   /// Shutdown the reactor.
00366   void shutdown_reactor (void);
00367 
00368   /// Wait for threads to exit.
00369   void wait (void);
00370 
00371   /// Does @a mprofile belong to us?
00372   int is_collocated (const TAO_MProfile &mprofile);
00373 
00374   /// Create a threadpool without lanes.
00375   RTCORBA::ThreadpoolId
00376   create_threadpool (CORBA::ULong stacksize,
00377                      CORBA::ULong static_threads,
00378                      CORBA::ULong dynamic_threads,
00379                      RTCORBA::Priority default_priority,
00380                      CORBA::Boolean allow_request_buffering,
00381                      CORBA::ULong max_buffered_requests,
00382                      CORBA::ULong max_request_buffer_size,
00383                      ACE_Time_Value const &dynamic_thread_idle_timeout);
00384 
00385   /// Create a threadpool with lanes.
00386   RTCORBA::ThreadpoolId
00387   create_threadpool_with_lanes (CORBA::ULong stacksize,
00388                                 const RTCORBA::ThreadpoolLanes & lanes,
00389                                 CORBA::Boolean allow_borrowing,
00390                                 CORBA::Boolean allow_request_buffering,
00391                                 CORBA::ULong max_buffered_requests,
00392                                 CORBA::ULong max_request_buffer_size,
00393                                 ACE_Time_Value const &dynamic_thread_idle_timeout
00394                                 );
00395 
00396   /// Destroy a threadpool.
00397   void destroy_threadpool (RTCORBA::ThreadpoolId threadpool
00398                            );
00399 
00400   TAO_Thread_Pool *get_threadpool (RTCORBA::ThreadpoolId thread_pool_id);
00401 
00402   /// Collection of thread pools.
00403   typedef ACE_Hash_Map_Manager<RTCORBA::ThreadpoolId, TAO_Thread_Pool *, ACE_Null_Mutex> THREAD_POOLS;
00404 
00405   /// @name Accessors
00406   // @{
00407 
00408   TAO_ORB_Core &orb_core (void) const;
00409 
00410   // @}
00411 
00412 private:
00413 
00414   /// @name Helpers
00415   // @{
00416 
00417   RTCORBA::ThreadpoolId
00418   create_threadpool_i (CORBA::ULong stacksize,
00419                        CORBA::ULong static_threads,
00420                        CORBA::ULong dynamic_threads,
00421                        RTCORBA::Priority default_priority,
00422                        CORBA::Boolean allow_request_buffering,
00423                        CORBA::ULong max_buffered_requests,
00424                        CORBA::ULong max_request_buffer_size,
00425                        ACE_Time_Value const &dynamic_thread_idle_timeout);
00426 
00427   RTCORBA::ThreadpoolId
00428   create_threadpool_with_lanes_i (CORBA::ULong stacksize,
00429                                   const RTCORBA::ThreadpoolLanes & lanes,
00430                                   CORBA::Boolean allow_borrowing,
00431                                   CORBA::Boolean allow_request_buffering,
00432                                   CORBA::ULong max_buffered_requests,
00433                                   CORBA::ULong max_request_buffer_size,
00434                                   ACE_Time_Value const &dynamic_thread_idle_timeout
00435                                   );
00436 
00437   RTCORBA::ThreadpoolId
00438   create_threadpool_helper (TAO_Thread_Pool *thread_pool);
00439 
00440   // @}
00441 
00442 private:
00443 
00444   TAO_ORB_Core &orb_core_;
00445 
00446   THREAD_POOLS thread_pools_;
00447   RTCORBA::ThreadpoolId thread_pool_id_counter_;
00448   ACE_SYNCH_MUTEX lock_;
00449 };
00450 
00451 TAO_END_VERSIONED_NAMESPACE_DECL
00452 
00453 #if defined (__ACE_INLINE__)
00454 #include "tao/RTCORBA/Thread_Pool.inl"
00455 #endif /* __ACE_INLINE__ */
00456 
00457 #endif /* TAO_HAS_CORBA_MESSAGING && TAO_HAS_CORBA_MESSAGING != 0 */
00458 
00459 #include /**/ "ace/post.h"
00460 
00461 #endif /* TAO_THREAD_POOL_H */

Generated on Sun Jan 27 13:33:23 2008 for TAO_RTCORBA by doxygen 1.3.6