/* -*- C++ -*- */ // $Id$ // ============================================================================ // // = LIBRARY // ace ORB // // = FILENAME // Event_Utilities // // = AUTHOR // Tim Harrison (harrison@cs.wustl.edu) // // ============================================================================ #ifndef ACE_EVENT_UTILITIES_H #define ACE_EVENT_UTILITIES_H #include "ace/pre.h" #include "orbsvcs/RtecEventChannelAdminC.h" #include "orbsvcs/Event_Service_Constants.h" #include "Event/event_export.h" typedef void (*TAO_EC_Event_Initializer) (RtecEventComm::Event&); class TAO_RTEvent_Export ACE_ConsumerQOS_Factory { // = TITLE // Consumer QOS Factory. // // = DESCRIPTION // // This class allows easy (free from CORBA IDL constraints) // construction of RtecEventChannelAdmin::ConsumerQOS structures. // // = CORRELATIONS // // ACE_ConsumerQOS_Factory separates subscriptions into conjunction // and disjunction groups. A group can be thought of as a set of // events inside parenthesis: (A+B+C), where A,B, and C are // events. // // The following code would be used to represent (A+B) | (B+C): // // ACE_ConsumerQOS_Factor factory; // factory.start_conjunction_group (); // factory.insert (A); // factory.insert (B); // factory.start_conjunction_group (); // factory.insert (B); // factory.insert (C); // // The following code would be used to represent (A|B) | (B|C): // // ACE_ConsumerQOS_Factor factory; // factory.start_disjunction_group (); // factory.insert (A); // factory.insert (B); // factory.start_disjunction_group (); // factory.insert (B); // factory.insert (C); // // First, this may not seem to be initially useful, as (A|B) | // (B|C) seems the same as A|B|C. However, this form does have a // significant use when deadline timers are specified (described // below). Note that groups end with the next call to // start_XX_group. Groups are always OR'd together. That is, // there is no way to directly build (A|B|C) + (D|E|F). You can // always expand the previous statement to the OR of multiple ANDs. // // = TIMEOUTS // // There are two types of timeout types defined in // Event_Service_Constants.h. // // ACE_ES_EVENT_INTERVAL_TIMEOUT - the consumer wants to receive a // timeout every N seconds. // // ACE_ES_EVENT_DEADLINE_TIMEOUT - the consumer wants the timeout // if and only if some dependencies are not resolved first. // // Using these timeouts with the correlations discussed above, we // can construct four different timer semantics: Interval Timer, // Deadline Timer, Interval Correlation, Deadline Correlation: // // Interval Timer: // // (A+B+C) | (D+E+F) | (G+H+I) | IntervalTimeout // // This registers to receive an interval timeout regardless of // other dependencies. Event if events occur, the interval // timeout will still be sent. // // Deadline Timer: // // (A+B+C) | (D+E+F) | (G+H+I) | DeadlineTimeout // // This registers to receive the deadline timeout ONLY if no // other events occur. If a single event is sent to the // consumer, the timer is cancelled and rescheduled. // // Deadline Correlation: // // (A+B+C) | (D+E+F) | (G+H+DeadlineTimeout) // // If G and H do not occur within DeadlineTimeout time, a // deadline timeout is sent. It is cancelled and rescheduled if G // and H occur. // // Interval Correlation: // // (A+B+C) | (D+E+F) | (G+H+IntervalTimeout) // // G+H+IntervalTimeout are sent ONLY after all have occurred. If // G+H occur, they are queued until IntervalTimeout occurs. If // IntervalTimeout occurs, it is queued until G+H occur. public: ACE_ConsumerQOS_Factory (TAO_EC_Event_Initializer initializer = 0); // Default construction. ~ACE_ConsumerQOS_Factory (void); // Death and destruction. int start_conjunction_group (int nchildren = 0); // The Event Channel waits until all the children have accepted at // least one event, and then send them all as a single event to the // consumer. int start_disjunction_group (int nchildren = 0); // The consumer accepts any event that is accepted by at least one // child. int start_logical_and_group (int nchildren = 0); // The consumer only accepts events that pass all the filter // expressions defined by the children. int start_negation (void); // The consumer wants all the events *except* the group that // follows. int start_bitmask (CORBA::ULong source_mask, CORBA::ULong type_mask); // Insert a bitmask filter, this acts as a quick rejection mechanism // for the subsequent filters. int insert_bitmasked_value (CORBA::ULong source_mask, CORBA::ULong type_mask, CORBA::ULong source_value, CORBA::ULong type_value); // Inser a new filter that only accepts events with the following // properties: // (event.header.type & type_mask) == type_value // (event.header.source & source_mask) == source_value int insert_null_terminator (void); // Insert a node that accepts any event, useful for bitmask filters. // = Insert operations add to the current conjunction or disjunction // group. These return 0 on success, -1 on failure. Before insert // is called, a start_XX_group method should be called. If a // start_XX_group method is not called, start_conjunction_group is // assumed. int insert (const RtecEventChannelAdmin::Dependency &subscribe); // Insert the structure describing the event and // receiving method into the current group. int insert (RtecEventComm::EventSourceID source, RtecEventComm::EventType type, RtecBase::handle_t rt_info); // Insert source/type dependency. of the event (may be // zero), of the event. describes the method that // will handle the / events. int insert_type (RtecEventComm::EventType type, RtecBase::handle_t rt_info); // Insert type-only dependency. int insert_source (RtecEventComm::EventSourceID source, RtecBase::handle_t rt_info); // Insert source-only dependency. int insert_time (RtecEventComm::EventType type, RtecEventComm::Time interval, RtecBase::handle_t rt_info); // Register temporal dependency. designates interval or // deadline timeout that will occur every . int insert_act (RtecEventComm::EventData act); // This will be inserted as type ACE_ES_EVENT_ACT. // = Conversion operators. The Event Channel takes ConsumerQOS // objects. const RtecEventChannelAdmin::ConsumerQOS &get_ConsumerQOS (void); // Allows conversions to ConsumerQOS, which is expected by the // PushSupplierProxy::connect_push_consumer interface. operator const RtecEventChannelAdmin::ConsumerQOS &(void); // Calls this->get_ConsumerQOS. static void debug (const RtecEventChannelAdmin::ConsumerQOS& qos); private: RtecEventChannelAdmin::ConsumerQOS qos_; // The representation to be sent to the channel. int designator_set_; // Whether a start_XX_group has been called yet. This is to make // sure that a designator is placed in the subscription list first. TAO_EC_Event_Initializer event_initializer_; // If not zero this is a user-provided function used to initialize // the events. When the event contains unions this is required to // avoid marshaling and demarshaling of default initialized unions // that (AFAIK) is not CORBA compliant. }; // ************************************************************ class TAO_RTEvent_Export ACE_SupplierQOS_Factory { public: ACE_SupplierQOS_Factory (TAO_EC_Event_Initializer initializer = 0); // Default construction. int insert (RtecEventComm::EventSourceID sid, RtecEventComm::EventType type, RtecBase::handle_t rtinfo, u_int ncalls); // Publish and that is generate by a method described by // . The method generates number of times // per "iteration." const RtecEventChannelAdmin::SupplierQOS &get_SupplierQOS (void); // Allows conversions to SupplierQOS, which is expected by the // PushSupplierProxy::connect_push_supplier interface. operator const RtecEventChannelAdmin::SupplierQOS &(void); // Calls this->get_SupplierQOS. static void debug (const RtecEventChannelAdmin::SupplierQOS& qos); private: RtecEventChannelAdmin::SupplierQOS qos_; // Representation needed by channel. TAO_EC_Event_Initializer event_initializer_; // If not zero this is a user-provided function used to initialize // the events. When the event contains unions this is required to // avoid marshaling and demarshaling of default initialized unions // that (AFAIK) is not CORBA compliant. }; #if defined (__ACE_INLINE__) #include "orbsvcs/Event_Utilities.i" #endif /* __ACE_INLINE__ */ #include "ace/post.h" #endif /* ACE_EVENT_UTILITIES_H */