00001 // -*- C++ -*- 00002 00003 /** 00004 * @file EC_Supplier_Filter.h 00005 * 00006 * $Id: EC_Supplier_Filter.h 76589 2007-01-25 18:04:11Z elliott_c $ 00007 * 00008 * @author Carlos O'Ryan (coryan@cs.wustl.edu) 00009 * 00010 * Based on previous work by Tim Harrison (harrison@cs.wustl.edu) and 00011 * other members of the DOC group. More details can be found in: 00012 * 00013 * http://doc.ece.uci.edu/~coryan/EC/index.html 00014 */ 00015 00016 #ifndef TAO_EC_SUPPLIER_FILTER_H 00017 #define TAO_EC_SUPPLIER_FILTER_H 00018 00019 #include /**/ "ace/pre.h" 00020 00021 #include "orbsvcs/RtecEventCommC.h" 00022 #include "orbsvcs/ESF/ESF_Worker.h" 00023 00024 #include /**/ "orbsvcs/Event/event_serv_export.h" 00025 00026 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00027 # pragma once 00028 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00029 00030 TAO_BEGIN_VERSIONED_NAMESPACE_DECL 00031 00032 class TAO_EC_ProxyPushSupplier; 00033 class TAO_EC_ProxyPushConsumer; 00034 class TAO_EC_QOS_Info; 00035 00036 /** 00037 * @class TAO_EC_Supplier_Filter 00038 * 00039 * @brief The strategy to filter close to the supplier. 00040 * 00041 * After an event is received by the a ProxyPushConsumer it must 00042 * be dispatched to the right set of ProxyPushSuppliers; 00043 * determining this set is the task of this class. 00044 * Notice that this is in fact a filter, and enforces (in part) 00045 * the subscriptions and publications of the Event Service 00046 * clients. 00047 * Several implementations are possible: 00048 * - Each ProxyPushConsumer keeps a list of ProxyPushSuppliers, 00049 * using the subscriptions and publications to find potential 00050 * matches. 00051 * - Each ProxyPushConsumer keeps several such lists, indexed by 00052 * event type and/or source, this has the advantage of further 00053 * minimizing the set of ProxyPushSuppliers invoked. 00054 * - A single list of consumers is kept (global for the event 00055 * channel), such a list results is faster updates and requires 00056 * an smaller memory footprint. 00057 * - Multiple global lists are kept, indexed by type and/or 00058 * source, this is a tradeoff between the solutions above. 00059 * - No list is kept, the events are sent to the consumers which 00060 * must filter out what they want, this is good when no 00061 * filtering is wanted or when the amount of filtering is coarse 00062 * i.e. each event goes to a large subset of the 00063 * ProxyPushSuppliers. 00064 * Different applications will require to use different 00065 * implementations of this class; as usual the EC_Factory will 00066 * create the right instance. 00067 */ 00068 class TAO_RTEvent_Serv_Export TAO_EC_Supplier_Filter 00069 { 00070 public: 00071 /// Destructor 00072 virtual ~TAO_EC_Supplier_Filter (void); 00073 00074 /** 00075 * Whenever a ProxyPushConsumer is initialized it calls this method 00076 * to inform the Supplier_Filter of its identity. 00077 * Strategies that do not keep ProxyPushConsumer specific 00078 * information, or that are shared between multiple 00079 * ProxyPushConsumers can ignore this message. 00080 */ 00081 virtual void bind (TAO_EC_ProxyPushConsumer* consumer) = 0; 00082 00083 /** 00084 * Wheneve a ProxyPushConsumer is about to be destroyed it calls 00085 * this method to inform the Supplier_Filter that it should 00086 * release any resources related to it. 00087 * Supplier_Filter strategies that are bound to a particular 00088 * ProxyConsumer can use this opportunity to destroy themselves; 00089 * filter strategies that do not keep ProxyPushConsumer specific 00090 * information can simply ignore the message. 00091 */ 00092 virtual void unbind (TAO_EC_ProxyPushConsumer* consumer) = 0; 00093 00094 /// Concrete implementations can use this methods to keep track of 00095 /// the consumers interested in this events. 00096 virtual void connected (TAO_EC_ProxyPushSupplier *supplier) = 0; 00097 virtual void reconnected (TAO_EC_ProxyPushSupplier *supplier) = 0; 00098 virtual void disconnected (TAO_EC_ProxyPushSupplier *supplier) = 0; 00099 00100 /// The event channel is shutting down. 00101 virtual void shutdown (void) = 0; 00102 00103 /// The ProxyPushConsumer delegates on this class to actually send 00104 /// the event. 00105 virtual void push (const RtecEventComm::EventSet &event, 00106 TAO_EC_ProxyPushConsumer *consumer) = 0; 00107 00108 /// Events are first scheduled by the TAO_EC_Scheduling_Strategy, 00109 /// and then pushed through this class again. 00110 virtual void push_scheduled_event (RtecEventComm::EventSet &event, 00111 const TAO_EC_QOS_Info &event_info) = 0; 00112 00113 /// Increment and decrement the reference count, locking must be 00114 /// provided by the user. 00115 virtual CORBA::ULong _incr_refcnt (void) = 0; 00116 virtual CORBA::ULong _decr_refcnt (void) = 0; 00117 }; 00118 00119 // **************************************************************** 00120 00121 class TAO_EC_Filter_Worker : public TAO_ESF_Worker<TAO_EC_ProxyPushSupplier> 00122 { 00123 public: 00124 TAO_EC_Filter_Worker (RtecEventComm::EventSet &event, 00125 const TAO_EC_QOS_Info &event_info); 00126 00127 virtual void work (TAO_EC_ProxyPushSupplier *supplier); 00128 00129 private: 00130 /// The event we push on each case, use a reference to avoid copies. 00131 RtecEventComm::EventSet &event_; 00132 00133 /// The QoS info propagated on each event. 00134 const TAO_EC_QOS_Info &event_info_; 00135 }; 00136 00137 TAO_END_VERSIONED_NAMESPACE_DECL 00138 00139 #if defined (__ACE_INLINE__) 00140 #include "orbsvcs/Event/EC_Supplier_Filter.inl" 00141 #endif /* __ACE_INLINE__ */ 00142 00143 #include /**/ "ace/post.h" 00144 00145 #endif /* TAO_EC_SUPPLIER_FILTER_H */