#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.
|
|
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 } |
|
|
The destructor.
Definition at line 81 of file Transport_Connector.cpp. References active_connect_strategy_.
00082 {
00083 delete this->active_connect_strategy_;
00084 }
|
|
|
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 725 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().
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 }
|
|
|
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 351 of file Transport_Connector.cpp. References ACE_DEBUG, ACE_ERROR, ACE_TEXT, TransportCleanupGuard::down(), 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(). 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 }
|
|
||||||||||||
|
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 check_prefix(), 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 }
|
|
|
Create a connect strategy.
Definition at line 707 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().
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 }
|
|
|
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 104 of file Transport_Connector.cpp. References TAO_Profile::_decr_refcnt(), ACE_CString, ACE_DEBUG, ACE_TEXT, ACE_TEXT_CHAR_TO_TCHAR, check_prefix(), TAO_MProfile::give_profile(), LM_DEBUG, make_profile(), TAO_Profile::parse_string(), TAO_MProfile::set(), 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 }
|
|
||||||||||||||||
|
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 }
|
|
|
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 289 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(). 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 }
|
|
|
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 274 of file Transport_Connector.cpp. Referenced by parallel_connect().
00275 {
00276 return 0; // by default, we don't support parallel connection attempts;
00277 }
|
|
|
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 592 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().
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 }
|
|
||||||||||||||||
|
Wait for connection completion. We have a transport that is not connected yet, wait until it is connected.
Definition at line 465 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(), TAO_Connection_Handler::is_closed(), TAO_Connection_Handler::is_open(), TAO_Connection_Handler::is_timeout(), LM_DEBUG, LM_ERROR, TAO_debug_level, and TAO_Connect_Strategy::wait(). Referenced by TAO_IIOP_Connector::complete_connection(), and connect().
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 create_connect_strategy(), wait_for_connection_completion(), and ~TAO_Connector(). |
|
|
Pointer to our ORB core.
Definition at line 209 of file Transport_Connector.h. |
|
|
IOP protocol tag.
Definition at line 206 of file Transport_Connector.h. |
1.3.6