Optimized_Connection_Endpoint_Selector.cpp

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 #include "tao/Strategies/Optimized_Connection_Endpoint_Selector.h"
00004 
00005 #include "tao/debug.h"
00006 #include "tao/Stub.h"
00007 #include "tao/Profile.h"
00008 #include "tao/Endpoint.h"
00009 #include "tao/Base_Transport_Property.h"
00010 #include "tao/ORB_Core.h"
00011 #include "tao/Transport.h"
00012 #include "tao/Profile_Transport_Resolver.h"
00013 
00014 ACE_RCSID (tao,
00015            Invocation_Endpoint_Selectors,
00016            "Optimized_Connection_Endpoint_Selector.cpp,v 1.4 2006/04/26 19:08:02 mesnier_p Exp")
00017 
00018 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00019 
00020 // ****************************************************************
00021 
00022 ACE_Time_Value TAO_Optimized_Connection_Endpoint_Selector::timeout_;
00023 
00024 TAO_Optimized_Connection_Endpoint_Selector::TAO_Optimized_Connection_Endpoint_Selector (const ACE_Time_Value &tv)
00025 {
00026   TAO_Optimized_Connection_Endpoint_Selector::timeout_ = tv;
00027   if (TAO_debug_level)
00028     {
00029       ACE_DEBUG ((LM_DEBUG,
00030                   ACE_TEXT ("TAO(%P|%t) Optimized Connection Enpoint Selector: ")
00031                   ACE_TEXT ("Initializing timeout hook tv = %d sec, %d usec\n"),
00032               tv.sec(), tv.usec()));
00033     }
00034   if (tv > ACE_Time_Value::zero)
00035     {
00036       TAO_ORB_Core::connection_timeout_hook
00037         (TAO_Optimized_Connection_Endpoint_Selector::hook);
00038     }
00039 }
00040 
00041 TAO_Optimized_Connection_Endpoint_Selector::~TAO_Optimized_Connection_Endpoint_Selector (void)
00042 {
00043 }
00044 
00045 
00046 void
00047 TAO_Optimized_Connection_Endpoint_Selector::hook (TAO_ORB_Core *,
00048                                                   TAO_Stub *,
00049                                                   bool &has_timeout,
00050                                                   ACE_Time_Value &tv)
00051 {
00052   has_timeout =
00053     TAO_Optimized_Connection_Endpoint_Selector::
00054     timeout_ > ACE_Time_Value::zero;
00055   if (has_timeout)
00056     tv = TAO_Optimized_Connection_Endpoint_Selector::timeout_;
00057 }
00058 
00059 int
00060 TAO_Optimized_Connection_Endpoint_Selector::check_profile (TAO_Profile *p,
00061                                                            TAO::Profile_Transport_Resolver *r)
00062 {
00063   TAO_Endpoint *effective_endpoint = 0;
00064 
00065   r->profile(p);
00066   effective_endpoint = p->endpoint ();
00067   size_t endpoint_count = p->endpoint_count();
00068   for (size_t i = 0; i < endpoint_count; ++i)
00069     {
00070       TAO_Base_Transport_Property desc (effective_endpoint);
00071       if (r->find_transport(&desc))
00072         return 1;
00073       // Go to the next endpoint in this profile
00074       effective_endpoint = effective_endpoint->next();
00075     }
00076   return 0;
00077 }
00078 
00079 void
00080 TAO_Optimized_Connection_Endpoint_Selector::select_endpoint
00081   ( TAO::Profile_Transport_Resolver *r,
00082     ACE_Time_Value *max_wait_time
00083     ACE_ENV_ARG_DECL)
00084 {
00085   TAO_Stub *stub = r->stub();
00086   TAO_Profile *p = stub->profile_in_use();
00087 
00088   // first, look for the endpoints for the current profile in use.
00089   // if that is available then go for it.
00090 
00091   if (this->check_profile (p, r) != 0)
00092     return;
00093 
00094   // next, look for any other profiles. If the stub has any forward profiles,
00095   // use those, otherwise look at the base profiles. This separation is
00096   // necessary to avoid re-using a corbaloc or other previously forwarded
00097   // profile.
00098 
00099   const TAO_MProfile *profiles = stub->forward_profiles();
00100   if (profiles != 0)
00101     {
00102       for (CORBA::ULong count = 0; count <  profiles->profile_count(); count++)
00103         {
00104           p = const_cast<TAO_Profile *>(profiles->get_profile(count));
00105           if (this->check_profile (p, r) != 0)
00106             {
00107               if (stub->profile_in_use() != p)
00108                 {
00109                   // thread-safe way to coerse stub to this profile.
00110                   stub->reset_profiles();
00111                   while (stub->profile_in_use() != p)
00112                     if (stub->next_profile_retry() == 0)
00113                       break;
00114                 }
00115               return;
00116             }
00117         }
00118     }
00119   else
00120     {
00121       do
00122         {
00123           p = stub->profile_in_use();
00124           if (this->check_profile(p, r) != 0)
00125             return;
00126         }
00127       while (stub->next_profile_retry () != 0);
00128     }
00129 
00130 
00131 
00132   // at this point, we do not have an existing transport, so we must
00133   // reset the profile list and try establishing connections via the
00134   // connector(s).
00135 
00136   do
00137     {
00138       r->profile (r->stub ()->profile_in_use ());
00139 
00140       // Check whether we need to do a blocked wait or we have a
00141       // non-blocked wait and we support that.  If this is not the
00142       // case we can't use this profile so try the next.
00143       if (r->blocked_connect () ||
00144          (!r->blocked_connect () && r->profile ()->supports_non_blocking_oneways ()))
00145         {
00146           const size_t endpoint_count =
00147             r->profile ()->endpoint_count ();
00148 
00149           TAO_Endpoint *ep =
00150             r->profile ()->endpoint ();
00151 
00152           for (size_t i = 0; i < endpoint_count; ++i)
00153             {
00154               TAO_Base_Transport_Property desc (ep);
00155               const bool retval =
00156                 r->try_connect (&desc,
00157                                 max_wait_time
00158                                 ACE_ENV_ARG_PARAMETER);
00159               ACE_CHECK;
00160 
00161               // Check if the connect has completed.
00162               if (retval)
00163                 return;
00164 
00165               // Go to the next endpoint in this profile.
00166               ep = ep->next ();
00167             }
00168         }
00169     }
00170   while (r->stub ()->next_profile_retry () != 0);
00171 
00172   // If we get here, we completely failed to find an endpoint selector
00173   // that we know how to use, so throw an exception.
00174   ACE_THROW (CORBA::TRANSIENT (CORBA::OMGVMCID | 2,
00175                                CORBA::COMPLETED_NO));
00176 }
00177 
00178 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Thu Nov 9 13:39:29 2006 for TAO_Strategies by doxygen 1.3.6