00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file LF_Event.h 00006 * 00007 * LF_Event.h,v 1.15 2006/04/26 17:12:47 mesnier_p Exp 00008 * 00009 * @author Carlos O'Ryan <coryan@uci.edu> 00010 */ 00011 //============================================================================= 00012 00013 #ifndef TAO_LF_EVENT_H 00014 #define TAO_LF_EVENT_H 00015 00016 #include /**/ "ace/pre.h" 00017 00018 #include "tao/TAO_Export.h" 00019 00020 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00021 # pragma once 00022 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00023 00024 #include "tao/Versioned_Namespace.h" 00025 00026 TAO_BEGIN_VERSIONED_NAMESPACE_DECL 00027 00028 class TAO_LF_Follower; 00029 class TAO_Leader_Follower; 00030 00031 /** 00032 * @class TAO_LF_Event 00033 * 00034 * @brief Use the Leader/Follower loop to wait for one specific event. 00035 * 00036 * The Leader/Follower event loop is used to wait for incoming 00037 * responses, as well as to wait for all the data to be flushed. 00038 * This class encapsulates this event loop. It uses Template Method to 00039 * parametrize the 'waited for' predicate (i.e. reply received or 00040 * message sent or connection establishment etc.) 00041 * 00042 * @todo Implementing the Leader/Followers loop in this class, as 00043 * well as the callbacks to communicate that an event has completed 00044 * leads to excessive coupling. A better design would use a separate 00045 * class to signal the events, that would allow us to remove the 00046 * Leader/Followers logic from the ORB. However, that requires other 00047 * major changes and it somewhat complicates the design. 00048 * 00049 */ 00050 class TAO_Export TAO_LF_Event 00051 { 00052 public: 00053 00054 friend class TAO_Leader_Follower; 00055 00056 /// Constructor 00057 TAO_LF_Event (void); 00058 00059 /// Destructor 00060 virtual ~TAO_LF_Event (void); 00061 00062 /// Bind a follower 00063 /** 00064 * An event can be waited on by at most one follower thread, this 00065 * method is used to bind the waiting thread to the event, in order 00066 * to let the event signal any important state changes. 00067 * 00068 * This is virtual to allow the LF_Multi_Event derived type share 00069 * the follower with all the subordinate LF_CH_Events. 00070 * 00071 * @return -1 if the LF_Event is already bound, 0 otherwise 00072 */ 00073 virtual int bind (TAO_LF_Follower *follower); 00074 00075 /// Unbind the follower 00076 virtual int unbind (void); 00077 00078 //@{ 00079 /** @name State management 00080 * 00081 * A Leader/Followers event goes through several states during its 00082 * lifetime. We use an enum to represent those states and state 00083 * changes are validated according to the rules defined in the 00084 * concrete classes. We treat the states as finite states in a 00085 * FSM. The possible sequence of states through which the FSM 00086 * migrates is defined in the concrete classes. 00087 */ 00088 enum { 00089 /// The event is created, and is in initial state 00090 LFS_IDLE = 0, 00091 /// The event is active 00092 LFS_ACTIVE, 00093 /// The event is waiting for connection completion. 00094 LFS_CONNECTION_WAIT, 00095 /// The event has completed successfully 00096 LFS_SUCCESS, 00097 /// A failure has been detected while the event was active 00098 LFS_FAILURE, 00099 /// The event has timed out 00100 LFS_TIMEOUT, 00101 /// The connection was closed. 00102 LFS_CONNECTION_CLOSED 00103 }; 00104 00105 /** 00106 * Virtual methods for this class hierarchy.. 00107 */ 00108 /// Accessor to change the state. The state isnt changed unless 00109 /// certain conditions are satisfied. 00110 void state_changed (int new_state, 00111 TAO_Leader_Follower &lf); 00112 00113 /// Return 1 if the condition was satisfied successfully, 0 if it 00114 /// has not 00115 virtual int successful (void) const = 0 ; 00116 00117 /// Return 1 if an error was detected while waiting for the 00118 /// event 00119 virtual int error_detected (void) const = 0; 00120 00121 /// Check if we should keep waiting. 00122 int keep_waiting (void); 00123 //@} 00124 00125 /// Reset the state, irrespective of the previous states 00126 void reset_state (int new_state); 00127 00128 protected: 00129 00130 /// Validate the state change 00131 virtual void state_changed_i (int new_state) = 0; 00132 00133 /// Check whether we have reached the final state.. 00134 virtual int is_state_final (void) = 0; 00135 00136 private: 00137 00138 /// Set the state irrespective of anything. 00139 virtual void set_state (int new_state); 00140 00141 protected: 00142 /// The current state 00143 int state_; 00144 00145 /// The bounded follower 00146 TAO_LF_Follower *follower_; 00147 }; 00148 00149 TAO_END_VERSIONED_NAMESPACE_DECL 00150 00151 #if defined (__ACE_INLINE__) 00152 # include "tao/LF_Event.inl" 00153 #endif /* __ACE_INLINE__ */ 00154 00155 #include /**/ "ace/post.h" 00156 00157 #endif /* TAO_LF_EVENT_H */