TcpTransport.h

Go to the documentation of this file.
00001 /*
00002  *
00003  *
00004  * Distributed under the OpenDDS License.
00005  * See: http://www.opendds.org/license.html
00006  */
00007 
00008 #ifndef OPENDDS_TCPTRANSPORT_H
00009 #define OPENDDS_TCPTRANSPORT_H
00010 
00011 #include "Tcp_export.h"
00012 
00013 #include "dds/DCPS/transport/framework/TransportImpl.h"
00014 #include "TcpInst_rch.h"
00015 #include "TcpDataLink_rch.h"
00016 #include "TcpConnection.h"
00017 #include "TcpConnection_rch.h"
00018 
00019 #include "dds/DCPS/transport/framework/TransportReactorTask_rch.h"
00020 #include "dds/DCPS/transport/framework/PriorityKey.h"
00021 
00022 #include "ace/INET_Addr.h"
00023 #include "ace/Hash_Map_Manager.h"
00024 #include "ace/Synch.h"
00025 #include "ace/Connector.h"
00026 #include "ace/SOCK_Connector.h"
00027 
00028 namespace OpenDDS {
00029 namespace DCPS {
00030 
00031 class TcpAcceptor;
00032 class TcpConnectionReplaceTask;
00033 
00034 /**
00035  * This class provides the "Tcp" transport specific implementation.
00036  * It creates the acceptor for listening the incoming requests using
00037  * TCP and maintains a collection of TCP specific connections/datalinks.
00038  *
00039  * Notes about object ownership:
00040  * 1) Own the datalink objects, passive connection objects, acceptor object
00041  *    and TcpConnectionReplaceTask object(used during reconnecting).
00042  * 2) Reference to TransportReactorTask object owned by base class.
00043  */
00044 class OpenDDS_Tcp_Export TcpTransport : public TransportImpl {
00045 public:
00046 
00047   explicit TcpTransport(const TransportInst_rch& inst);
00048   virtual ~TcpTransport();
00049 
00050   TcpInst* get_configuration();
00051 
00052   int fresh_link(TcpConnection_rch connection);
00053 
00054   virtual void unbind_link(DataLink* link);
00055 
00056 
00057 private:
00058   virtual AcceptConnectResult connect_datalink(const RemoteTransport& remote,
00059                                                const ConnectionAttribs& attribs,
00060                                                TransportClient* client);
00061 
00062   virtual AcceptConnectResult accept_datalink(const RemoteTransport& remote,
00063                                               const ConnectionAttribs& attribs,
00064                                               TransportClient* client);
00065 
00066   virtual void stop_accepting_or_connecting(TransportClient* client,
00067                                             const RepoId& remote_id);
00068 
00069   virtual bool configure_i(TransportInst* config);
00070 
00071   virtual void shutdown_i();
00072   virtual void pre_shutdown_i();
00073 
00074   virtual bool connection_info_i(TransportLocator& local_info) const;
00075 
00076   /// Called by the DataLink to release itself.
00077   virtual void release_datalink(DataLink* link);
00078 
00079   virtual std::string transport_type() const { return "tcp"; }
00080 
00081   void async_connect_failed(const PriorityKey& key);
00082 
00083   /// The TcpConnection is our friend.  It tells us when it
00084   /// has been created (by our acceptor_), and is seeking the
00085   /// DataLink that should be (or will be) expecting the passive
00086   /// connection.
00087   friend class TcpConnection;
00088   friend class TcpDataLink;
00089 
00090   /// Called by the TcpConnection object when it has been
00091   /// created by the acceptor and needs to be attached to a DataLink.
00092   /// The DataLink may or may not already be created and waiting
00093   /// for this passive connection to appear.
00094   void passive_connection(const ACE_INET_Addr& remote_address,
00095                           const TcpConnection_rch& connection);
00096 
00097   bool find_datalink_i(const PriorityKey& key, TcpDataLink_rch& link,
00098                        TransportClient* client, const RepoId& remote_id);
00099 
00100   /// Code common to make_active_connection() and
00101   /// make_passive_connection().
00102   int connect_tcp_datalink(const TcpDataLink_rch& link,
00103                            const TcpConnection_rch& connection);
00104 
00105   PriorityKey blob_to_key(const TransportBLOB& remote,
00106                           Priority priority,
00107                           bool active);
00108 
00109   /// Map Type: (key) PriorityKey to (value) TcpDataLink_rch
00110   typedef ACE_Hash_Map_Manager_Ex
00111             <PriorityKey,
00112             TcpDataLink_rch,
00113             ACE_Hash<PriorityKey>,
00114             ACE_Equal_To<PriorityKey>,
00115             ACE_Null_Mutex>              AddrLinkMap;
00116 
00117   typedef OPENDDS_MAP(PriorityKey, TcpDataLink_rch)   LinkMap;
00118   typedef OPENDDS_MAP(PriorityKey, TcpConnection_rch) ConnectionMap;
00119 
00120   typedef ACE_SYNCH_MUTEX         LockType;
00121   typedef ACE_Guard<LockType>     GuardType;
00122   typedef ACE_Condition<LockType> ConditionType;
00123 
00124 // TBD SOON - Something needs to protect the tcp_config_ reference
00125 //            because it gets set in our configure() method, and
00126 //            dropped in our shutdown_i() method.  Maybe we can just
00127 //            assume that configure() can remain unlocked (why not lock it
00128 //            though - it isn't in the send or receive path?)
00129 //            Step back and take a look at when the various locks in here
00130 //            get used - and if not in the direct send or receive path,
00131 //            maybe we can simplify this at the expense of a little more
00132 //            locking (ie, longer critical sections).  And the base
00133 //            class has a lock that might work for us - check out if
00134 //            our base class should do the locking, and then we can
00135 //            assume it has been done for us (in various situations).
00136 
00137   /// Used to accept passive connections on our local_address_.
00138   TcpAcceptor* acceptor_;
00139 
00140   /// Open TcpConnections using non-blocking connect.
00141   ACE_Connector<TcpConnection, ACE_SOCK_Connector> connector_;
00142 
00143   /// Our configuration object, supplied to us in config_i().
00144   TcpInst_rch tcp_config_;
00145 
00146   /// This is the map of connected DataLinks.
00147   AddrLinkMap links_;
00148   AddrLinkMap pending_release_links_;
00149 
00150   /// This lock is used to protect the links_ data member.
00151   LockType links_lock_;
00152 
00153   /// Map of passive connection objects that need to be paired
00154   /// with a DataLink.
00155   ConnectionMap connections_;
00156 
00157   /// This protects the connections_ and the pending_connections_
00158   /// data members.
00159   LockType connections_lock_;
00160 
00161   /// We need the reactor for our Acceptor.
00162   TransportReactorTask_rch reactor_task_;
00163 
00164   /// This task is used to resolve some deadlock situation
00165   /// during reconnecting.
00166   /// TODO: reuse the reconnect_task in the TcpConnection
00167   ///       for new connection checking.
00168   TcpConnectionReplaceTask* con_checker_;
00169 };
00170 
00171 } // namespace DCPS
00172 } // namespace OpenDDS
00173 
00174 #endif  /* OPENDDS_TCPTRANSPORT_H */

Generated on Fri Feb 12 20:05:27 2016 for OpenDDS by  doxygen 1.4.7