00001 // -*- C++ -*- 00002 /** 00003 * @file EC_Filter.h 00004 * 00005 * $Id: EC_Filter.h 76589 2007-01-25 18:04:11Z elliott_c $ 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_FILTER_H 00016 #define TAO_EC_FILTER_H 00017 00018 #include /**/ "ace/pre.h" 00019 00020 #include "orbsvcs/RtecEventCommC.h" 00021 00022 #include /**/ "orbsvcs/Event/event_serv_export.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_QOS_Info; 00031 00032 /** 00033 * @class TAO_EC_Filter 00034 * 00035 * @brief Abstract base class for the filter hierarchy. 00036 * 00037 * The per-consumer filtering mechanisms. 00038 * The EC needs to filter data passed to the consumers, so it can 00039 * correctly satisfy its subscription requirements. 00040 * This filtering can include correlations, sequences, timeouts, 00041 * etc. each consumer can request different filtering criteria. 00042 * Different filtering objects are associated with each consumer, 00043 * the filters are organized in a hierarchical structure, 00044 * corresponding to the subscription "expression" that the events 00045 * must satisfy. 00046 * The hierarchy is constructed using the "Builder" pattern. 00047 * 00048 * <H2>Memory Management</H2> 00049 * It does *not* assume ownership of its parent. 00050 */ 00051 class TAO_RTEvent_Serv_Export TAO_EC_Filter 00052 { 00053 public: 00054 /// constructor... 00055 TAO_EC_Filter (void); 00056 00057 /// destructor... 00058 virtual ~TAO_EC_Filter (void); 00059 00060 /// Obtain the parent of this filter. 00061 TAO_EC_Filter* parent (void) const; 00062 00063 /// Become the parent of @a child. 00064 void adopt_child (TAO_EC_Filter* child); 00065 00066 /// Matches two event headers. 00067 /// @todo Should we strategize the algorithm used to match headers? 00068 static int matches (const RtecEventComm::EventHeader& rhs, 00069 const RtecEventComm::EventHeader& lhs); 00070 00071 typedef TAO_EC_Filter* value_type; 00072 typedef TAO_EC_Filter* const const_value_type; 00073 typedef const_value_type* ChildrenIterator; 00074 00075 /** 00076 * STL-like iterators 00077 * Filters follow the Composite pattern. All filters expose the same 00078 * interface as if they all had children, but for simple filters the 00079 * iterators return an empty range. 00080 */ 00081 virtual ChildrenIterator begin (void) const; 00082 virtual ChildrenIterator end (void) const; 00083 virtual int size (void) const; 00084 00085 /** 00086 * Filter this event, returns 1 if the event is accepted, 0 00087 * otherwise. 00088 * Notice that there are two versions of the method, if the event is 00089 * not const then filter can take ownership of the event. 00090 * 00091 * @attention There seems to be a disparity in interfaces: Supplier 00092 * always push event sets of size 1 to the EC_ProxyPushSupplier, and 00093 * EC_Filters do not implement handling of sets of more than 1 00094 * event. Then, why is this not enforced by the interface by having 00095 * EC_ProxyPushSupplier take an event rather than a set? 00096 */ 00097 virtual int filter (const RtecEventComm::EventSet& event, 00098 TAO_EC_QOS_Info& qos_info) = 0; 00099 virtual int filter_nocopy (RtecEventComm::EventSet& event, 00100 TAO_EC_QOS_Info& qos_info) = 0; 00101 00102 /** 00103 * This is called by the children when they accept an event and 00104 * which to pass it up. 00105 * Notice that there are two versions of the method, if the event is 00106 * not const then filter can take ownership of the event. 00107 */ 00108 virtual void push (const RtecEventComm::EventSet& event, 00109 TAO_EC_QOS_Info& qos_info) = 0; 00110 virtual void push_nocopy (RtecEventComm::EventSet& event, 00111 TAO_EC_QOS_Info& qos_info) = 0; 00112 00113 /// Clear any saved state, must reset and assume no events have been 00114 /// received. 00115 virtual void clear (void) = 0; 00116 00117 /// Returns the maximum size of the events pushed by this filter. 00118 virtual CORBA::ULong max_event_size (void) const = 0; 00119 00120 /** 00121 * Returns 0 if an event with that header could never be accepted. 00122 * This can used by the suppliers to filter out consumers that 00123 * couldn't possibly be interested in their events. 00124 * The rt_info and 00125 */ 00126 virtual int can_match (const RtecEventComm::EventHeader& header) const = 0; 00127 00128 /** 00129 * This is used for computing the scheduling dependencies: 00130 * 00131 * Leaf filters check if the header could be matched, similar to the 00132 * can_match() method; if it does they return 1, and 0 otherwise. 00133 * Intermediate nodes always return 0. 00134 * 00135 * This is used to build precise dependencies between the suppliers 00136 * and the leaf of the filters that accept that event. Notice that 00137 * only the nodes doing scheduling recurse through the list, so in 00138 * configurations that do no require scheduling the recursion stops 00139 * fairly soon. 00140 */ 00141 virtual int add_dependencies (const RtecEventComm::EventHeader& header, 00142 const TAO_EC_QOS_Info& qos_info) = 0; 00143 00144 /** 00145 * Obtain the QOS information for this filter, the default 00146 * implementation returns an invalid QOS. Only the filters that 00147 * support scheduling information implement this method. 00148 * @return Returns 0 on success and -1 on failure 00149 */ 00150 virtual void get_qos_info (TAO_EC_QOS_Info& qos_info); 00151 00152 private: 00153 /// The parent... 00154 TAO_EC_Filter* parent_; 00155 }; 00156 00157 // **************************************************************** 00158 00159 /** 00160 * @class TAO_EC_Null_Filter 00161 * 00162 * @brief A null filter 00163 * 00164 * This filter accepts any kind of event, it is useful for the 00165 * implementation: 00166 * a) Consumers that accept all events 00167 * b) Consumers that trust the filtering done at the Supplier 00168 * layer. 00169 * c) Event Channels that don't do filtering (such as CosEC 00170 * backends) 00171 */ 00172 class TAO_RTEvent_Serv_Export TAO_EC_Null_Filter : public TAO_EC_Filter 00173 { 00174 public: 00175 /// Constructor. 00176 TAO_EC_Null_Filter (void); 00177 00178 // = The TAO_EC_Filter methods, please check the documentation in 00179 // TAO_EC_Filter. 00180 virtual int filter (const RtecEventComm::EventSet& event, 00181 TAO_EC_QOS_Info& qos_info); 00182 virtual int filter_nocopy (RtecEventComm::EventSet& event, 00183 TAO_EC_QOS_Info& qos_info); 00184 virtual void push (const RtecEventComm::EventSet& event, 00185 TAO_EC_QOS_Info& qos_info); 00186 virtual void push_nocopy (RtecEventComm::EventSet& event, 00187 TAO_EC_QOS_Info& qos_info); 00188 virtual void clear (void); 00189 virtual CORBA::ULong max_event_size (void) const; 00190 virtual int can_match (const RtecEventComm::EventHeader& header) const; 00191 virtual int add_dependencies (const RtecEventComm::EventHeader& header, 00192 const TAO_EC_QOS_Info &qos_info); 00193 }; 00194 00195 // **************************************************************** 00196 00197 // @@ Add more types of filters like: 00198 // - Events in a sequence. 00199 // - Events in a sequence with timeouts. 00200 // - Conjunction with timeout [as opposed to disjunction of 00201 // conjunction and a timeout] 00202 // - etc. 00203 00204 // **************************************************************** 00205 00206 TAO_END_VERSIONED_NAMESPACE_DECL 00207 00208 #if defined (__ACE_INLINE__) 00209 #include "orbsvcs/Event/EC_Filter.inl" 00210 #endif /* __ACE_INLINE__ */ 00211 00212 #include /**/ "ace/post.h" 00213 00214 #endif /* TAO_EC_FILTER_H */