diff options
Diffstat (limited to 'TAO/orbsvcs/orbsvcs/Event/ECG_UDP_Sender.h')
-rw-r--r-- | TAO/orbsvcs/orbsvcs/Event/ECG_UDP_Sender.h | 223 |
1 files changed, 223 insertions, 0 deletions
diff --git a/TAO/orbsvcs/orbsvcs/Event/ECG_UDP_Sender.h b/TAO/orbsvcs/orbsvcs/Event/ECG_UDP_Sender.h new file mode 100644 index 00000000000..20118e46426 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/ECG_UDP_Sender.h @@ -0,0 +1,223 @@ +// -*- C++ -*- + +/** + * @file ECG_UDP_Sender.h + * + * $Id$ + * + * @author Carlos O'Ryan (coryan@cs.wustl.edu) + * @author Marina Spivak (marina@atdesk.com) + * + * Based on previous work by Tim Harrison (harrison@cs.wustl.edu) and + * other members of the DOC group. More details can be found in: + * + * http://doc.ece.uci.edu/~coryan/EC/index.html + * + * Define helper classes to propagate events between ECs using + * either UDP or multicast. + * The architecture is a bit complicated and deserves some + * explanation: sending the events over UDP (or mcast) is easy, a + * Consumer (TAO_ECG_UDP_Sender) subscribes for a certain set of + * events, its push() method marshalls the event set into a CDR + * stream that is sent using an ACE_SOCK_Dgram. The subscription + * set and IP address can be configured. + * Another helper class (TAO_ECG_UDP_Receiver) acts as a supplier of + * events; it receives a callback when an event is available on an + * ACE_SOCK_Dgram, it demarshalls the event and pushes it to the + * EC. Two ACE_Event_Handler classes are provided that can forward + * the events to this Supplier: TAO_ECG_Mcast_EH can receive events + * from a multicast group; TAO_ECG_UDP_EH can receive events from a + * regular UDP socket. + * + * @todo The class makes an extra copy of the events, we need to + * investigate if closer collaboration with its collocated EC could + * be used to remove that copy. + * + */ + +#ifndef TAO_ECG_UDP_SENDER_H +#define TAO_ECG_UDP_SENDER_H +#include /**/ "ace/pre.h" + +#include "orbsvcs/RtecUDPAdminS.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include /**/ "orbsvcs/Event/event_serv_export.h" +#include "orbsvcs/RtecEventChannelAdminS.h" + +#include "orbsvcs/Event/EC_Lifetime_Utils.h" +#include "orbsvcs/Event/EC_Lifetime_Utils_T.h" +#include "orbsvcs/Event/ECG_CDR_Message_Sender.h" + +ACE_BEGIN_VERSIONED_NAMESPACE_DECL +class ACE_SOCK_Dgram; +ACE_END_VERSIONED_NAMESPACE_DECL + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +class TAO_ECG_UDP_Out_Endpoint; + +/** + * @class TAO_ECG_UDP_Sender_Disconnect_Command + * + * @brief Disconnects consumer represented by @a proxy from the Event Channel. + * + * Utility class for use as a template argument to TAO_EC_Auto_Command. + * TAO_EC_Auto_Command<TAO_ECG_UDP_Sender_Disconnect_Command> manages + * consumer connection to the Event Channel, automatically disconnecting from + * @a proxy in its destructor, if necessary. + */ +class TAO_RTEvent_Serv_Export TAO_ECG_UDP_Sender_Disconnect_Command +{ +public: + TAO_ECG_UDP_Sender_Disconnect_Command (void); + TAO_ECG_UDP_Sender_Disconnect_Command ( + RtecEventChannelAdmin::ProxyPushSupplier_ptr proxy); + + TAO_ECG_UDP_Sender_Disconnect_Command ( + const TAO_ECG_UDP_Sender_Disconnect_Command & rhs); + + TAO_ECG_UDP_Sender_Disconnect_Command & + operator= (const TAO_ECG_UDP_Sender_Disconnect_Command & rhs); + + void execute (void); + +private: + + RtecEventChannelAdmin::ProxyPushSupplier_var proxy_; +}; + + +/** + * @class TAO_ECG_UDP_Sender + * + * @brief Send events received from a "local" EC using UDP. + * NOT THREAD-SAFE. + * This class connect as a consumer to an EventChannel + * and forwards the events it receives from that EC using UDP. + * + */ +class TAO_RTEvent_Serv_Export TAO_ECG_UDP_Sender : + public virtual POA_RtecEventComm::PushConsumer, + public TAO_EC_Deactivated_Object +{ +public: + + /// Initialization and termination methods. + //@{ + + /// Create a new TAO_ECG_UDP_Sender object. + /// (Constructor access is restricted to insure that all + /// TAO_ECG_UDP_Sender objects are heap-allocated.) + static TAO_EC_Servant_Var<TAO_ECG_UDP_Sender> create (CORBA::Boolean crc = 0); + + ~TAO_ECG_UDP_Sender (void); + + /** + * @param lcl_ec Event Channel to which we will act as a consumer of events. + * @param addr_server Address server used to obtain event type to + * multicast group mapping. + * @param endpoint_rptr Endpoint for sending udp/multicast messages. + * Endpoint's dgram must be open! + * + * To insure proper resource clean up, if init () is successful, + * shutdown () must be called when the sender is no longer needed. + * This is done by disconnect_push_consumer() method. If + * disconnect_push_consumer() will not be called, it is the + * responsibility of the user. + * Furthermore, if shutdown() is not explicitly called by + * either disconnect_push_consumer () or the user, the sender + * will clean up the resources in its destructor, however, certain + * entities involved in cleanup must still exist at that point, + * e.g., POA. + */ + void init (RtecEventChannelAdmin::EventChannel_ptr lcl_ec, + RtecUDPAdmin::AddrServer_ptr addr_server, + TAO_ECG_Refcounted_Endpoint endpoint_rptr); + + /// Connect or reconnect to the EC with the given subscriptions. + /** + * NOTE: if we are already connected to EC and a reconnection is + * necessary, the EC must have reconnects enabled in order for this + * method to succeed. + */ + void connect (const RtecEventChannelAdmin::ConsumerQOS &sub); + + /// Deactivate from POA and disconnect from EC, if necessary. Shut + /// down all sender components. + /** + * Calling this method may result in decrementing of the reference + * count (due to deactivation) and deletion of the object. + */ + void shutdown (void); + //@} + + /// Accessors. + //@{ + /** + * The sender may need to fragment the message, otherwise the + * network may drop the packets. + * Setting the MTU can fail if the value is too small (at least the + * header + 8 bytes must fit). + */ + int mtu (CORBA::ULong mtu); + CORBA::ULong mtu (void) const; + + /// Get the local endpoint used to send the events. + int get_local_addr (ACE_INET_Addr& addr); + //@} + + /// The PushConsumer methods. + //@{ + /// Invokes shutdown (), which may result in the object being deleted, if + /// refcounting is used to manage its lifetime. + virtual void disconnect_push_consumer (void); + virtual void push (const RtecEventComm::EventSet &events); + //@} + +protected: + + /// Constructor (protected). Clients can create new + /// TAO_ECG_UDP_Sender objects using the static create() method. + TAO_ECG_UDP_Sender (CORBA::Boolean crc = 0); + +private: + + /// Helpers for the connect() method. + //@{ + // Establishes connection to the Event Channel for the first time. + void new_connect (const RtecEventChannelAdmin::ConsumerQOS& sub); + + // Updates existing connection to the Event Channel. + void reconnect (const RtecEventChannelAdmin::ConsumerQOS& sub); + //@} + + /// Proxy used to receive events from the Event Channel. + RtecEventChannelAdmin::ProxyPushSupplier_var supplier_proxy_; + + /// Event Channel to which we act as a consumer. + RtecEventChannelAdmin::EventChannel_var lcl_ec_; + + /// We query this object to determine where the events should be sent. + RtecUDPAdmin::AddrServer_var addr_server_; + + /// Helper for fragmenting and sending cdr-encoded events using udp. + TAO_ECG_CDR_Message_Sender cdr_sender_; + + typedef TAO_EC_Auto_Command<TAO_ECG_UDP_Sender_Disconnect_Command> + ECG_Sender_Auto_Proxy_Disconnect; + /// Manages our connection to Supplier Proxy. + ECG_Sender_Auto_Proxy_Disconnect auto_proxy_disconnect_; +}; + +TAO_END_VERSIONED_NAMESPACE_DECL + +#if defined(__ACE_INLINE__) +#include "orbsvcs/Event/ECG_UDP_Sender.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" +#endif /* TAO_ECG_UDP_SENDER_H */ |