Leader_Follower.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //=============================================================================
00004 /**
00005  *  @file   Leader_Follower.h
00006  *
00007  *  Leader_Follower.h,v 1.33 2005/11/24 11:05:45 ossama Exp
00008  *
00009  *  @author Carlos O'Ryan (coryan@cs.wustl.edu)
00010  */
00011 //=============================================================================
00012 
00013 
00014 #ifndef TAO_LEADER_FOLLOWER_H
00015 #define TAO_LEADER_FOLLOWER_H
00016 
00017 #include /**/ "ace/pre.h"
00018 #include "ace/os_include/os_errno.h"
00019 
00020 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00021 # pragma once
00022 #endif /* ACE_LACKS_PRAGMA_ONCE */
00023 
00024 #include "tao/New_Leader_Generator.h"
00025 #include "tao/LF_Follower.h"
00026 #include "ace/Reverse_Lock_T.h"
00027 #include "ace/Intrusive_List.h"
00028 #include "ace/Intrusive_List_Node.h"
00029 #include "ace/OS_NS_Thread.h"
00030 
00031 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00032 class ACE_Reactor;
00033 ACE_END_VERSIONED_NAMESPACE_DECL
00034 
00035 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00036 
00037 class TAO_LF_Event;
00038 class TAO_Transport;
00039 class TAO_ORB_Core;
00040 class TAO_ORB_Core_TSS_Resources;
00041 
00042 /**
00043  * @class TAO_Leader_Follower
00044  *
00045  * @brief TAO_Leader_Follower
00046  *
00047  * TAO_Leader_Follower
00048  */
00049 class TAO_Export TAO_Leader_Follower
00050 {
00051 public:
00052   /// Constructor
00053   TAO_Leader_Follower (TAO_ORB_Core *orb_core,
00054                        TAO_New_Leader_Generator *new_leader_generator = 0);
00055 
00056   /// Destructor
00057   ~TAO_Leader_Follower (void);
00058 
00059   /// The current thread has become a server thread (i.e. called
00060   /// ORB::run), update any flags and counters.
00061   int set_event_loop_thread (ACE_Time_Value *max_wait_time);
00062 
00063   /// The current thread is not a server thread anymore, reset any
00064   /// flags and counters.
00065   void reset_event_loop_thread (void);
00066 
00067   /// This thread is going to perform an upcall, it will no longer be
00068   /// an event loop thread.
00069   void set_upcall_thread (void);
00070 
00071   /// Is there any thread running as a leader?
00072   int leader_available (void) const;
00073 
00074   /// A server thread is making a request.
00075   void set_client_thread (void);
00076 
00077   /// A server thread has finished is making a request.
00078   void reset_client_thread (void);
00079 
00080   /// Wait on the Leader/Followers loop until one event happens.
00081   /**
00082    * @param event The event we wait for, the loop iterates until the
00083    * event is sucessful, or it fails due to timeout, and error or a
00084    * connection closed.
00085    * @param transport The transport attached to the event
00086    * @param max_wait_time Limit the time spent on the loop
00087    * @param return Returns -1 on error, 0 or non-zero value
00088    *  otherwise.
00089    *
00090    * @todo Document this better, split the Follower code to the
00091    * TAO_LF_Follower class, we probably don't need the transport
00092    * object.
00093    */
00094   int wait_for_event (TAO_LF_Event *event,
00095                       TAO_Transport *transport,
00096                       ACE_Time_Value *max_wait_time);
00097 
00098   /// The current thread has become the leader thread in the
00099   /// client side leader-follower set.
00100   void set_client_leader_thread (void) ;
00101 
00102   /// The current thread is no longer the leader thread in the client
00103   /// side leader-follower set.
00104   void reset_client_leader_thread (void) ;
00105 
00106   /// sets the thread ID of the leader thread in the leader-follower
00107   /// model
00108   void set_client_leader_thread (ACE_thread_t thread_ID);
00109 
00110   /// checks if we are a leader thread
00111   int is_client_leader_thread (void) const;
00112 
00113   /**
00114    * A leader thread is relinquishing its role, unless there are more
00115    * leader threads running pick up a follower (if there is any) to
00116    * play the leader role.
00117    */
00118   int elect_new_leader (void);
00119 
00120   /** @name Follower creation/destructions
00121    *
00122    * The Leader/Followers set acts as a factory for the Follower
00123    * objects.  Followers are used to represent a thread blocked
00124    * waiting in the Follower set.
00125    *
00126    * The Leader/Followers abstraction keeps a list of the waiting
00127    * followers, so it can wake up one when the leader thread stops
00128    * handling events.
00129    *
00130    * For performance reasons the Leader/Followers set uses a pool (or
00131    * free-list) to keep Follower objects unattached to any thread.  It
00132    * could be tempting to use TSS to keep such followers, after all a
00133    * thread can only need one such Follower object, however, that does
00134    * not work with multiple Leader/Followers sets, consult this bug
00135    * report for more details:
00136    *
00137    * http://ace.cs.wustl.edu/bugzilla/show_bug.cgi?id=296
00138    *
00139    */
00140   //@{
00141   /// Allocate a new follower to the caller.
00142   TAO_LF_Follower *allocate_follower (void);
00143 
00144   /// The caller has finished using a follower.
00145   void release_follower (TAO_LF_Follower *);
00146   //@}
00147 
00148   /** @name Follower Set Operations
00149    *
00150    */
00151   //@{
00152   /// Add a new follower to the set
00153   void add_follower (TAO_LF_Follower *follower);
00154 
00155   /// Removes a follower from the leader-follower set
00156   void remove_follower (TAO_LF_Follower *follower);
00157 
00158   /// Checks if there are any followers available
00159   /**
00160    * @return 1 if there follower set is not empty
00161    */
00162   int follower_available (void) const;
00163 
00164   //@}
00165 
00166   /// Get a reference to the underlying mutex
00167   TAO_SYNCH_MUTEX &lock (void);
00168 
00169   /// Provide a pre-initialized reverse lock for the Leader/Followers
00170   /// set.
00171   /**
00172    * The Leader/Followers set mutex must be release during some long
00173    * running operations.  This helper class simplifies the process of
00174    * releasing and reacquiring said mutex.
00175    */
00176   ACE_Reverse_Lock<TAO_SYNCH_MUTEX> &reverse_lock (void);
00177 
00178   /// Check if there are any client threads running
00179   int has_clients (void) const;
00180 
00181   /// Accesor to the reactor
00182   ACE_Reactor *reactor (void);
00183 
00184   /// Called when we are out of leaders.
00185   void no_leaders_available (void);
00186 
00187 private:
00188   /// Shortcut to obtain the TSS resources of the orb core.
00189   TAO_ORB_Core_TSS_Resources *get_tss_resources (void) const;
00190 
00191   /// Wait for the client leader to complete.
00192   int wait_for_client_leader_to_complete (ACE_Time_Value *max_wait_time);
00193 
00194   /**
00195    * Implement the reset_event_loop_thread() method, once the TSS
00196    * resources have been acquired.
00197    * Also used in the set_upcall_thread.
00198    */
00199   void reset_event_loop_thread_i (TAO_ORB_Core_TSS_Resources *tss);
00200 
00201   /** @name Follower Set Operations
00202    *
00203    */
00204   //@{
00205   /// Remote a follower from the Followers set and promote it to the
00206   /// leader role.
00207   /**
00208    * This is a helper routine for elect_new_leader(), after verifying
00209    * that all the pre-conditions are satisfied the Follower set is
00210    * changed and the promoted Follower is signaled.
00211    */
00212   int elect_new_leader_i (void);
00213 
00214   //@}
00215 
00216 private:
00217   /// The orb core
00218   TAO_ORB_Core *orb_core_;
00219 
00220   /// To synchronize access to the members.
00221   TAO_SYNCH_MUTEX lock_;
00222 
00223   /// do protect the access to the following three members
00224   ACE_Reverse_Lock<TAO_SYNCH_MUTEX> reverse_lock_;
00225 
00226   /// Implement the Leader/Followers set using an intrusive list
00227   typedef ACE_Intrusive_List<TAO_LF_Follower> Follower_Set;
00228   Follower_Set follower_set_;
00229 
00230   /// Use a free list to allocate and release Follower objects
00231   Follower_Set follower_free_list_;
00232 
00233   /**
00234    * Count the number of active leaders.
00235    * There could be many leaders in the thread pool (i.e. calling
00236    * ORB::run), and the same leader could show up multiple times as it
00237    * receives nested upcalls and sends more requests.
00238    */
00239   int leaders_;
00240 
00241   /// Count the number of active clients, this is useful to know when
00242   /// to deactivate the reactor
00243   int clients_;
00244 
00245   /// The reactor
00246   ACE_Reactor *reactor_;
00247 
00248   /// Is a client thread the current leader?
00249   int client_thread_is_leader_;
00250 
00251   /// Are server threads waiting for the client leader to complete?
00252   int event_loop_threads_waiting_;
00253 
00254   /// Condition variable for server threads waiting for the client
00255   /// leader to complete.
00256   TAO_SYNCH_CONDITION event_loop_threads_condition_;
00257 
00258   /// Leader/Follower class uses this method to notify the system that
00259   /// we are out of leaders.
00260   TAO_New_Leader_Generator *new_leader_generator_;
00261 };
00262 
00263 class TAO_Export TAO_LF_Client_Thread_Helper
00264 {
00265 public:
00266   /// Constructor
00267   TAO_LF_Client_Thread_Helper (TAO_Leader_Follower &leader_follower);
00268 
00269   /// Destructor
00270   ~TAO_LF_Client_Thread_Helper (void);
00271 
00272 private:
00273   /// Reference to leader/followers object.
00274   TAO_Leader_Follower &leader_follower_;
00275 };
00276 
00277 class TAO_Export TAO_LF_Client_Leader_Thread_Helper
00278 {
00279 public:
00280   /// Constructor
00281   TAO_LF_Client_Leader_Thread_Helper (TAO_Leader_Follower &leader_follower);
00282 
00283   /// Destructor
00284   ~TAO_LF_Client_Leader_Thread_Helper (void);
00285 
00286 private:
00287   /// Reference to leader/followers object.
00288   TAO_Leader_Follower &leader_follower_;
00289 };
00290 
00291 TAO_END_VERSIONED_NAMESPACE_DECL
00292 
00293 #if defined (__ACE_INLINE__)
00294 # include "tao/Leader_Follower.i"
00295 #endif /* __ACE_INLINE__ */
00296 
00297 #include /**/ "ace/post.h"
00298 
00299 #endif /* TAO_LEADER_FOLLOWER_H */

Generated on Thu Nov 9 11:54:14 2006 for TAO by doxygen 1.3.6