TAO_Connector Class Reference

Generic Connector interface definitions. More...

#include <Transport_Connector.h>

Inheritance diagram for TAO_Connector:

Inheritance graph
[legend]
Collaboration diagram for TAO_Connector:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 TAO_Connector (CORBA::ULong tag)
 Default constructor.

virtual ~TAO_Connector (void)
 The destructor.

CORBA::ULong tag (void) const
int make_mprofile (const char *ior, TAO_MProfile &mprofile)
virtual TAO_Profilecorbaloc_scan (const char *ior, size_t &len)
virtual int open (TAO_ORB_Core *orb_core)=0
 Initialize object and register with reactor.

virtual int close (void)=0
 Shutdown Connector bridge and concrete Connector.

virtual TAO_Transportconnect (TAO::Profile_Transport_Resolver *r, TAO_Transport_Descriptor_Interface *desc, ACE_Time_Value *timeout)
virtual TAO_Transportparallel_connect (TAO::Profile_Transport_Resolver *r, TAO_Transport_Descriptor_Interface *desc, ACE_Time_Value *timeout)
virtual TAO_Profilecreate_profile (TAO_InputCDR &cdr)=0
virtual int check_prefix (const char *endpoint)=0
virtual char object_key_delimiter (void) const=0
 Return the object key delimiter to use or expect.


Protected Member Functions

virtual int supports_parallel_connects (void) const
virtual TAO_Profilemake_profile ()=0
 Create a profile with a given endpoint.

virtual int set_validate_endpoint (TAO_Endpoint *endpoint)=0
virtual TAO_Transportmake_connection (TAO::Profile_Transport_Resolver *r, TAO_Transport_Descriptor_Interface &desc, ACE_Time_Value *timeout)=0
 Make a connection.

virtual TAO_Transportmake_parallel_connection (TAO::Profile_Transport_Resolver *r, TAO_Transport_Descriptor_Interface &desc, ACE_Time_Value *timeout)
virtual int cancel_svc_handler (TAO_Connection_Handler *svc_handler)=0
 Cancel the passed cvs handler from the connector.

virtual int check_connection_closure (TAO_Connection_Handler *connection_handler)
 Check whether the connection is not closed.

virtual bool wait_for_connection_completion (TAO::Profile_Transport_Resolver *r, TAO_Transport *&transport, ACE_Time_Value *timeout)
virtual bool wait_for_connection_completion (TAO::Profile_Transport_Resolver *r, TAO_Transport *&the_winner, TAO_Transport **transport, unsigned int count, TAO_LF_Multi_Event *mev, ACE_Time_Value *timeout)
void orb_core (TAO_ORB_Core *orb_core)
 Set the ORB Core pointer.

int create_connect_strategy (void)
 Create a connect strategy.

TAO_ORB_Coreorb_core (void)
 Return the TAO_ORB_Core pointer.


Protected Attributes

TAO_Connect_Strategyactive_connect_strategy_
 The (a)synch connect strategy.


Private Attributes

CORBA::ULong const  tag_
 IOP protocol tag.

TAO_ORB_Coreorb_core_
 Pointer to our ORB core.


Detailed Description

Generic Connector interface definitions.

Base class for connector bridge object.

Todo:
Need to rename the class as TAO_Transport_Connector.

Definition at line 71 of file Transport_Connector.h.


Constructor & Destructor Documentation

TAO_BEGIN_VERSIONED_NAMESPACE_DECL TAO_Connector::TAO_Connector CORBA::ULong  tag  ) 
 

Default constructor.

Definition at line 35 of file Transport_Connector.cpp.

00036   : active_connect_strategy_ (0),
00037     tag_ (tag),
00038     orb_core_ (0)
00039 {
00040 }

TAO_Connector::~TAO_Connector void   )  [virtual]
 

The destructor.

Definition at line 42 of file Transport_Connector.cpp.

References active_connect_strategy_.

00043 {
00044   delete this->active_connect_strategy_;
00045 }


Member Function Documentation

virtual int TAO_Connector::cancel_svc_handler TAO_Connection_Handler svc_handler  )  [protected, pure virtual]
 

Cancel the passed cvs handler from the connector.

Implemented in TAO_IIOP_Connector.

Referenced by check_connection_closure(), and wait_for_connection_completion().

int TAO_Connector::check_connection_closure TAO_Connection_Handler connection_handler  )  [protected, virtual]
 

Check whether the connection is not closed.

Return values:
0 The connection happens to be not closed, but is now open because an other thread managed to open the handler
-1 The connection is closed

Definition at line 671 of file Transport_Connector.cpp.

References ACE_ASSERT, cancel_svc_handler(), TAO_Connection_Handler::close_handler(), TAO_Connection_Handler::is_closed(), TAO_Connection_Handler::is_connecting(), and TAO_Connection_Handler::is_open().

Referenced by wait_for_connection_completion().

00673 {
00674   int result = -1;
00675 
00676   // Check if the handler has been closed.
00677   bool closed =
00678     connection_handler->is_closed ();
00679 
00680   // In case of failures and close() has not be called.
00681   if (!closed)
00682     {
00683       // First, cancel from connector.
00684       if (this->cancel_svc_handler (connection_handler) == -1)
00685         return -1;
00686 
00687       // Double check to make sure the handler has not been closed
00688       // yet.  This double check is required to ensure that the
00689       // connection handler was not closed yet by some other
00690       // thread since it was still registered with the connector.
00691       // Once connector.cancel() has been processed, we are
00692       // assured that the connector will no longer open/close this
00693       // handler.
00694       closed = connection_handler->is_closed ();
00695 
00696 
00697       // If closed, there is nothing to do here.  If not closed,
00698       // it was either opened or is still pending.
00699       if (!closed)
00700         {
00701           // Check if the handler has been opened.
00702           const bool open = connection_handler->is_open ();
00703 
00704           // Some other thread was able to open the handler even
00705           // though wait failed for this thread.
00706           if (open)
00707             {
00708               // Set the result to 0, we have an open connection
00709               result = 0;
00710             }
00711           else
00712             {
00713               // Assert that it is still connecting.
00714               ACE_ASSERT (connection_handler->is_connecting ());
00715 
00716               // Force close the handler now.
00717               connection_handler->close_handler ();
00718             }
00719         }
00720     }
00721 
00722   return result;
00723 }

virtual int TAO_Connector::check_prefix const char *  endpoint  )  [pure virtual]
 

Check that the prefix of the provided endpoint is valid for use with a given pluggable protocol.

Implemented in TAO_IIOP_Connector.

Referenced by corbaloc_scan(), and make_mprofile().

virtual int TAO_Connector::close void   )  [pure virtual]
 

Shutdown Connector bridge and concrete Connector.

Implemented in TAO_IIOP_Connector.

Referenced by TAO_Connector_Registry::close_all().

TAO_Transport * TAO_Connector::connect TAO::Profile_Transport_Resolver r,
TAO_Transport_Descriptor_Interface desc,
ACE_Time_Value timeout
[virtual]
 

To support pluggable we need to abstract away the details of the connect () method so it can be called from the invocation code independent of the actual transport protocol in use.

Definition at line 325 of file Transport_Connector.cpp.

References ACE_DEBUG, ACE_ENV_ARG_PARAMETER, ACE_ERROR, ACE_TEXT, TAO_Transport::close_connection(), TAO_Transport_Descriptor_Interface::endpoint(), TAO::Transport_Cache_Manager::find_transport(), TAO_Transport::id(), TAO_Transport::is_connected(), TAO_ORB_Core::lane_resources(), LM_DEBUG, LM_ERROR, make_connection(), TAO_Transport::opened_as(), orb_core(), TAO_Transport::post_connect_hook(), TAO::Transport_Cache_Manager::purge(), TAO_Transport::purge_entry(), TAO_Wait_Strategy::register_handler(), set_validate_endpoint(), TAO_debug_level, TAO_Thread_Lane_Resources::transport_cache(), wait_for_connection_completion(), and TAO_Transport::wait_strategy().

00329 {
00330   if (desc == 0 ||
00331       (this->set_validate_endpoint (desc->endpoint ()) == -1))
00332     return 0;
00333 
00334   TAO_Transport *base_transport = 0;
00335 
00336   TAO::Transport_Cache_Manager &tcm =
00337     this->orb_core ()->lane_resources ().transport_cache ();
00338 
00339   // Check the Cache first for connections
00340   // If transport found, reference count is incremented on assignment
00341   // @@todo: We need to send the timeout value to the cache registry
00342   // too. That should be the next step!
00343   if (tcm.find_transport (desc,
00344                           base_transport) != 0)
00345     {
00346       // @@TODO: This is not the right place for this!
00347       // Purge connections (if necessary)
00348       tcm.purge ();
00349 
00350       TAO_Transport* t = this->make_connection (r,
00351                                                 *desc,
00352                                                 timeout);
00353 
00354       if (t == 0)
00355         return t;
00356 
00357       t->opened_as (TAO::TAO_CLIENT_ROLE);
00358 
00359       if (TAO_debug_level > 4)
00360         ACE_DEBUG ((LM_DEBUG,
00361                     ACE_TEXT("(%P|%t) Transport_Connector::connect, ")
00362                     ACE_TEXT("opening Transport[%d] in TAO_CLIENT_ROLE\n"),
00363                     t->id ()));
00364 
00365       // Call post connect hook. If the post_connect_hook () returns
00366       // false, just purge the entry.
00367       if (!t->post_connect_hook ())
00368         {
00369           (void) t->purge_entry ();
00370 
00371           // Call connect again
00372           return this->connect (r,
00373                                 desc,
00374                                 timeout
00375                                 ACE_ENV_ARG_PARAMETER);
00376         }
00377 
00378       return t;
00379     }
00380 
00381   if (TAO_debug_level > 4)
00382     {
00383       TAO::Connection_Role cr =
00384         base_transport->opened_as ();
00385 
00386       ACE_DEBUG ((LM_DEBUG,
00387                   "TAO (%P|%t) - Transport_Connector::connect, "
00388                   "got an existing %s Transport[%d] in role %s\n",
00389                   base_transport->is_connected () ? "connected" : "unconnected",
00390                   base_transport->id (),
00391                   cr == TAO::TAO_SERVER_ROLE ? "TAO_SERVER_ROLE" :
00392                   cr == TAO::TAO_CLIENT_ROLE ? "TAO_CLIENT_ROLE" :
00393                   "TAO_UNSPECIFIED_ROLE" ));
00394     }
00395 
00396 
00397   // If connected return.
00398   if (base_transport->is_connected ())
00399     return base_transport;
00400 
00401   // It it possible to get a transport from the cache that is not
00402   // connected? If not, then the following code is bogus. We cannot
00403   // wait for a connection to complete on a transport in the cache.
00404   //
00405   // (mesnier_p@ociweb.com) It is indeed possible to reach this point.
00406   // The AMI_Buffering test does. When using non-blocking connects and
00407   // the first request(s) are asynch and may be queued, the connection
00408   // establishment may not be completed by the time the invocation is
00409   // done with it. In that case it is up to a subsequent invocation to
00410   // handle the connection completion.
00411 
00412   if (!this->wait_for_connection_completion (r,
00413                                              base_transport,
00414                                              timeout))
00415     {
00416       if (TAO_debug_level > 2)
00417         ACE_ERROR ((LM_ERROR,
00418                     "TAO (%P|%t) - Transport_Connector::"
00419                     "connect, "
00420                     "wait for completion failed\n"));
00421       return 0;
00422     }
00423 
00424   if (base_transport->is_connected () &&
00425       base_transport->wait_strategy ()->register_handler () == 0)
00426     {
00427       // Registration failures.
00428 
00429       // Purge from the connection cache, if we are not in the cache, this
00430       // just does nothing.
00431       (void) base_transport->purge_entry ();
00432 
00433       // Close the handler.
00434       (void) base_transport->close_connection ();
00435 
00436       if (TAO_debug_level > 0)
00437         ACE_ERROR ((LM_ERROR,
00438                     "TAO (%P|%t) - Transport_Connector [%d]::connect, "
00439                     "could not register the transport "
00440                     "in the reactor.\n",
00441                     base_transport->id ()));
00442 
00443       return 0;
00444     }
00445 
00446   return base_transport;
00447 }

TAO_Profile * TAO_Connector::corbaloc_scan const char *  ior,
size_t &  len
[virtual]
 

Helper function to assist corbaloc parsing. The default simply validates the protocol identifyier and scans up to the next comma or slash. Any protocol that has a specific need, such as uiop, can override this method to provide a custom scanner. The profile returned is either null if this the ior does not match or an empty profile of the correct type, obtained from make_profile().

Definition at line 48 of file Transport_Connector.cpp.

References ACE_DEBUG, ACE_ENV_SINGLE_ARG_PARAMETER, ACE_TEXT, check_prefix(), LM_DEBUG, make_profile(), ACE_OS::strchr(), ACE_OS::strlen(), and TAO_debug_level.

00051 {
00052   if (this->check_prefix (str) != 0)
00053     return 0;
00054   const char *comma_pos = ACE_OS::strchr (str,',');
00055   const char *slash_pos = ACE_OS::strchr (str,'/');
00056   if (comma_pos == 0 && slash_pos == 0)
00057     {
00058       if (TAO_debug_level)
00059         ACE_DEBUG ((LM_DEBUG,
00060                     ACE_TEXT("(%P|%t) TAO_CONNECTOR::corbaloc_scan warning: ")
00061                     ACE_TEXT("supplied string contains no comma or slash: %s\n"),
00062                     str));
00063       len = ACE_OS::strlen (str);
00064     }
00065   else if (comma_pos == 0 || comma_pos > slash_pos)
00066     len = (slash_pos - str);
00067   else len = comma_pos - str;
00068   return this->make_profile(ACE_ENV_SINGLE_ARG_PARAMETER);
00069 }

int TAO_Connector::create_connect_strategy void   )  [protected]
 

Create a connect strategy.

Definition at line 653 of file Transport_Connector.cpp.

References active_connect_strategy_, TAO_ORB_Core::client_factory(), and TAO_Client_Strategy_Factory::create_connect_strategy().

Referenced by TAO_IIOP_Connector::open().

00654 {
00655   if (this->active_connect_strategy_ == 0)
00656     {
00657       this->active_connect_strategy_ =
00658         this->orb_core_->client_factory ()->create_connect_strategy (
00659           this->orb_core_);
00660     }
00661 
00662   if (this->active_connect_strategy_ == 0)
00663     {
00664       return -1;
00665     }
00666 
00667   return 0;
00668 }

virtual TAO_Profile* TAO_Connector::create_profile TAO_InputCDR cdr  )  [pure virtual]
 

Create a profile for this protocol and initialize it based on the encapsulation in cdr

Implemented in TAO_IIOP_Connector.

Referenced by TAO_Connector_Registry::create_profile().

virtual TAO_Transport* TAO_Connector::make_connection TAO::Profile_Transport_Resolver r,
TAO_Transport_Descriptor_Interface desc,
ACE_Time_Value timeout
[protected, pure virtual]
 

Make a connection.

Implemented in TAO_IIOP_Connector.

Referenced by connect().

int TAO_Connector::make_mprofile const char *  ior,
TAO_MProfile mprofile
 

Parse a string containing a URL style IOR and return an MProfile. Verify that ior is in the correct format.

Definition at line 72 of file Transport_Connector.cpp.

References TAO_Profile::_decr_refcnt(), ACE_CHECK_RETURN, ACE_CString, ACE_DEBUG, ACE_ENV_ARG_PARAMETER, ACE_ENV_SINGLE_ARG_PARAMETER, ACE_TEXT, ACE_TEXT_CHAR_TO_TCHAR, ACE_THROW_RETURN, check_prefix(), LM_DEBUG, make_profile(), TAO_Profile::parse_string(), ssize_t, TAO_debug_level, and TAO_MPROFILE_CREATION_ERROR.

00075 {
00076   // This method utilizes the "Template Method" design pattern to
00077   // parse the given URL style IOR for the protocol being used
00078   // and create an mprofile from it.
00079   //
00080   // The methods that must be defined by all Connector sub-classes are:
00081   //      make_profile
00082   //      check_prefix
00083 
00084   // Check for a valid string
00085   if (!string || !*string)
00086     {
00087       ACE_THROW_RETURN (CORBA::INV_OBJREF (
00088                           CORBA::SystemException::_tao_minor_code (
00089                             0,
00090                             EINVAL),
00091                           CORBA::COMPLETED_NO),
00092                         -1);
00093     }
00094 
00095   // Check for the proper prefix in the IOR.  If the proper prefix isn't
00096   // in the IOR then it is not an IOR we can use.
00097   if (this->check_prefix (string) != 0)
00098     {
00099       return 1;
00100       // Failure: not the correct IOR for this protocol.
00101       // DO NOT throw an exception here since the Connector_Registry
00102       // should be allowed the opportunity to continue looking for
00103       // an appropriate connector.
00104     }
00105 
00106   if (TAO_debug_level > 0)
00107     {
00108       ACE_DEBUG ((LM_DEBUG,
00109                   ACE_TEXT ("TAO (%P|%t) - TAO_Connector::make_mprofile ")
00110                   ACE_TEXT ("<%s>\n"),
00111                   ACE_TEXT_CHAR_TO_TCHAR (string)));
00112     }
00113 
00114   ACE_CString ior;
00115 
00116   ior.set (string, ACE_OS::strlen (string), 1);
00117 
00118   // Find out where the protocol ends
00119   ssize_t ior_index = ior.find ("://");
00120 
00121   if (ior_index == ACE_CString::npos)
00122     {
00123       ACE_THROW_RETURN (CORBA::INV_OBJREF (), -1);
00124       // No colon ':' in the IOR!
00125     }
00126   else
00127     {
00128       ior_index += 3;
00129       // Add the length of the colon and the two forward slashes `://'
00130       // to the IOR string index (i.e. 3)
00131     }
00132 
00133   // Find the object key
00134   const ssize_t objkey_index =
00135     ior.find (this->object_key_delimiter (), ior_index);
00136 
00137   if (objkey_index == 0 || objkey_index == ACE_CString::npos)
00138     {
00139       ACE_THROW_RETURN (CORBA::INV_OBJREF (), -1);
00140       // Failure: No endpoints specified or no object key specified.
00141     }
00142 
00143   const char endpoint_delimiter = ',';
00144   // The delimiter used to seperate inidividual addresses.
00145 
00146   // Count the number of endpoints in the IOR.  This will be the number
00147   // of entries in the MProfile.
00148 
00149   CORBA::ULong profile_count = 1;
00150   // Number of endpoints in the IOR  (initialized to 1).
00151 
00152   // Only check for endpoints after the protocol specification and
00153   // before the object key.
00154   for (ssize_t i = ior_index; i < objkey_index; ++i)
00155     {
00156       if (ior[i] == endpoint_delimiter)
00157         ++profile_count;
00158     }
00159 
00160   // Tell the MProfile object how many Profiles it should hold.
00161   // MProfile::set(size) returns the number profiles it can hold.
00162   if (mprofile.set (profile_count) != static_cast<int> (profile_count))
00163     {
00164       ACE_THROW_RETURN (CORBA::INV_OBJREF (
00165                           CORBA::SystemException::_tao_minor_code (
00166                             TAO_MPROFILE_CREATION_ERROR,
00167                             0),
00168                           CORBA::COMPLETED_NO),
00169                         -1);
00170       // Error while setting the MProfile size!
00171     }
00172 
00173   // The idea behind the following loop is to split the IOR into several
00174   // strings that can be parsed by each profile.
00175   // For example,
00176   //    `1.3@moo,shu,1.1@chicken/arf'
00177   // will be parsed into:
00178   //    `1.3@moo/arf'
00179   //    `shu/arf'
00180   //    `1.1@chicken/arf'
00181 
00182   ssize_t begin = 0;
00183   ssize_t end = ior_index - 1;
00184   // Initialize the end of the endpoint index
00185 
00186   for (CORBA::ULong j = 0; j < profile_count; ++j)
00187     {
00188       begin = end + 1;
00189 
00190       if (j < profile_count - 1)
00191         {
00192           end = ior.find (endpoint_delimiter, begin);
00193         }
00194       else
00195         {
00196           end = objkey_index;  // Handle last endpoint differently
00197         }
00198 
00199       if (end < static_cast<ssize_t> (ior.length ()) && end != ior.npos)
00200         {
00201           ACE_CString endpoint = ior.substring (begin, end - begin);
00202 
00203           // Add the object key to the string.
00204           endpoint += ior.substring (objkey_index);
00205 
00206           // The endpoint should now be of the form:
00207           //    `N.n@endpoint/object_key'
00208           // or
00209           //    `endpoint/object_key'
00210 
00211           TAO_Profile *profile =
00212             this->make_profile (ACE_ENV_SINGLE_ARG_PARAMETER);
00213           ACE_CHECK_RETURN (-1);
00214           // Failure:  Problem during profile creation
00215 
00216           // Initialize a Profile using the individual endpoint
00217           // string.
00218           // @@ Not exception safe!  We need a TAO_Profile_var!
00219           profile->parse_string (endpoint.c_str ()
00220                                  ACE_ENV_ARG_PARAMETER);
00221           ACE_CHECK_RETURN (-1);
00222 
00223           // Give up ownership of the profile.
00224           if (mprofile.give_profile (profile) == -1)
00225             {
00226               profile->_decr_refcnt ();
00227 
00228               ACE_THROW_RETURN (CORBA::INV_OBJREF (
00229                                   CORBA::SystemException::_tao_minor_code (
00230                                      TAO_MPROFILE_CREATION_ERROR,
00231                                      0),
00232                                   CORBA::COMPLETED_NO),
00233                                 -1);
00234               // Failure presumably only occurs when MProfile is full!
00235               // This should never happen.
00236             }
00237         }
00238       else
00239         {
00240           ACE_THROW_RETURN (CORBA::INV_OBJREF (), -1);
00241           // Unable to seperate endpoints
00242         }
00243     }
00244 
00245   return 0;  // Success
00246 }

TAO_Transport * TAO_Connector::make_parallel_connection TAO::Profile_Transport_Resolver r,
TAO_Transport_Descriptor_Interface desc,
ACE_Time_Value timeout
[protected, virtual]
 

Make a connection using - not a pure virtual since not all protocols support this.

Reimplemented in TAO_IIOP_Connector.

Definition at line 255 of file Transport_Connector.cpp.

Referenced by parallel_connect().

00258 {
00259   return 0;
00260 }

virtual TAO_Profile* TAO_Connector::make_profile  )  [protected, pure virtual]
 

Create a profile with a given endpoint.

Implemented in TAO_IIOP_Connector.

Referenced by corbaloc_scan(), and make_mprofile().

virtual char TAO_Connector::object_key_delimiter void   )  const [pure virtual]
 

Return the object key delimiter to use or expect.

Implemented in TAO_IIOP_Connector.

virtual int TAO_Connector::open TAO_ORB_Core orb_core  )  [pure virtual]
 

Initialize object and register with reactor.

Implemented in TAO_IIOP_Connector.

TAO_BEGIN_VERSIONED_NAMESPACE_DECL ACE_INLINE TAO_ORB_Core * TAO_Connector::orb_core void   )  [protected]
 

Return the TAO_ORB_Core pointer.

Definition at line 8 of file Transport_Connector.inl.

Referenced by TAO_IIOP_Connector::complete_connection(), connect(), TAO_IIOP_Connector::make_parallel_connection(), TAO_IIOP_Connector::open(), and parallel_connect().

00009 {
00010   return this->orb_core_;
00011 }

ACE_INLINE void TAO_Connector::orb_core TAO_ORB_Core orb_core  )  [protected]
 

Set the ORB Core pointer.

Definition at line 14 of file Transport_Connector.inl.

00015 {
00016   this->orb_core_ = orb_core;
00017 }

TAO_Transport * TAO_Connector::parallel_connect TAO::Profile_Transport_Resolver r,
TAO_Transport_Descriptor_Interface desc,
ACE_Time_Value timeout
[virtual]
 

A variation on connect that will try simultanious connections on all endpoints listed in the desc.

Definition at line 264 of file Transport_Connector.cpp.

References ACE_DEBUG, ACE_TEXT, TAO_Transport_Descriptor_Interface::endpoint(), ENOTSUP, TAO::Transport_Cache_Manager::find_transport(), TAO_Transport::id(), TAO_ORB_Core::lane_resources(), LM_DEBUG, make_parallel_connection(), TAO_Endpoint::next_filtered(), orb_core(), set_validate_endpoint(), supports_parallel_connects(), TAO_debug_level, and TAO_Thread_Lane_Resources::transport_cache().

00268 {
00269   if (this->supports_parallel_connects() == 0)
00270     {
00271       errno = ENOTSUP;
00272       return 0;
00273     }
00274 
00275   errno = 0; // need to clear errno to ensure a stale enotsup is not set
00276   if (desc == 0)
00277     return 0;
00278   unsigned int endpoint_count = 0;
00279   TAO_Endpoint *root_ep = desc->endpoint();
00280   for (TAO_Endpoint *ep = root_ep->next_filtered (this->orb_core(),0);
00281        ep != 0;
00282        ep = ep->next_filtered(this->orb_core(),root_ep))
00283     if (this->set_validate_endpoint (ep) == 0)
00284       ++endpoint_count;
00285   if (endpoint_count == 0)
00286     return 0;
00287 
00288   TAO_Transport *base_transport = 0;
00289 
00290   TAO::Transport_Cache_Manager &tcm =
00291     this->orb_core ()->lane_resources ().transport_cache ();
00292 
00293   // Iterate through the endpoints. Since find_transport takes a
00294   // Transport Descriptor rather than an endpoint, we must create a
00295   // local TDI for each endpoint. The first one found will be used.
00296   for (TAO_Endpoint *ep = root_ep->next_filtered (this->orb_core(),0);
00297        ep != 0;
00298        ep = ep->next_filtered(this->orb_core(),root_ep))
00299     {
00300       TAO_Base_Transport_Property desc2(ep,0);
00301       if (tcm.find_transport (&desc2,
00302                               base_transport) == 0)
00303         {
00304           if (TAO_debug_level)
00305             ACE_DEBUG ((LM_DEBUG,
00306                         ACE_TEXT ("(%P|%t) TAO_Connector::parallel_connect: ")
00307                         ACE_TEXT ("found a transport [%d]\n"),
00308                         base_transport->id()));
00309           return base_transport;
00310         }
00311     }
00312 
00313   // Now we have searched the cache on all endpoints and come up
00314   // empty. We need to initiate connections on each of the
00315   // endpoints. Presumably only one will have a route and will succeed,
00316   // and the rest will fail. This requires the use of asynch
00317   // connection establishment. Maybe a custom wait strategy is needed
00318   // at this point to register several potential transports so that
00319   // when one succeeds the rest are cancelled or closed.
00320 
00321   return this->make_parallel_connection (r,*desc,timeout);
00322 }

virtual int TAO_Connector::set_validate_endpoint TAO_Endpoint endpoint  )  [protected, pure virtual]
 

Set and validate endpoint. We need to do this to initialize our remote *_Addr's which have not been done during IOR decode.

Implemented in TAO_IIOP_Connector.

Referenced by connect(), and parallel_connect().

int TAO_Connector::supports_parallel_connects void   )  const [protected, virtual]
 

A flag indicating the actual connector supports parallel connection attempts. The base implementation alwayse returns 0. Override to return non-zero if parallel connection attempts may be tried.

Reimplemented in TAO_IIOP_Connector.

Definition at line 249 of file Transport_Connector.cpp.

Referenced by parallel_connect().

00250 {
00251   return 0; // by default, we don't support parallel connection attempts;
00252 }

ACE_INLINE CORBA::ULong TAO_Connector::tag void   )  const
 

The tag identifying the specific ORB transport layer protocol. For example IOP::TAG_INTERNET_IOP == 0. The tag is used in the IOR to identify the type of profile included. IOR -> {{tag0, profile0} {tag1, profile1} ...}. The IOP module defines the ProfileId typedef to be a CORBA::ULong.

Definition at line 20 of file Transport_Connector.inl.

00021 {
00022   return this->tag_;
00023 }

bool TAO_Connector::wait_for_connection_completion TAO::Profile_Transport_Resolver r,
TAO_Transport *&  the_winner,
TAO_Transport **  transport,
unsigned int  count,
TAO_LF_Multi_Event mev,
ACE_Time_Value timeout
[protected, virtual]
 

In the case of a parallel connection attempt, we take an array of transports, and wait on any of them. When the first one completes, the rest are closed.

Definition at line 544 of file Transport_Connector.cpp.

References ACE_DEBUG, ACE_ERROR, ACE_TEXT, active_connect_strategy_, TAO::Profile_Transport_Resolver::blocked_connect(), cancel_svc_handler(), check_connection_closure(), TAO_Transport::connection_handler(), ETIME, TAO_Transport::id(), TAO_Connection_Handler::is_closed(), TAO_Transport::is_connected(), LM_DEBUG, LM_ERROR, TAO_debug_level, TAO_Connection_Handler::transport(), TAO_Connect_Strategy::wait(), and TAO_LF_Multi_Event::winner().

00551 {
00552   if (TAO_debug_level > 2)
00553     {
00554       ACE_DEBUG ((LM_DEBUG,
00555                   ACE_TEXT("(%P|%t) Transport_Connector::")
00556                   ACE_TEXT("wait_for_connection_completion, ")
00557                   ACE_TEXT("waiting for connection completion on ")
00558                   ACE_TEXT("%d transports, ["),
00559                   count));
00560       for (unsigned int i = 0; i < count; i++)
00561         ACE_DEBUG ((LM_DEBUG,
00562                     ACE_TEXT("%d%s"),transport[i]->id(),
00563                     (i < (count -1) ? ", " : "]\n")));
00564     }
00565 
00566   // If we don't need to block for a transport just set the timeout to
00567   // be zero.
00568   ACE_Time_Value tmp_zero (ACE_Time_Value::zero);
00569   if (!r->blocked_connect ())
00570     {
00571       timeout = &tmp_zero;
00572     }
00573 
00574   int result = this->active_connect_strategy_->wait (mev,timeout);
00575   the_winner = 0;
00576 
00577   if (result != -1)
00578     {
00579       the_winner = mev->winner()->transport();
00580       if (TAO_debug_level > 2)
00581         ACE_DEBUG ((LM_DEBUG,
00582                     ACE_TEXT("(%P|%t) Transport_Connector::")
00583                     ACE_TEXT("wait_for_connection_completion, ")
00584                     ACE_TEXT("transport [%d]\n"),
00585                     the_winner->id ()));
00586     }
00587   else if (errno == ETIME)
00588     {
00589       // this is the most difficult case. In this situation, there is no
00590       // nominated by the Multi_Event. The best we can do is pick one of
00591       // the pending connections.
00592       // Of course, this shouldn't happen in any case, since the wait
00593       // strategy is called with a timeout value of 0.
00594       for (unsigned int i = 0; i < count; i++)
00595         if (!transport[i]->connection_handler()->is_closed())
00596           {
00597             the_winner = transport[i];
00598             break;
00599           }
00600     }
00601 
00602   // It is possible that we have more than one connection that happened
00603   // to complete, or that none completed. Therefore we need to traverse
00604   // the list and ensure that all of the losers are closed.
00605   for (unsigned int i = 0; i < count; i++)
00606     {
00607       if (transport[i] != the_winner)
00608         this->check_connection_closure (transport[i]->connection_handler());
00609       // since we are doing this on may connections, the result isn't
00610       // particularly important.
00611     }
00612 
00613   // In case of errors.
00614   if (the_winner == 0)
00615     {
00616       // Report that making the connection failed, don't print errno
00617       // because we touched the reactor and errno could be changed
00618       if (TAO_debug_level > 2)
00619         ACE_ERROR ((LM_ERROR,
00620                     ACE_TEXT ("(%P|%t) Transport_Connector::")
00621                     ACE_TEXT ("wait_for_connection_completion, failed\n")
00622                     ));
00623 
00624       return false;
00625     }
00626 
00627   // Fix for a subtle problem. What happens if we are supposed to do
00628   // blocked connect but the transport is NOT connected? Force close
00629   // the connections
00630   if (r->blocked_connect () && !the_winner->is_connected ())
00631     {
00632       if (TAO_debug_level > 2)
00633         ACE_DEBUG ((LM_DEBUG,
00634                     "TAO (%P|%t) - Transport_Connector::"
00635                     "wait_for_connection_completion, "
00636                     "no connected transport for a blocked connection, "
00637                     "cancelling connections and reverting things \n"));
00638 
00639       // Forget the return value. We are busted anyway. Try our best
00640       // here.
00641       (void) this->cancel_svc_handler (the_winner->connection_handler ());
00642       the_winner = 0;
00643       return false;
00644     }
00645 
00646   // Connection may not ready for SYNC_NONE cases but we can use this
00647   // transport, if we need a connected one we will block later to make
00648   // sure it is connected
00649   return true;
00650 }

bool TAO_Connector::wait_for_connection_completion TAO::Profile_Transport_Resolver r,
TAO_Transport *&  transport,
ACE_Time_Value timeout
[protected, virtual]
 

Wait for connection completion. We have a transport that is not connected yet, wait until it is connected.

Return values:
true When we could use transport
Returns:
false When we can't use the transport

Definition at line 450 of file Transport_Connector.cpp.

References ACE_DEBUG, ACE_ERROR, active_connect_strategy_, TAO::Profile_Transport_Resolver::blocked_connect(), check_connection_closure(), TAO_Transport::connection_handler(), ETIME, TAO_Transport::id(), LM_DEBUG, LM_ERROR, TAO_debug_level, and TAO_Connect_Strategy::wait().

Referenced by TAO_IIOP_Connector::complete_connection(), and connect().

00454 {
00455   if (TAO_debug_level > 2)
00456       ACE_DEBUG ((LM_DEBUG,
00457                   "TAO (%P|%t) - Transport_Connector::"
00458                   "wait_for_connection_completion, "
00459                   "going to wait for connection completion on transport"
00460                   "[%d]\n",
00461                   transport->id ()));
00462   // If we don't need to block for a transport just set the timeout to
00463   // be zero.
00464   ACE_Time_Value tmp_zero (ACE_Time_Value::zero);
00465   if (!r->blocked_connect ())
00466     {
00467       timeout = &tmp_zero;
00468     }
00469 
00470   // Wait until the connection is ready, when non-blocking we just do a wait
00471   // with zero time
00472   int result =
00473     this->active_connect_strategy_->wait (
00474       transport,
00475       timeout);
00476 
00477   if (TAO_debug_level > 2)
00478     ACE_DEBUG ((LM_DEBUG,
00479                 "TAO (%P|%t) - Transport_Connector::"
00480                 "wait_for_connection_completion, "
00481                 "transport [%d], wait done result = %d\n",
00482                 transport->id (), result));
00483 
00484   // There are three possibilities when wait() returns: (a)
00485   // connection succeeded; (b) connection failed; (c) wait()
00486   // failed because of some other error.  It is easy to deal with
00487   // (a) and (b).  (c) is tricky since the connection is still
00488   // pending and may get completed by some other thread.  The
00489   // following method deals with (c).
00490 
00491   if (result == -1)
00492     {
00493       if (!r->blocked_connect () && errno == ETIME)
00494         {
00495           if (TAO_debug_level > 2)
00496             ACE_DEBUG ((LM_DEBUG,
00497                         "TAO (%P|%t) - Transport_Connector::"
00498                         "wait_for_connection_completion, "
00499                         "transport [%d], timeout, resetting state.\n",
00500                         transport->id ()));
00501           transport->connection_handler()->
00502             reset_state(TAO_LF_Event::LFS_CONNECTION_WAIT);
00503           // If we did a non blocking connect, just ignore
00504           // any timeout errors
00505           result = 0;
00506         }
00507       else
00508         {
00509           // When we need to get a connected transport
00510           result =
00511             this->check_connection_closure (
00512               transport->connection_handler ());
00513         }
00514 
00515       // In case of errors.
00516       if (result == -1)
00517         {
00518           // Report that making the connection failed, don't print errno
00519           // because we touched the reactor and errno could be changed
00520           if (TAO_debug_level > 2)
00521             ACE_ERROR ((LM_ERROR,
00522                         "TAO (%P|%t) - Transport_Connector::"
00523                         "wait_for_connection_completion, "
00524                         "transport [%d], wait for completion failed\n",
00525                         transport->id()));
00526 
00527 
00528           // Set transport to zero, it is not usable, and the reference
00529           // count we added above was decremented by the base connector
00530           // handling the connection failure.
00531           transport = 0;
00532 
00533           return false;
00534         }
00535     }
00536 
00537   // Connection not ready yet but we can use this transport, if
00538   // we need a connected one we will block later to make sure
00539   // it is connected
00540   return true;
00541 }


Member Data Documentation

TAO_Connect_Strategy* TAO_Connector::active_connect_strategy_ [protected]
 

The (a)synch connect strategy.

Definition at line 221 of file Transport_Connector.h.

Referenced by create_connect_strategy(), wait_for_connection_completion(), and ~TAO_Connector().

TAO_ORB_Core* TAO_Connector::orb_core_ [private]
 

Pointer to our ORB core.

Definition at line 229 of file Transport_Connector.h.

CORBA::ULong const TAO_Connector::tag_ [private]
 

IOP protocol tag.

Definition at line 226 of file Transport_Connector.h.


The documentation for this class was generated from the following files:
Generated on Thu Nov 9 12:12:57 2006 for TAO by doxygen 1.3.6