#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 ()=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 71 of file Transport_Connector.h.
|
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 } |
|
The destructor.
Definition at line 42 of file Transport_Connector.cpp. References active_connect_strategy_.
00043 { 00044 delete this->active_connect_strategy_; 00045 } |
|
Cancel the passed cvs handler from the connector.
Implemented in TAO_IIOP_Connector. Referenced by check_connection_closure(), and wait_for_connection_completion(). |
|
Check whether the connection is not 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 } |
|
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(). |
|
Shutdown Connector bridge and concrete Connector.
Implemented in TAO_IIOP_Connector. Referenced by TAO_Connector_Registry::close_all(). |
|
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 } |
|
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 } |
|
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 } |
|
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(). |
|
Make a connection.
Implemented in TAO_IIOP_Connector. Referenced by connect(). |
|
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 } |
|
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 }
|
|
Create a profile with a given endpoint.
Implemented in TAO_IIOP_Connector. Referenced by corbaloc_scan(), and make_mprofile(). |
|
Return the object key delimiter to use or expect.
Implemented in TAO_IIOP_Connector. |
|
Initialize object and register with reactor.
Implemented in TAO_IIOP_Connector. |
|
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 } |
|
Set the ORB Core pointer.
Definition at line 14 of file Transport_Connector.inl.
00015 { 00016 this->orb_core_ = orb_core; 00017 } |
|
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 } |
|
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(). |
|
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 } |
|
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 } |
|
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 } |
|
Wait for connection completion. We have a transport that is not connected yet, wait until it is connected.
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 } |
|
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(). |
|
Pointer to our ORB core.
Definition at line 229 of file Transport_Connector.h. |
|
IOP protocol tag.
Definition at line 226 of file Transport_Connector.h. |