Transport_Connector.cpp

Go to the documentation of this file.
00001 #include "tao/Transport_Connector.h"
00002 #include "tao/Transport.h"
00003 #include "tao/ORB_Core.h"
00004 #include "tao/MProfile.h"
00005 #include "tao/Profile.h"
00006 #include "tao/Thread_Lane_Resources.h"
00007 #include "tao/debug.h"
00008 #include "tao/Connect_Strategy.h"
00009 #include "tao/LF_Multi_Event.h"
00010 #include "tao/Client_Strategy_Factory.h"
00011 #include "tao/Connection_Handler.h"
00012 #include "tao/Profile_Transport_Resolver.h"
00013 #include "tao/Wait_Strategy.h"
00014 #include "tao/SystemException.h"
00015 #include "tao/Endpoint.h"
00016 #include "tao/Base_Transport_Property.h"
00017 
00018 #include "ace/OS_NS_string.h"
00019 
00020 //@@ TAO_CONNECTOR_SPL_INCLUDE_ADD_HOOK
00021 
00022 #if !defined (__ACE_INLINE__)
00023 # include "tao/Transport_Connector.inl"
00024 #endif /* __ACE_INLINE__ */
00025 
00026 ACE_RCSID (tao,
00027            Connector,
00028            "$Id: Transport_Connector.cpp 79388 2007-08-17 16:05:00Z wilsond $")
00029 
00030 namespace
00031 {
00032   class TransportCleanupGuard
00033   {
00034   public:
00035 
00036     TransportCleanupGuard (TAO_Transport *tp)
00037       : tp_ (tp)
00038       , awake_ (true)
00039     {
00040     }
00041 
00042     ~TransportCleanupGuard ()
00043     {
00044       if (this->awake_ && this->tp_)
00045         {
00046           // Purge from the connection cache.  If we are not in the
00047           // cache, this does nothing.
00048           this->tp_->purge_entry ();
00049 
00050           // Close the handler.
00051           this->tp_->close_connection ();
00052 
00053           this->tp_->remove_reference ();
00054         }
00055     }
00056 
00057     /// Turn off the guard.
00058     void down ()
00059     {
00060       this->awake_ = false;
00061     }
00062 
00063   private:
00064 
00065     TAO_Transport * const tp_;
00066     bool awake_;
00067 
00068   };
00069 }
00070 
00071 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00072 
00073 // Connector
00074 TAO_Connector::TAO_Connector (CORBA::ULong tag)
00075   : active_connect_strategy_ (0),
00076     tag_ (tag),
00077     orb_core_ (0)
00078 {
00079 }
00080 
00081 TAO_Connector::~TAO_Connector (void)
00082 {
00083   delete this->active_connect_strategy_;
00084 }
00085 
00086 TAO_Profile *
00087 TAO_Connector::corbaloc_scan (const char *str, size_t &len)
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 }
00102 
00103 int
00104 TAO_Connector::make_mprofile (const char *string, TAO_MProfile &mprofile)
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 }
00272 
00273 int
00274 TAO_Connector::supports_parallel_connects(void) const
00275 {
00276   return 0; // by default, we don't support parallel connection attempts;
00277 }
00278 
00279 TAO_Transport*
00280 TAO_Connector::make_parallel_connection (TAO::Profile_Transport_Resolver *,
00281                                          TAO_Transport_Descriptor_Interface &,
00282                                          ACE_Time_Value *)
00283 {
00284   return 0;
00285 }
00286 
00287 
00288 TAO_Transport*
00289 TAO_Connector::parallel_connect (TAO::Profile_Transport_Resolver *r,
00290                                  TAO_Transport_Descriptor_Interface *desc,
00291                                  ACE_Time_Value *timeout)
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 }
00349 
00350 TAO_Transport*
00351 TAO_Connector::connect (TAO::Profile_Transport_Resolver *r,
00352                         TAO_Transport_Descriptor_Interface *desc,
00353                         ACE_Time_Value *timeout)
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 }
00463 
00464 bool
00465 TAO_Connector::wait_for_connection_completion (
00466     TAO::Profile_Transport_Resolver *r,
00467     TAO_Transport *&transport,
00468     ACE_Time_Value *timeout)
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 }
00590 
00591 bool
00592 TAO_Connector::wait_for_connection_completion (
00593     TAO::Profile_Transport_Resolver *r,
00594     TAO_Transport *&the_winner,
00595     TAO_Transport **transport,
00596     unsigned int count,
00597     TAO_LF_Multi_Event *mev,
00598     ACE_Time_Value *timeout)
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 }
00705 
00706 int
00707 TAO_Connector::create_connect_strategy (void)
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 }
00723 
00724 int
00725 TAO_Connector::check_connection_closure (
00726   TAO_Connection_Handler *connection_handler)
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 }
00776 
00777 //@@ TAO_CONNECTOR_SPL_METHODS_ADD_HOOK
00778 
00779 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:37:53 2010 for TAO by  doxygen 1.4.7