#include <Transport_Connector.h>
Inheritance diagram for TAO_Connector:
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_Profile * | corbaloc_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_Transport * | connect (TAO::Profile_Transport_Resolver *r, TAO_Transport_Descriptor_Interface *desc, ACE_Time_Value *timeout) |
virtual TAO_Transport * | parallel_connect (TAO::Profile_Transport_Resolver *r, TAO_Transport_Descriptor_Interface *desc, ACE_Time_Value *timeout) |
virtual TAO_Profile * | create_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_Profile * | make_profile (void)=0 |
Create a profile with a given endpoint. | |
virtual int | set_validate_endpoint (TAO_Endpoint *endpoint)=0 |
virtual TAO_Transport * | make_connection (TAO::Profile_Transport_Resolver *r, TAO_Transport_Descriptor_Interface &desc, ACE_Time_Value *timeout)=0 |
Make a connection. | |
virtual TAO_Transport * | make_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_Core * | orb_core (void) |
Return the TAO_ORB_Core pointer. | |
Protected Attributes | |
TAO_Connect_Strategy * | active_connect_strategy_ |
The (a)synch connect strategy. | |
Private Attributes | |
CORBA::ULong const | tag_ |
IOP protocol tag. | |
TAO_ORB_Core * | orb_core_ |
Pointer to our ORB core. |
Base class for connector bridge object.
Definition at line 65 of file Transport_Connector.h.
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 }
virtual int TAO_Connector::cancel_svc_handler | ( | TAO_Connection_Handler * | svc_handler | ) | [protected, pure virtual] |
int TAO_Connector::check_connection_closure | ( | TAO_Connection_Handler * | connection_handler | ) | [protected, virtual] |
Check whether the connection is not closed.
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] |
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] |
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().
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] |
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_.
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.
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.
true | When we could use 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 }
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] |