00001 // -*- C++ -*- 00002 /** 00003 * @file EC_ProxyConsumer.h 00004 * 00005 * $Id: EC_ProxyConsumer.h 77001 2007-02-12 07:54:49Z johnnyw $ 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 = 0; 00073 00074 /// Deactivate from the POA 00075 virtual void deactivate (void); 00076 00077 /// Disconnect this from 00078 virtual void disconnect_push_consumer () = 0; 00079 00080 /// Return 0 if no supplier is connected... 00081 CORBA::Boolean is_connected (void) const; 00082 00083 /// Return the consumer object reference. It returns nil() if it has 00084 /// not connected yet. 00085 RtecEventComm::PushSupplier_ptr supplier (void) const; 00086 00087 /// The QoS (subscription) used to connect to the EC. 00088 const RtecEventChannelAdmin::SupplierQOS& publications (void) const; 00089 00090 /** 00091 * Invoke the _non_existent() pseudo-operation on the supplier. If 00092 * it is disconnected then it returns true and sets the 00093 * <disconnected> flag. 00094 */ 00095 CORBA::Boolean supplier_non_existent (CORBA::Boolean_out disconnected); 00096 00097 /// Concrete implementations can use this methods to keep track of 00098 /// the consumers interested in this events. 00099 virtual void connected (TAO_EC_ProxyPushSupplier* supplier); 00100 virtual void reconnected (TAO_EC_ProxyPushSupplier* supplier); 00101 virtual void disconnected (TAO_EC_ProxyPushSupplier* supplier); 00102 00103 /// Usually implemented as no-ops, but some configurations may 00104 /// require this methods. 00105 virtual void connected (TAO_EC_ProxyPushConsumer* consumer); 00106 virtual void reconnected (TAO_EC_ProxyPushConsumer* consumer); 00107 virtual void disconnected (TAO_EC_ProxyPushConsumer* consumer); 00108 00109 /// The event channel is shutting down 00110 virtual void shutdown (void); 00111 00112 /// The QoS (subscription) used to connect to the EC, assumes the 00113 /// locks are held, use with care! 00114 const RtecEventChannelAdmin::SupplierQOS& publications_i (void) const; 00115 00116 /// Increment and decrement the reference count. 00117 CORBA::ULong _incr_refcnt (void); 00118 CORBA::ULong _decr_refcnt (void); 00119 00120 00121 protected: 00122 /// Set the supplier, used by some implementations to change the 00123 /// policies used when invoking operations on the supplier. 00124 void supplier (RtecEventComm::PushSupplier_ptr supplier); 00125 void supplier_i (RtecEventComm::PushSupplier_ptr supplier); 00126 00127 friend class TAO_EC_ProxyPushConsumer_Guard; 00128 // The guard needs access to the following protected methods. 00129 00130 /// The private version (without locking) of is_connected(). 00131 CORBA::Boolean is_connected_i (void) const; 00132 00133 /// Return the current filter, assumes the locks are held. 00134 TAO_EC_Supplier_Filter *filter_i (void) const; 00135 00136 /// Release the filter and the supplier 00137 void cleanup_i (void); 00138 00139 /// The supplier admin, used for activation and memory managment. 00140 TAO_EC_Event_Channel_Base* event_channel_; 00141 00142 /// The locking strategy. 00143 ACE_Lock* lock_; 00144 00145 /// The reference count. 00146 CORBA::ULong refcount_; 00147 00148 /// The supplier.... 00149 RtecEventComm::PushSupplier_var supplier_; 00150 00151 /// If the flag is not zero then we are connected, notice that the 00152 /// supplier can be nil. 00153 int connected_; 00154 00155 /// The publication and QoS information... 00156 RtecEventChannelAdmin::SupplierQOS qos_; 00157 00158 /// Store the default POA. 00159 PortableServer::POA_var default_POA_; 00160 00161 /// The strategy to do filtering close to the supplier 00162 TAO_EC_Supplier_Filter* filter_; 00163 00164 private: 00165 /// Template method hooks. 00166 virtual void shutdown_hook (void); 00167 virtual void refcount_zero_hook (void); 00168 00169 virtual PortableServer::ObjectId 00170 object_id (void) 00171 = 0; 00172 }; 00173 00174 // **************************************************************** 00175 00176 /** 00177 * @class TAO_EC_ProxyPushConsumer_Guard 00178 * 00179 * @brief A Guard for the ProxyPushConsumer reference count 00180 * 00181 * This is a helper class used in the implementation of 00182 * ProxyPushConumer. It provides a Guard mechanism to increment 00183 * the reference count on the proxy and its filter, eliminating 00184 * the need to hold mutexes during long operations. 00185 */ 00186 class TAO_RTEvent_Serv_Export TAO_EC_ProxyPushConsumer_Guard 00187 { 00188 public: 00189 /// Constructor 00190 TAO_EC_ProxyPushConsumer_Guard (ACE_Lock *lock, 00191 CORBA::ULong &refcount, 00192 TAO_EC_Event_Channel_Base *ec, 00193 TAO_EC_ProxyPushConsumer *proxy); 00194 00195 /// Destructor 00196 ~TAO_EC_ProxyPushConsumer_Guard (void); 00197 00198 /// Returns 1 if the reference count successfully acquired 00199 int locked (void) const; 00200 00201 TAO_EC_Supplier_Filter *filter; 00202 00203 private: 00204 /// The lock used to protect the reference count 00205 ACE_Lock *lock_; 00206 00207 /// The reference count 00208 CORBA::ULong &refcount_; 00209 00210 /// The event channel used to destroy the proxy 00211 TAO_EC_Event_Channel_Base *event_channel_; 00212 00213 /// The proxy whose lifetime is controlled by the reference count 00214 TAO_EC_ProxyPushConsumer *proxy_; 00215 00216 /// This flag is set to 1 if the reference count was successfully 00217 /// acquired. 00218 int locked_; 00219 }; 00220 00221 TAO_END_VERSIONED_NAMESPACE_DECL 00222 00223 #if defined (__ACE_INLINE__) 00224 #include "orbsvcs/Event/EC_ProxyConsumer.inl" 00225 #endif /* __ACE_INLINE__ */ 00226 00227 #include /**/ "ace/post.h" 00228 00229 #endif /* TAO_EC_PROXYCONSUMER_H */