00001 // -*- C++ -*- 00002 /** 00003 * @file EC_ProxySupplier.h 00004 * 00005 * $Id: EC_ProxySupplier.h 77052 2007-02-12 18:59:05Z 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_PROXYSUPPLIER_H 00016 #define TAO_EC_PROXYSUPPLIER_H 00017 00018 #include /**/ "ace/pre.h" 00019 00020 #include "orbsvcs/RtecEventChannelAdminS.h" 00021 00022 #include "orbsvcs/Event/EC_Filter.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_ProxyPushConsumer; 00032 00033 /** 00034 * @class TAO_EC_ProxyPushSupplier 00035 * 00036 * @brief ProxyPushSupplier 00037 * 00038 * Implement the RtecEventChannelAdmin::ProxyPushSupplier interface, 00039 * remember that this class is used to communicate with a 00040 * PushConsumer, so, in effect, this is the ambassador for a 00041 * consumer inside the event channel. 00042 * 00043 * <H2>Memory Management</H2> 00044 * It does not assume ownership of the TAO_EC_Dispatching object. 00045 * It makes a copy of the ConsumerQOS and the consumer object 00046 * reference. 00047 * 00048 * <H2>Locking</H2> 00049 * Locking is strategized, the event channel acts as a factory for 00050 * the locking strategies. 00051 * 00052 * @todo We don't need to provide a trivial filter, the object itself 00053 * could short-circuit the filter() ---> push() cycle when the EC 00054 * is properly configured, we need to explore this... 00055 */ 00056 class TAO_RTEvent_Serv_Export TAO_EC_ProxyPushSupplier : public TAO_EC_Filter 00057 { 00058 public: 00059 typedef RtecEventChannelAdmin::ProxyPushSupplier Interface; 00060 typedef RtecEventChannelAdmin::ProxyPushSupplier_var _var_type; 00061 typedef RtecEventChannelAdmin::ProxyPushSupplier_ptr _ptr_type; 00062 00063 /// Constructor... 00064 TAO_EC_ProxyPushSupplier (TAO_EC_Event_Channel_Base* event_channel, int validate_connection); 00065 00066 /// Destructor... 00067 virtual ~TAO_EC_ProxyPushSupplier (void); 00068 00069 /// Activate in the POA 00070 virtual void activate ( 00071 RtecEventChannelAdmin::ProxyPushSupplier_ptr &proxy) = 0; 00072 00073 /// Deactivate from the POA 00074 virtual void deactivate (void) throw (); 00075 00076 /// Disconnect this from 00077 virtual void disconnect_push_supplier () = 0; 00078 00079 /// Return false if no consumer is connected... 00080 CORBA::Boolean is_connected (void) const; 00081 00082 /// Return true if it is suspended. 00083 CORBA::Boolean is_suspended (void) const; 00084 00085 /** 00086 * Return the consumer object reference. It returns nil() if it has 00087 * not connected yet. 00088 */ 00089 RtecEventComm::PushConsumer_ptr consumer (void) const; 00090 00091 /// The QoS (subscription) used to connect to the EC. 00092 const RtecEventChannelAdmin::ConsumerQOS& subscriptions (void) const; 00093 00094 /// Concrete implementations can use this methods to keep track of 00095 /// the suppliers that publish its events. 00096 virtual void connected (TAO_EC_ProxyPushConsumer *consumer); 00097 virtual void reconnected (TAO_EC_ProxyPushConsumer *consumer); 00098 virtual void disconnected (TAO_EC_ProxyPushConsumer *consumer); 00099 00100 /// Usually implemented as no-ops, but some configurations may 00101 /// require this methods. 00102 virtual void connected (TAO_EC_ProxyPushSupplier *supplier); 00103 virtual void reconnected (TAO_EC_ProxyPushSupplier *supplier); 00104 virtual void disconnected (TAO_EC_ProxyPushSupplier *supplier); 00105 00106 /// The event channel is shutting down 00107 virtual void shutdown (void); 00108 00109 /// Pushes to the consumer, verifies that it is connected and that it 00110 /// is not suspended. 00111 /** 00112 * These methods take @a consumer argument because during the time 00113 * the filters have been processing the event, this proxy's consumer 00114 * may have changed. 00115 */ 00116 void push_to_consumer (RtecEventComm::PushConsumer_ptr consumer, 00117 const RtecEventComm::EventSet &event); 00118 void reactive_push_to_consumer (RtecEventComm::PushConsumer_ptr consumer, 00119 const RtecEventComm::EventSet &event); 00120 00121 /** 00122 * Invoke the _non_existent() pseudo-operation on the consumer. If 00123 * it is disconnected then it returns true and sets the 00124 * <disconnected> flag. 00125 */ 00126 CORBA::Boolean consumer_non_existent (CORBA::Boolean_out disconnected); 00127 00128 /// Increment and decrement the reference count. 00129 CORBA::ULong _incr_refcnt (void); 00130 CORBA::ULong _decr_refcnt (void); 00131 00132 // = The TAO_EC_Filter methods, only push() is implemented... 00133 virtual int filter (const RtecEventComm::EventSet &event, 00134 TAO_EC_QOS_Info& qos_info); 00135 virtual int filter_nocopy (RtecEventComm::EventSet &event, 00136 TAO_EC_QOS_Info &qos_info); 00137 virtual void push (const RtecEventComm::EventSet &event, 00138 TAO_EC_QOS_Info& qos_info); 00139 virtual void push_nocopy (RtecEventComm::EventSet &event, 00140 TAO_EC_QOS_Info &qos_info); 00141 virtual void clear (void); 00142 virtual CORBA::ULong max_event_size (void) const; 00143 virtual int can_match (const RtecEventComm::EventHeader &header) const; 00144 virtual int add_dependencies (const RtecEventComm::EventHeader &header, 00145 const TAO_EC_QOS_Info &qos_info); 00146 00147 protected: 00148 /// Set the consumer, used by some implementations to change the 00149 /// policies used when invoking operations on the consumer. 00150 void consumer (RtecEventComm::PushConsumer_ptr consumer); 00151 void consumer_i (RtecEventComm::PushConsumer_ptr consumer); 00152 00153 void suspend_connection_i (void); 00154 void resume_connection_i (void); 00155 void suspend_connection_locked (void); 00156 void resume_connection_locked (void); 00157 00158 /// The private version (without locking) of is_connected(). 00159 CORBA::Boolean is_connected_i (void) const; 00160 00161 /// Release the child and the consumer 00162 void cleanup_i (void); 00163 00164 /// The Event Channel that owns this object. 00165 TAO_EC_Event_Channel_Base* event_channel_; 00166 00167 /// The locking strategy. 00168 ACE_Lock* lock_; 00169 00170 /// The reference count. 00171 CORBA::ULong refcount_; 00172 00173 /// The consumer.... 00174 RtecEventComm::PushConsumer_var consumer_; 00175 00176 /// Is this consumer suspended? 00177 CORBA::Boolean suspended_; 00178 00179 /// The subscription and QoS information... 00180 RtecEventChannelAdmin::ConsumerQOS qos_; 00181 00182 /// Store the default POA. 00183 PortableServer::POA_var default_POA_; 00184 00185 /// The filter object 00186 TAO_EC_Filter* child_; 00187 00188 /// Validate the connection to consumer on connect 00189 int consumer_validate_connection_; 00190 private: 00191 00192 /// Template method hooks. 00193 virtual void refcount_zero_hook (void); 00194 virtual void pre_dispatch_hook (RtecEventComm::EventSet&); 00195 virtual PortableServer::ObjectId 00196 object_id (void) 00197 = 0; 00198 }; 00199 00200 TAO_END_VERSIONED_NAMESPACE_DECL 00201 00202 #if defined (__ACE_INLINE__) 00203 #include "orbsvcs/Event/EC_ProxySupplier.inl" 00204 #endif /* __ACE_INLINE__ */ 00205 00206 #include /**/ "ace/post.h" 00207 00208 #endif /* TAO_EC_PROXYSUPPLIER_H */