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 (void)=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 65 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 74 of file Transport_Connector.cpp.

00075   : active_connect_strategy_ (0),
00076     tag_ (tag),
00077     orb_core_ (0)
00078 {
00079 }

TAO_Connector::~TAO_Connector ( void   )  [virtual]

The destructor.

Definition at line 81 of file Transport_Connector.cpp.

References active_connect_strategy_.

00082 {
00083   delete this->active_connect_strategy_;
00084 }


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.

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 725 of file Transport_Connector.cpp.

References ACE_ASSERT, TAO_Connection_Handler::is_closed(), and open().

Referenced by wait_for_connection_completion().

00727 {
00728   int result = -1;
00729 
00730   // Check if the handler has been closed.
00731   bool closed = connection_handler->is_closed ();
00732 
00733   // In case of failures and close() has not be called.
00734   if (!closed)
00735     {
00736       // First, cancel from connector.
00737       if (this->cancel_svc_handler (connection_handler) == -1)
00738         return -1;
00739 
00740       // Double check to make sure the handler has not been closed
00741       // yet.  This double check is required to ensure that the
00742       // connection handler was not closed yet by some other
00743       // thread since it was still registered with the connector.
00744       // Once connector.cancel() has been processed, we are
00745       // assured that the connector will no longer open/close this
00746       // handler.
00747       closed = connection_handler->is_closed ();
00748 
00749       // If closed, there is nothing to do here.  If not closed,
00750       // it was either opened or is still pending.
00751       if (!closed)
00752         {
00753           // Check if the handler has been opened.
00754           const bool open = connection_handler->is_open ();
00755 
00756           // Some other thread was able to open the handler even
00757           // though wait failed for this thread.
00758           if (open)
00759             {
00760               // Set the result to 0, we have an open connection
00761               result = 0;
00762             }
00763           else
00764             {
00765               // Assert that it is still connecting.
00766               ACE_ASSERT (connection_handler->is_connecting ());
00767 
00768               // Force close the handler now.
00769               connection_handler->close_handler ();
00770             }
00771         }
00772     }
00773 
00774   return result;
00775 }

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.

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

Shutdown Connector bridge and concrete Connector.

Implemented in TAO_IIOP_Connector.

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 351 of file Transport_Connector.cpp.

References ACE_DEBUG, ACE_ERROR, ACE_TEXT, TAO_Transport_Descriptor_Interface::endpoint(), 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::purge_entry(), TAO::TAO_CLIENT_ROLE, TAO_debug_level, TAO::TAO_SERVER_ROLE, and TAO_Thread_Lane_Resources::transport_cache().

Referenced by TAO::Profile_Transport_Resolver::try_connect_i().

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

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 87 of file Transport_Connector.cpp.

References make_profile(), ACE_OS::strchr(), and ACE_OS::strlen().

00088 {
00089   if (this->check_prefix (str) != 0)
00090     return 0;
00091   const char *comma_pos = ACE_OS::strchr (str,',');
00092   const char *slash_pos = ACE_OS::strchr (str,'/');
00093   if (comma_pos == 0 && slash_pos == 0)
00094     {
00095       len = ACE_OS::strlen (str);
00096     }
00097   else if (comma_pos == 0 || comma_pos > slash_pos)
00098     len = (slash_pos - str);
00099   else len = comma_pos - str;
00100   return this->make_profile();
00101 }

int TAO_Connector::create_connect_strategy ( void   )  [protected]

Create a connect strategy.

Definition at line 707 of file Transport_Connector.cpp.

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

00708 {
00709   if (this->active_connect_strategy_ == 0)
00710     {
00711       this->active_connect_strategy_ =
00712         this->orb_core_->client_factory ()->create_connect_strategy (
00713           this->orb_core_);
00714     }
00715 
00716   if (this->active_connect_strategy_ == 0)
00717     {
00718       return -1;
00719     }
00720 
00721   return 0;
00722 }

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 104 of file Transport_Connector.cpp.

References TAO_Profile::_decr_refcnt(), CORBA::SystemException::_tao_minor_code(), ACE_DEBUG, ACE_TEXT, ACE_TEXT_CHAR_TO_TCHAR, CORBA::COMPLETED_NO, ACE_String_Base< CHAR >::find(), TAO_MProfile::give_profile(), ACE_String_Base< CHAR >::length(), LM_DEBUG, make_profile(), ACE_String_Base_Const::npos, TAO_Profile::parse_string(), TAO_MProfile::set(), ACE_String_Base< CHAR >::set(), ACE_OS::strlen(), ACE_String_Base< CHAR >::substring(), TAO_debug_level, and TAO_MPROFILE_CREATION_ERROR.

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

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 280 of file Transport_Connector.cpp.

Referenced by parallel_connect().

00283 {
00284   return 0;
00285 }

virtual TAO_Profile* TAO_Connector::make_profile ( void   )  [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.

Referenced by check_connection_closure().

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.

References orb_core_.

Referenced by connect(), TAO_IIOP_Connector::make_parallel_connection(), TAO_IIOP_Connector::open(), orb_core(), 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.

References orb_core(), and orb_core_.

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 289 of file Transport_Connector.cpp.

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

Referenced by TAO::Profile_Transport_Resolver::try_connect_i().

00292 {
00293   if (this->supports_parallel_connects() == 0)
00294     {
00295       errno = ENOTSUP;
00296       return 0;
00297     }
00298 
00299   errno = 0; // need to clear errno to ensure a stale enotsup is not set
00300   if (desc == 0)
00301     return 0;
00302   unsigned int endpoint_count = 0;
00303   TAO_Endpoint *root_ep = desc->endpoint();
00304   for (TAO_Endpoint *ep = root_ep->next_filtered (this->orb_core(),0);
00305        ep != 0;
00306        ep = ep->next_filtered(this->orb_core(),root_ep))
00307     if (this->set_validate_endpoint (ep) == 0)
00308       ++endpoint_count;
00309   if (endpoint_count == 0)
00310     return 0;
00311 
00312   TAO_Transport *base_transport = 0;
00313 
00314   TAO::Transport_Cache_Manager &tcm =
00315     this->orb_core ()->lane_resources ().transport_cache ();
00316 
00317   // Iterate through the endpoints. Since find_transport takes a
00318   // Transport Descriptor rather than an endpoint, we must create a
00319   // local TDI for each endpoint. The first one found will be used.
00320   for (TAO_Endpoint *ep = root_ep->next_filtered (this->orb_core(),0);
00321        ep != 0;
00322        ep = ep->next_filtered(this->orb_core(),root_ep))
00323     {
00324       TAO_Base_Transport_Property desc2(ep,0);
00325       if (tcm.find_transport (&desc2,
00326                               base_transport) == 0)
00327         {
00328           if (TAO_debug_level)
00329             {
00330               ACE_DEBUG ((LM_DEBUG,
00331                           ACE_TEXT ("TAO (%P|%t) - TAO_Connector::parallel_connect: ")
00332                           ACE_TEXT ("found a transport [%d]\n"),
00333                           base_transport->id ()));
00334             }
00335           return base_transport;
00336         }
00337     }
00338 
00339   // Now we have searched the cache on all endpoints and come up
00340   // empty. We need to initiate connections on each of the
00341   // endpoints. Presumably only one will have a route and will succeed,
00342   // and the rest will fail. This requires the use of asynch
00343   // connection establishment. Maybe a custom wait strategy is needed
00344   // at this point to register several potential transports so that
00345   // when one succeeds the rest are cancelled or closed.
00346 
00347   return this->make_parallel_connection (r,*desc,timeout);
00348 }

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.

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 274 of file Transport_Connector.cpp.

00275 {
00276   return 0; // by default, we don't support parallel connection attempts;
00277 }

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.

References tag_.

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 592 of file Transport_Connector.cpp.

References ACE_DEBUG, ACE_ERROR, ACE_TEXT, TAO_Transport::connection_handler(), TAO_Transport::id(), TAO_Transport::is_connected(), LM_DEBUG, LM_ERROR, TAO_debug_level, TAO_Connection_Handler::transport(), and TAO_LF_Multi_Event::winner().

00599 {
00600   if (TAO_debug_level > 2)
00601     {
00602       ACE_DEBUG ((LM_DEBUG,
00603                   ACE_TEXT("TAO (%P|%t) - Transport_Connector::")
00604                   ACE_TEXT("wait_for_connection_completion, ")
00605                   ACE_TEXT("waiting for connection completion on ")
00606                   ACE_TEXT("%d transports, ["),
00607                   count));
00608       for (unsigned int i = 0; i < count; i++)
00609         ACE_DEBUG ((LM_DEBUG,
00610                     ACE_TEXT("%d%s"),transport[i]->id (),
00611                     (i < (count -1) ? ", " : "]\n")));
00612     }
00613 
00614   int result = -1;
00615   if (r->blocked_connect ())
00616     {
00617       result = this->active_connect_strategy_->wait (mev, timeout);
00618       the_winner = 0;
00619     }
00620   else
00621     {
00622       errno = ETIME;
00623     }
00624 
00625   if (result != -1)
00626     {
00627       the_winner = mev->winner()->transport();
00628       if (TAO_debug_level > 2)
00629         {
00630           ACE_DEBUG ((LM_DEBUG,
00631                       ACE_TEXT ("TAO (%P|%t) - Transport_Connector::")
00632                       ACE_TEXT ("wait_for_connection_completion, ")
00633                       ACE_TEXT ("transport [%d]\n"),
00634                       the_winner->id ()));
00635         }
00636     }
00637   else if (errno == ETIME)
00638     {
00639       // this is the most difficult case. In this situation, there is no
00640       // nominated by the Multi_Event. The best we can do is pick one of
00641       // the pending connections.
00642       // Of course, this shouldn't happen in any case, since the wait
00643       // strategy is called with a timeout value of 0.
00644       for (unsigned int i = 0; i < count; i++)
00645         if (!transport[i]->connection_handler()->is_closed())
00646           {
00647             the_winner = transport[i];
00648             break;
00649           }
00650     }
00651 
00652   // It is possible that we have more than one connection that happened
00653   // to complete, or that none completed. Therefore we need to traverse
00654   // the list and ensure that all of the losers are closed.
00655   for (unsigned int i = 0; i < count; i++)
00656     {
00657       if (transport[i] != the_winner)
00658         this->check_connection_closure (transport[i]->connection_handler());
00659       // since we are doing this on may connections, the result isn't
00660       // particularly important.
00661     }
00662 
00663   // In case of errors.
00664   if (the_winner == 0)
00665     {
00666       // Report that making the connection failed, don't print errno
00667       // because we touched the reactor and errno could be changed
00668       if (TAO_debug_level > 2)
00669         {
00670           ACE_ERROR ((LM_ERROR,
00671                       ACE_TEXT ("TAO (%P|%t) - Transport_Connector::")
00672                       ACE_TEXT ("wait_for_connection_completion, failed\n")
00673                       ));
00674         }
00675 
00676       return false;
00677     }
00678 
00679   // Fix for a subtle problem. What happens if we are supposed to do
00680   // blocked connect but the transport is NOT connected? Force close
00681   // the connections
00682   if (r->blocked_connect () && !the_winner->is_connected ())
00683     {
00684       if (TAO_debug_level > 2)
00685         {
00686           ACE_DEBUG ((LM_DEBUG,
00687                       "TAO (%P|%t) - Transport_Connector::"
00688                       "wait_for_connection_completion, "
00689                       "no connected transport for a blocked connection, "
00690                       "cancelling connections and reverting things \n"));
00691         }
00692 
00693       // Forget the return value. We are busted anyway. Try our best
00694       // here.
00695       (void) this->cancel_svc_handler (the_winner->connection_handler ());
00696       the_winner = 0;
00697       return false;
00698     }
00699 
00700   // Connection may not ready for SYNC_NONE and SYNC_DELAYED_BUFFERING cases
00701   // but we can use this transport, if we need a connected one we will poll
00702   // later to make sure it is connected
00703   return true;
00704 }

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 465 of file Transport_Connector.cpp.

References ACE_DEBUG, ACE_ERROR, active_connect_strategy_, check_connection_closure(), TAO_Transport::connection_handler(), TAO_Transport::id(), TAO_Connection_Handler::is_closed(), TAO_Connection_Handler::is_open(), TAO_Connection_Handler::is_timeout(), TAO_LF_Event::LFS_CONNECTION_WAIT, LM_DEBUG, LM_ERROR, TAO_debug_level, and TAO_Connect_Strategy::wait().

00469 {
00470   int result = -1;
00471   if (!r->blocked_connect ())
00472     {
00473       if (transport->connection_handler ()->is_open ())
00474         {
00475           result = 0;
00476         }
00477       else if (transport->connection_handler ()->is_timeout ())
00478         {
00479           if (TAO_debug_level > 2)
00480             {
00481               ACE_DEBUG ((LM_DEBUG,
00482                           "TAO (%P|%t) - Transport_Connector::"
00483                           "wait_for_connection_completion, "
00484                           "transport [%d], Connection timed out.\n",
00485                           transport->id ()));
00486             }
00487           result = -1;
00488           errno = ETIME;
00489         }
00490       else if (transport->connection_handler ()->is_closed ())
00491         {
00492           if (TAO_debug_level > 2)
00493             {
00494               ACE_DEBUG ((LM_DEBUG,
00495               "TAO (%P|%t) - Transport_Connector::"
00496               "wait_for_connection_completion, "
00497               "transport [%d], Connection failed. (%d) %p\n",
00498               transport->id (), errno, ""));
00499             }
00500           result = -1;
00501         }
00502       else
00503         {
00504           if (TAO_debug_level > 2)
00505             {
00506               ACE_DEBUG ((LM_DEBUG,
00507                           "TAO (%P|%t) - Transport_Connector::"
00508                           "wait_for_connection_completion, "
00509                           "transport [%d], Connection not complete.\n",
00510                           transport->id ()));
00511             }
00512           transport->connection_handler ()->
00513             reset_state (TAO_LF_Event::LFS_CONNECTION_WAIT);
00514           result = 0;
00515         }
00516     }
00517   else
00518     {
00519       if (TAO_debug_level > 2)
00520         {
00521             ACE_DEBUG ((LM_DEBUG,
00522                         "TAO (%P|%t) - Transport_Connector::"
00523                         "wait_for_connection_completion, "
00524                         "going to wait for connection completion on transport"
00525                         "[%d]\n",
00526                         transport->id ()));
00527         }
00528       result = this->active_connect_strategy_->wait (transport, timeout);
00529 
00530       if (TAO_debug_level > 2)
00531         {
00532           ACE_DEBUG ((LM_DEBUG,
00533                       "TAO (%P|%t) - Transport_Connector::"
00534                       "wait_for_connection_completion, "
00535                       "transport [%d], wait done result = %d\n",
00536                       transport->id (), result));
00537         }
00538     // There are three possibilities when wait() returns: (a)
00539     // connection succeeded; (b) connection failed; (c) wait()
00540     // failed because of some other error.  It is easy to deal with
00541     // (a) and (b).  (c) is tricky since the connection is still
00542     // pending and may get completed by some other thread.  The
00543     // following code deals with (c).
00544 
00545     if (result == -1)
00546       {
00547         if (errno == ETIME)
00548           {
00549             if (TAO_debug_level > 2)
00550               {
00551                 ACE_DEBUG ((LM_DEBUG,
00552                             "TAO (%P|%t) - Transport_Connector::"
00553                             "wait_for_connection_completion, "
00554                             "transport [%d], Connection timed out.\n",
00555                             transport->id ()));
00556               }
00557           }
00558         else
00559           {
00560             // The wait failed for some other reason.
00561             // Report that making the connection failed, don't print errno
00562             // because we touched the reactor and errno could be changed
00563             if (TAO_debug_level > 2)
00564               {
00565                 ACE_ERROR ((LM_ERROR,
00566                             "TAO (%P|%t) - Transport_Connector::"
00567                             "wait_for_connection_completion, "
00568                   "transport [%d], wait for completion failed (%d) %p\n",
00569                   transport->id (), errno, ""));
00570               }
00571             TAO_Connection_Handler *con = transport->connection_handler ();
00572             result = this->check_connection_closure (con);
00573           }
00574       }
00575     }
00576 
00577   if (result == -1)
00578     {
00579       // Set transport to zero, it is not usable, and the reference
00580       // count we added above was decremented by the base connector
00581       // handling the connection failure.
00582       transport = 0;
00583       return false;
00584     }
00585   // Connection not ready yet but we can use this transport, if
00586   // we need a connected one we will block later to make sure
00587   // it is connected
00588   return true;
00589 }


Member Data Documentation

TAO_Connect_Strategy* TAO_Connector::active_connect_strategy_ [protected]

The (a)synch connect strategy.

Definition at line 201 of file Transport_Connector.h.

Referenced by TAO_IIOP_Connector::begin_connection(), create_connect_strategy(), TAO_IIOP_Connector::make_parallel_connection(), wait_for_connection_completion(), and ~TAO_Connector().

TAO_ORB_Core* TAO_Connector::orb_core_ [private]

Pointer to our ORB core.

Definition at line 209 of file Transport_Connector.h.

Referenced by create_connect_strategy(), and orb_core().

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

IOP protocol tag.

Definition at line 206 of file Transport_Connector.h.

Referenced by tag().


The documentation for this class was generated from the following files:
Generated on Tue Feb 2 17:39:25 2010 for TAO by  doxygen 1.4.7