00001 // -*- C++ -*- 00002 /** 00003 * @file EC_ProxyConsumer.h 00004 * 00005 * EC_ProxyConsumer.h,v 1.41 2006/03/15 07:52:22 jtc Exp 00006 * 00007 * @author Carlos O'Ryan (coryan@cs.wustl.edu) 00008 * 00009 * Based on previous work by Tim Harrison (harrison@cs.wustl.edu) and 00010 * other members of the DOC group. More details can be found in: 00011 * 00012 * http://doc.ece.uci.edu/~coryan/EC/index.html 00013 */ 00014 00015 #ifndef TAO_EC_PROXYCONSUMER_H 00016 #define TAO_EC_PROXYCONSUMER_H 00017 00018 #include /**/ "ace/pre.h" 00019 00020 #include /**/ "orbsvcs/Event/event_serv_export.h" 00021 00022 #include "orbsvcs/RtecEventChannelAdminS.h" 00023 00024 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00025 # pragma once 00026 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00027 00028 TAO_BEGIN_VERSIONED_NAMESPACE_DECL 00029 00030 class TAO_EC_Event_Channel_Base; 00031 class TAO_EC_ProxyPushSupplier; 00032 class TAO_EC_Supplier_Filter; 00033 00034 /** 00035 * @class TAO_EC_ProxyPushConsumer 00036 * 00037 * @brief ProxyPushConsumer 00038 * 00039 * Implement the RtecEventChannelAdmin::ProxyPushConsumer interface, 00040 * remember that this class is used to communicate with a 00041 * PushSupplier, so, in effect, this is the ambassador for a 00042 * supplier inside the event channel. 00043 * 00044 * <H2>Memory Management</H2> 00045 * It makes a copy of the SupplierQOS and the supplier object 00046 * reference. 00047 * It uses bind/unbind to control the lifetime of the 00048 * Supplier_Filter object. 00049 * The object commits suicide when disconnect_push_consumer() is 00050 * called. 00051 * 00052 * <H2>Locking</H2> 00053 * No provisions for locking, access must be serialized 00054 * externally. 00055 */ 00056 class TAO_RTEvent_Serv_Export TAO_EC_ProxyPushConsumer 00057 { 00058 public: 00059 typedef RtecEventChannelAdmin::ProxyPushConsumer Interface; 00060 typedef RtecEventChannelAdmin::ProxyPushConsumer_var _var_type; 00061 typedef RtecEventChannelAdmin::ProxyPushConsumer_ptr _ptr_type; 00062 00063 /// constructor... 00064 TAO_EC_ProxyPushConsumer (TAO_EC_Event_Channel_Base* event_channel); 00065 00066 /// destructor... 00067 virtual ~TAO_EC_ProxyPushConsumer (void); 00068 00069 /// Activate in the POA 00070 virtual void activate ( 00071 RtecEventChannelAdmin::ProxyPushConsumer_ptr &proxy 00072 ACE_ENV_ARG_DECL) 00073 ACE_THROW_SPEC ((CORBA::SystemException)) = 0; 00074 00075 /// Deactivate from the POA 00076 virtual void deactivate (ACE_ENV_SINGLE_ARG_DECL); 00077 00078 /// Disconnect this from 00079 virtual void disconnect_push_consumer ( 00080 ACE_ENV_SINGLE_ARG_DECL) = 0; 00081 00082 /// Return 0 if no supplier is connected... 00083 CORBA::Boolean is_connected (void) const; 00084 00085 /// Return the consumer object reference. It returns nil() if it has 00086 /// not connected yet. 00087 RtecEventComm::PushSupplier_ptr supplier (void) const; 00088 00089 /// The QoS (subscription) used to connect to the EC. 00090 const RtecEventChannelAdmin::SupplierQOS& publications (void) const; 00091 00092 /** 00093 * Invoke the _non_existent() pseudo-operation on the supplier. If 00094 * it is disconnected then it returns true and sets the 00095 * <disconnected> flag. 00096 */ 00097 CORBA::Boolean supplier_non_existent (CORBA::Boolean_out disconnected 00098 ACE_ENV_ARG_DECL); 00099 00100 /// Concrete implementations can use this methods to keep track of 00101 /// the consumers interested in this events. 00102 virtual void connected (TAO_EC_ProxyPushSupplier* supplier 00103 ACE_ENV_ARG_DECL); 00104 virtual void reconnected (TAO_EC_ProxyPushSupplier* supplier 00105 ACE_ENV_ARG_DECL); 00106 virtual void disconnected (TAO_EC_ProxyPushSupplier* supplier 00107 ACE_ENV_ARG_DECL); 00108 00109 /// Usually implemented as no-ops, but some configurations may 00110 /// require this methods. 00111 virtual void connected (TAO_EC_ProxyPushConsumer* consumer 00112 ACE_ENV_ARG_DECL); 00113 virtual void reconnected (TAO_EC_ProxyPushConsumer* consumer 00114 ACE_ENV_ARG_DECL); 00115 virtual void disconnected (TAO_EC_ProxyPushConsumer* consumer 00116 ACE_ENV_ARG_DECL); 00117 00118 /// The event channel is shutting down 00119 virtual void shutdown (ACE_ENV_SINGLE_ARG_DECL_NOT_USED); 00120 00121 /// The QoS (subscription) used to connect to the EC, assumes the 00122 /// locks are held, use with care! 00123 const RtecEventChannelAdmin::SupplierQOS& publications_i (void) const; 00124 00125 /// Increment and decrement the reference count. 00126 CORBA::ULong _incr_refcnt (void); 00127 CORBA::ULong _decr_refcnt (void); 00128 00129 00130 protected: 00131 /// Set the supplier, used by some implementations to change the 00132 /// policies used when invoking operations on the supplier. 00133 void supplier (RtecEventComm::PushSupplier_ptr supplier); 00134 void supplier_i (RtecEventComm::PushSupplier_ptr supplier); 00135 00136 friend class TAO_EC_ProxyPushConsumer_Guard; 00137 // The guard needs access to the following protected methods. 00138 00139 /// The private version (without locking) of is_connected(). 00140 CORBA::Boolean is_connected_i (void) const; 00141 00142 /// Return the current filter, assumes the locks are held. 00143 TAO_EC_Supplier_Filter *filter_i (void) const; 00144 00145 /// Release the filter and the supplier 00146 void cleanup_i (void); 00147 00148 /// The supplier admin, used for activation and memory managment. 00149 TAO_EC_Event_Channel_Base* event_channel_; 00150 00151 /// The locking strategy. 00152 ACE_Lock* lock_; 00153 00154 /// The reference count. 00155 CORBA::ULong refcount_; 00156 00157 /// The supplier.... 00158 RtecEventComm::PushSupplier_var supplier_; 00159 00160 /// If the flag is not zero then we are connected, notice that the 00161 /// supplier can be nil. 00162 int connected_; 00163 00164 /// The publication and QoS information... 00165 RtecEventChannelAdmin::SupplierQOS qos_; 00166 00167 /// Store the default POA. 00168 PortableServer::POA_var default_POA_; 00169 00170 /// The strategy to do filtering close to the supplier 00171 TAO_EC_Supplier_Filter* filter_; 00172 00173 private: 00174 /// Template method hooks. 00175 virtual void shutdown_hook (ACE_ENV_SINGLE_ARG_DECL); 00176 virtual void refcount_zero_hook (void); 00177 00178 virtual PortableServer::ObjectId 00179 object_id (ACE_ENV_SINGLE_ARG_DECL) 00180 ACE_THROW_SPEC ((CORBA::SystemException)) = 0; 00181 }; 00182 00183 // **************************************************************** 00184 00185 /** 00186 * @class TAO_EC_ProxyPushConsumer_Guard 00187 * 00188 * @brief A Guard for the ProxyPushConsumer reference count 00189 * 00190 * This is a helper class used in the implementation of 00191 * ProxyPushConumer. It provides a Guard mechanism to increment 00192 * the reference count on the proxy and its filter, eliminating 00193 * the need to hold mutexes during long operations. 00194 */ 00195 class TAO_RTEvent_Serv_Export TAO_EC_ProxyPushConsumer_Guard 00196 { 00197 public: 00198 /// Constructor 00199 TAO_EC_ProxyPushConsumer_Guard (ACE_Lock *lock, 00200 CORBA::ULong &refcount, 00201 TAO_EC_Event_Channel_Base *ec, 00202 TAO_EC_ProxyPushConsumer *proxy); 00203 00204 /// Destructor 00205 ~TAO_EC_ProxyPushConsumer_Guard (void); 00206 00207 /// Returns 1 if the reference count successfully acquired 00208 int locked (void) const; 00209 00210 TAO_EC_Supplier_Filter *filter; 00211 00212 private: 00213 /// The lock used to protect the reference count 00214 ACE_Lock *lock_; 00215 00216 /// The reference count 00217 CORBA::ULong &refcount_; 00218 00219 /// The event channel used to destroy the proxy 00220 TAO_EC_Event_Channel_Base *event_channel_; 00221 00222 /// The proxy whose lifetime is controlled by the reference count 00223 TAO_EC_ProxyPushConsumer *proxy_; 00224 00225 /// This flag is set to 1 if the reference count was successfully 00226 /// acquired. 00227 int locked_; 00228 }; 00229 00230 TAO_END_VERSIONED_NAMESPACE_DECL 00231 00232 #if defined (__ACE_INLINE__) 00233 #include "orbsvcs/Event/EC_ProxyConsumer.i" 00234 #endif /* __ACE_INLINE__ */ 00235 00236 #include /**/ "ace/post.h" 00237 00238 #endif /* TAO_EC_PROXYCONSUMER_H */