00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file Event_Utilities.h 00006 * 00007 * Event_Utilities.h,v 1.25 2006/03/15 07:52:21 jtc Exp 00008 * 00009 * @author Tim Harrison (harrison@cs.wustl.edu) 00010 */ 00011 //============================================================================= 00012 00013 00014 #ifndef ACE_EVENT_UTILITIES_H 00015 #define ACE_EVENT_UTILITIES_H 00016 00017 #include /**/ "ace/pre.h" 00018 00019 #include "orbsvcs/RtecEventChannelAdminC.h" 00020 #include "orbsvcs/Event_Service_Constants.h" 00021 00022 #include "orbsvcs/Event/event_export.h" 00023 00024 TAO_BEGIN_VERSIONED_NAMESPACE_DECL 00025 00026 00027 typedef void (*TAO_EC_Event_Initializer) (RtecEventComm::Event&); 00028 00029 /** 00030 * @class ACE_ConsumerQOS_Factory 00031 * 00032 * @brief Consumer QOS Factory. 00033 * 00034 * This class allows easy (free from CORBA IDL constraints) 00035 * construction of RtecEventChannelAdmin::ConsumerQOS structures. 00036 * = CORRELATIONS 00037 * ACE_ConsumerQOS_Factory separates subscriptions into conjunction 00038 * and disjunction groups. A group can be thought of as a set of 00039 * events inside parenthesis: (A+B+C), where A,B, and C are 00040 * events. 00041 * The following code would be used to represent (A+B) | (B+C): 00042 * ACE_ConsumerQOS_Factor factory; 00043 * factory.start_conjunction_group (); 00044 * factory.insert (A); 00045 * factory.insert (B); 00046 * factory.start_conjunction_group (); 00047 * factory.insert (B); 00048 * factory.insert (C); 00049 * The following code would be used to represent (A|B) | (B|C): 00050 * ACE_ConsumerQOS_Factor factory; 00051 * factory.start_disjunction_group (); 00052 * factory.insert (A); 00053 * factory.insert (B); 00054 * factory.start_disjunction_group (); 00055 * factory.insert (B); 00056 * factory.insert (C); 00057 * First, this may not seem to be initially useful, as (A|B) | 00058 * (B|C) seems the same as A|B|C. However, this form does have a 00059 * significant use when deadline timers are specified (described 00060 * below). Note that groups end with the next call to 00061 * start_XX_group. Groups are always OR'd together. That is, 00062 * there is no way to directly build (A|B|C) + (D|E|F). You can 00063 * always expand the previous statement to the OR of multiple ANDs. 00064 * = TIMEOUTS 00065 * There are two types of timeout types defined in 00066 * Event_Service_Constants.h. 00067 * ACE_ES_EVENT_INTERVAL_TIMEOUT - the consumer wants to receive a 00068 * timeout every N seconds. 00069 * ACE_ES_EVENT_DEADLINE_TIMEOUT - the consumer wants the timeout 00070 * if and only if some dependencies are not resolved first. 00071 * Using these timeouts with the correlations discussed above, we 00072 * can construct four different timer semantics: Interval Timer, 00073 * Deadline Timer, Interval Correlation, Deadline Correlation: 00074 * Interval Timer: 00075 * (A+B+C) | (D+E+F) | (G+H+I) | IntervalTimeout 00076 * This registers to receive an interval timeout regardless of 00077 * other dependencies. Event if events occur, the interval 00078 * timeout will still be sent. 00079 * Deadline Timer: 00080 * (A+B+C) | (D+E+F) | (G+H+I) | DeadlineTimeout 00081 * This registers to receive the deadline timeout ONLY if no 00082 * other events occur. If a single event is sent to the 00083 * consumer, the timer is cancelled and rescheduled. 00084 * Deadline Correlation: 00085 * (A+B+C) | (D+E+F) | (G+H+DeadlineTimeout) 00086 * If G and H do not occur within DeadlineTimeout time, a 00087 * deadline timeout is sent. It is cancelled and rescheduled if G 00088 * and H occur. 00089 * Interval Correlation: 00090 * (A+B+C) | (D+E+F) | (G+H+IntervalTimeout) 00091 * G+H+IntervalTimeout are sent ONLY after all have occurred. If 00092 * G+H occur, they are queued until IntervalTimeout occurs. If 00093 * IntervalTimeout occurs, it is queued until G+H occur. 00094 */ 00095 class TAO_RTEvent_Export ACE_ConsumerQOS_Factory 00096 { 00097 public: 00098 /// Default construction. 00099 ACE_ConsumerQOS_Factory (TAO_EC_Event_Initializer initializer = 0); 00100 00101 /// Death and destruction. 00102 ~ACE_ConsumerQOS_Factory (void); 00103 00104 /** 00105 * The Event Channel waits until all the children have accepted at 00106 * least one event, and then send them all as a single event to the 00107 * consumer. 00108 */ 00109 int start_conjunction_group (int nchildren = 0); 00110 00111 /// The consumer accepts any event that is accepted by at least one 00112 /// child. 00113 int start_disjunction_group (int nchildren = 0); 00114 00115 /// The consumer only accepts events that pass all the filter 00116 /// expressions defined by the children. 00117 int start_logical_and_group (int nchildren = 0); 00118 00119 /// The consumer wants all the events *except* the group that 00120 /// follows. 00121 int start_negation (void); 00122 00123 /// Insert a bitmask filter, this acts as a quick rejection mechanism 00124 /// for the subsequent filters. 00125 int start_bitmask (CORBA::ULong source_mask, 00126 CORBA::ULong type_mask); 00127 00128 /** 00129 * Inser a new filter that only accepts events with the following 00130 * properties: 00131 * (event.header.type & type_mask) == type_value 00132 * (event.header.source & source_mask) == source_value 00133 */ 00134 int insert_bitmasked_value (CORBA::ULong source_mask, 00135 CORBA::ULong type_mask, 00136 CORBA::ULong source_value, 00137 CORBA::ULong type_value); 00138 00139 /// Insert a node that accepts any event, useful for bitmask filters. 00140 int insert_null_terminator (void); 00141 00142 // = Insert operations add to the current conjunction or disjunction 00143 // group. These return 0 on success, -1 on failure. Before insert 00144 // is called, a start_XX_group method should be called. If a 00145 // start_XX_group method is not called, start_conjunction_group is 00146 // assumed. 00147 00148 /// Insert the @a subscribe structure describing the event and 00149 /// receiving method into the current group. 00150 int insert (const RtecEventChannelAdmin::Dependency &subscribe); 00151 00152 /** 00153 * Insert source/type dependency. @a source of the event (may be 00154 * zero), @a type of the event. @a rt_info describes the method that 00155 * will handle the source/type events. 00156 */ 00157 int insert (RtecEventComm::EventSourceID source, 00158 RtecEventComm::EventType type, 00159 RtecBase::handle_t rt_info); 00160 00161 /// Insert type-only dependency. 00162 int insert_type (RtecEventComm::EventType type, 00163 RtecBase::handle_t rt_info); 00164 00165 /// Insert source-only dependency. 00166 int insert_source (RtecEventComm::EventSourceID source, 00167 RtecBase::handle_t rt_info); 00168 00169 /// Register temporal dependency. @a type designates interval or 00170 /// deadline timeout that will occur every @a interval. 00171 int insert_time (RtecEventComm::EventType type, 00172 RtecEventComm::Time interval, 00173 RtecBase::handle_t rt_info); 00174 00175 /// This will be inserted as type ACE_ES_EVENT_ACT. 00176 int insert_act (RtecEventComm::EventData act); 00177 00178 // = Conversion operators. The Event Channel takes ConsumerQOS 00179 // objects. 00180 00181 /// Allows conversions to ConsumerQOS, which is expected by the 00182 /// PushSupplierProxy::connect_push_consumer interface. 00183 const RtecEventChannelAdmin::ConsumerQOS &get_ConsumerQOS (void); 00184 00185 /// Calls this->get_ConsumerQOS. 00186 operator const RtecEventChannelAdmin::ConsumerQOS &(void); 00187 00188 static void debug (const RtecEventChannelAdmin::ConsumerQOS& qos); 00189 00190 private: 00191 /// The representation to be sent to the channel. 00192 RtecEventChannelAdmin::ConsumerQOS qos_; 00193 00194 /// Whether a start_XX_group has been called yet. This is to make 00195 /// sure that a designator is placed in the subscription list first. 00196 int designator_set_; 00197 00198 /** 00199 * If not zero this is a user-provided function used to initialize 00200 * the events. When the event contains unions this is required to 00201 * avoid marshaling and demarshaling of default initialized unions 00202 * that (AFAIK) is not CORBA compliant. 00203 */ 00204 TAO_EC_Event_Initializer event_initializer_; 00205 }; 00206 00207 // ************************************************************ 00208 00209 class TAO_RTEvent_Export ACE_SupplierQOS_Factory 00210 { 00211 public: 00212 /// Default construction. 00213 ACE_SupplierQOS_Factory (TAO_EC_Event_Initializer initializer = 0, 00214 int qos_max_len = 0); 00215 00216 /** 00217 * Publish @a sid and @a type that is generate by a method described by 00218 * @a rtinfo. The method generates @a type @a ncalls number of times 00219 * per "iteration." 00220 */ 00221 int insert (RtecEventComm::EventSourceID sid, 00222 RtecEventComm::EventType type, 00223 RtecBase::handle_t rtinfo, 00224 u_int ncalls); 00225 00226 /// Allows conversions to SupplierQOS, which is expected by the 00227 /// PushSupplierProxy::connect_push_supplier interface. 00228 const RtecEventChannelAdmin::SupplierQOS &get_SupplierQOS (void); 00229 00230 /// Calls this->get_SupplierQOS(). 00231 operator const RtecEventChannelAdmin::SupplierQOS &(void); 00232 00233 static void debug (const RtecEventChannelAdmin::SupplierQOS& qos); 00234 00235 private: 00236 /// Representation needed by channel. 00237 RtecEventChannelAdmin::SupplierQOS qos_; 00238 00239 /** 00240 * If not zero this is a user-provided function used to initialize 00241 * the events. When the event contains unions this is required to 00242 * avoid marshaling and demarshaling of default initialized unions 00243 * that (AFAIK) is not CORBA compliant. 00244 */ 00245 TAO_EC_Event_Initializer event_initializer_; 00246 }; 00247 00248 TAO_END_VERSIONED_NAMESPACE_DECL 00249 00250 #if defined (__ACE_INLINE__) 00251 #include "orbsvcs/Event_Utilities.i" 00252 #endif /* __ACE_INLINE__ */ 00253 00254 #include /**/ "ace/post.h" 00255 00256 #endif /* ACE_EVENT_UTILITIES_H */