00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file LF_Event.h 00006 * 00007 * $Id: LF_Event.h 76687 2007-01-29 19:18:13Z johnnyw $ 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, TAO_Leader_Follower &lf); 00111 00112 /// Return 1 if the condition was satisfied successfully, 0 if it 00113 /// has not 00114 virtual int successful (void) const = 0 ; 00115 00116 /// Return 1 if an error was detected while waiting for the 00117 /// event 00118 virtual int error_detected (void) const = 0; 00119 00120 /// Check if we should keep waiting. 00121 int keep_waiting (void); 00122 //@} 00123 00124 /// Reset the state, irrespective of the previous states 00125 void reset_state (int new_state); 00126 00127 protected: 00128 00129 /// Validate the state change 00130 virtual void state_changed_i (int new_state) = 0; 00131 00132 /// Check whether we have reached the final state.. 00133 virtual int is_state_final (void) = 0; 00134 00135 private: 00136 00137 /// Set the state irrespective of anything. 00138 virtual void set_state (int new_state); 00139 00140 protected: 00141 /// The current state 00142 int state_; 00143 00144 /// The bounded follower 00145 TAO_LF_Follower *follower_; 00146 }; 00147 00148 TAO_END_VERSIONED_NAMESPACE_DECL 00149 00150 #if defined (__ACE_INLINE__) 00151 # include "tao/LF_Event.inl" 00152 #endif /* __ACE_INLINE__ */ 00153 00154 #include /**/ "ace/post.h" 00155 00156 #endif /* TAO_LF_EVENT_H */