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

Generated on 10 Aug 2018 for OpenDDS by  doxygen 1.6.1