RT_Invocation_Endpoint_Selectors.cpp

Go to the documentation of this file.
00001 #include "tao/RTCORBA/RT_Invocation_Endpoint_Selectors.h"
00002 
00003 #if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
00004 
00005 #include "tao/RTCORBA/RT_Policy_i.h"
00006 #include "tao/RTCORBA/RT_Stub.h"
00007 #include "tao/RTCORBA/RT_Transport_Descriptor.h"
00008 #include "tao/RTCORBA/RT_Transport_Descriptor_Property.h"
00009 #include "tao/RTCORBA/RT_Endpoint_Utils.h"
00010 #include "tao/RTCORBA/RT_Protocols_Hooks.h"
00011 #include "tao/Stub.h"
00012 #include "tao/ORB_Core.h"
00013 #include "tao/Profile.h"
00014 #include "tao/Endpoint.h"
00015 #include "tao/debug.h"
00016 #include "tao/Profile.h"
00017 #include "tao/Endpoint.h"
00018 #include "tao/Profile_Transport_Resolver.h"
00019 #include "tao/ORB_Core.h"
00020 #include "tao/SystemException.h"
00021 
00022 ACE_RCSID (RTCORBA,
00023            RT_Invocation_Endpoint_Selectors,
00024            "$Id: RT_Invocation_Endpoint_Selectors.cpp 79829 2007-10-23 12:39:52Z johnnyw $")
00025 
00026 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00027 
00028 void
00029 TAO_RT_Invocation_Endpoint_Selector::select_endpoint (
00030     TAO::Profile_Transport_Resolver *r,
00031     ACE_Time_Value *val)
00032 {
00033   if (r == 0)
00034     throw ::CORBA::INTERNAL ();
00035 
00036   CORBA::Policy_var client_protocol_policy_base =
00037     TAO_RT_Endpoint_Utils::policy (TAO_CACHED_POLICY_RT_CLIENT_PROTOCOL, *r);
00038 
00039   if (client_protocol_policy_base.ptr () == 0)
00040     {
00041       do
00042         {
00043           r->profile (r->stub ()->profile_in_use ());
00044 
00045           if (this->endpoint_from_profile (*r, val) == 1)
00046             return;
00047         }
00048       while (r->stub ()->next_profile_retry () != 0);
00049 
00050       // If we get here, we completely failed to find an endpoint selector
00051       // that we know how to use, so throw an exception.
00052       throw ::CORBA::TRANSIENT (CORBA::OMGVMCID | 2, CORBA::COMPLETED_NO);
00053     }
00054   else
00055     {
00056       RTCORBA::ClientProtocolPolicy_var client_protocol_policy =
00057         RTCORBA::ClientProtocolPolicy::_narrow (
00058           client_protocol_policy_base.in ());
00059 
00060       /// Cast to TAO_ClientProtocolPolicy
00061       TAO_ClientProtocolPolicy *tao_client_protocol_policy =
00062         static_cast<TAO_ClientProtocolPolicy *> (client_protocol_policy.in ());
00063 
00064       /// Get the ProtocolList
00065       RTCORBA::ProtocolList &client_protocols =
00066         tao_client_protocol_policy->protocols_rep ();
00067 
00068       this->select_endpoint_based_on_client_protocol_policy (
00069         *r,
00070         client_protocol_policy.in (),
00071         client_protocols,
00072         val);
00073     }
00074 }
00075 
00076 void
00077 TAO_RT_Invocation_Endpoint_Selector::select_endpoint_based_on_client_protocol_policy (
00078     TAO::Profile_Transport_Resolver &r,
00079     RTCORBA::ClientProtocolPolicy_ptr client_protocol_policy,
00080     RTCORBA::ProtocolList &client_protocols,
00081     ACE_Time_Value *val)
00082 {
00083   CORBA::Boolean valid_profile_found = false;
00084 
00085   // Even though cycling through all the protocols is the correct
00086   // things to do to find a match, starting from the start of the
00087   // profile list is not.  In addition, this code is also ignoring the
00088   // forwarded reference (if it exists).  This behavior is caused by
00089   // problems with the profile management in TAO which are documented
00090   // in bugzilla bugs 1237, 1238, and 1239.  Once the above problems
00091   // are fixed, this behavior should be fixed to do the right thing.
00092   for (CORBA::ULong protocol_index = 0;
00093        protocol_index < client_protocols.length ();
00094        ++protocol_index)
00095     {
00096       // Find the profiles that match the current protocol.
00097       TAO_Profile *profile = 0;
00098       TAO_MProfile &mprofile = r.stub ()->base_profiles ();
00099 
00100       for (TAO_PHandle i = 0;
00101            i < mprofile.profile_count ();
00102            ++i)
00103         {
00104           profile = mprofile.get_profile (i);
00105 
00106           if (profile->tag () == client_protocols[protocol_index].protocol_type)
00107             {
00108               valid_profile_found = true;
00109 
00110               r.profile (profile);
00111 
00112               if (this->endpoint_from_profile (r, val) == 1)
00113                 return;
00114               // @@ Else we should check for potential forwarding here.
00115             }
00116         }
00117     }
00118 
00119   // We have tried all the profiles specified in the client protocol
00120   // policy with no success.  Throw exception.
00121   if (!valid_profile_found)
00122     {
00123       if (r.inconsistent_policies ())
00124         {
00125           CORBA::PolicyList *p = r.inconsistent_policies ();
00126 
00127           p->length (1);
00128           (*p)[0u] = CORBA::Policy::_duplicate (client_protocol_policy);
00129         }
00130       throw ::CORBA::INV_POLICY ();
00131     }
00132 
00133   // If we get here, we found at least one pertinent profile, but no
00134   // usable endpoints.
00135   throw ::CORBA::TRANSIENT (CORBA::OMGVMCID | 2, CORBA::COMPLETED_NO);
00136 
00137 }
00138 
00139 int
00140 TAO_RT_Invocation_Endpoint_Selector::endpoint_from_profile (
00141     TAO::Profile_Transport_Resolver &r,
00142     ACE_Time_Value *val)
00143 {
00144   // Narrow to the RT Stub.
00145   TAO_RT_Stub *rt_stub = dynamic_cast <TAO_RT_Stub *> (r.stub ());
00146 
00147   if (!rt_stub)
00148     throw CORBA::INTERNAL ();
00149 
00150   // Get the priority model policy.
00151   CORBA::Policy_var priority_model_policy =
00152     rt_stub->get_cached_policy (TAO_CACHED_POLICY_PRIORITY_MODEL);
00153 
00154   // Get the bands policy.
00155   CORBA::Policy_var bands_policy =
00156     TAO_RT_Endpoint_Utils::policy (
00157       TAO_CACHED_POLICY_RT_PRIORITY_BANDED_CONNECTION, r);
00158 
00159   bool all_endpoints_are_valid = false;
00160   bool match_priority = false;
00161   bool match_bands = false;
00162   CORBA::Short client_thread_priority = 0;
00163   CORBA::Short min_priority = 0;
00164   CORBA::Short max_priority = 0;
00165 
00166   // If the priority model policy is not set.
00167   if (priority_model_policy.ptr () == 0)
00168     {
00169       // Bands without priority model do not make sense.
00170       if (bands_policy.ptr () != 0)
00171         {
00172           if (r.inconsistent_policies ())
00173             {
00174               CORBA::PolicyList *p = r.inconsistent_policies ();
00175 
00176               p->length (1);
00177               (*p)[0u] = CORBA::Policy::_duplicate (bands_policy.in ());
00178             }
00179           // Indicate error.
00180           throw ::CORBA::INV_POLICY ();
00181         }
00182 
00183       // No priority model policy (and no bands policy): all endpoints
00184       // are fair game.
00185       all_endpoints_are_valid = true;
00186     }
00187   // If the priority model policy is set.
00188   else
00189     {
00190       // Get the protocol hooks.
00191       TAO_Protocols_Hooks *protocol_hooks =
00192         r.stub ()->orb_core ()->get_protocols_hooks ();
00193 
00194       if (protocol_hooks != 0)
00195         {
00196           CORBA::Short server_priority = 0;
00197           CORBA::Boolean is_client_propagated = false;
00198 
00199           // Check the priority model policy to see if it is client
00200           // propagated.
00201           protocol_hooks->get_selector_hook (priority_model_policy.in (),
00202                                              is_client_propagated,
00203                                              server_priority);
00204 
00205           if (!is_client_propagated)
00206             {
00207               // Server declared: all endpoints are fair game.
00208               all_endpoints_are_valid = true;
00209             }
00210           // Client propagated.
00211           else
00212             {
00213               // Get client thread priority.
00214               int status =
00215                 protocol_hooks->get_thread_CORBA_priority (
00216                   client_thread_priority);   // side effect
00217               if (status == -1)
00218                 {
00219                   throw ::CORBA::DATA_CONVERSION (
00220                     CORBA::OMGVMCID | 1,
00221                     CORBA::COMPLETED_NO);
00222                 }
00223 
00224               // If there are no bands.
00225               if (bands_policy.ptr () == 0)
00226                 {
00227 
00228                   // Match the priority of the client thread with the
00229                   // endpoint.
00230                   match_priority = true;
00231                 }
00232               // There are bands.
00233               else
00234                 {
00235                   // Check which band range we fall in.
00236                   bool in_range = false;
00237                   protocol_hooks->get_selector_bands_policy_hook (
00238                     bands_policy.in (),
00239                     client_thread_priority,
00240                     min_priority,
00241                     max_priority,
00242                     in_range);
00243 
00244                   // If priority doesn't fall into any of the bands.
00245                   if (!in_range)
00246                     {
00247                       if (r.inconsistent_policies ())
00248                         {
00249 
00250                           CORBA::PolicyList *p = r.inconsistent_policies ();
00251                           p->length (2);
00252                           (*p)[0u] = CORBA::Policy::_duplicate (bands_policy.in ());
00253                           (*p)[1u] =
00254                             CORBA::Policy::_duplicate (
00255                               priority_model_policy.in ());
00256                         }
00257 
00258                       // Indicate error.
00259                       throw ::CORBA::INV_POLICY ();
00260                     }
00261 
00262                   // Match the priority of the band with the endpoint.
00263                   match_bands = true;
00264                 }
00265             }
00266         }
00267     }
00268 
00269   TAO_Endpoint *ep = r.profile ()->endpoint ();
00270 
00271   while (ep != 0)
00272     {
00273       // Get the priority of the endpoint.
00274       CORBA::Short endpoint_priority = ep->priority ();
00275 
00276       // If <all_endpoints_are_valid> or match the priority of the
00277       // client thread or match the priority of the band or
00278       // profile contains just one endpoint.  This happens when:
00279       //    a) we are talking to a nonTAO server (which doesn't have
00280       //       the concept of multiple endpoints per profile)
00281       //    or
00282       //    b) we have TAO server with a non-lane threadpool, in which
00283       //    case there is only one acceptor
00284       // In both cases we should use the endpoint regardless of its priority.
00285 
00286       if (all_endpoints_are_valid ||
00287           (match_priority &&
00288            client_thread_priority == endpoint_priority) ||
00289           (match_bands &&
00290            endpoint_priority <= max_priority &&
00291            endpoint_priority >= min_priority) ||
00292           r.profile ()->endpoint_count () == 1 &&
00293           endpoint_priority == TAO_INVALID_PRIORITY)
00294         {
00295           TAO_RT_Transport_Descriptor_Private_Connection_Property
00296             private_connection_descriptor_property;
00297 
00298           TAO_RT_Transport_Descriptor_Banded_Connection_Property
00299             banded_connection_descriptor_property;
00300 
00301           TAO_RT_Transport_Descriptor rt_transport_descriptor (ep);
00302 
00303           CORBA::Policy_var private_connection_policy =
00304             rt_stub->get_cached_policy (TAO_CACHED_POLICY_RT_PRIVATE_CONNECTION);
00305 
00306           if (!CORBA::is_nil (private_connection_policy.in ()))
00307             {
00308               private_connection_descriptor_property.init
00309                 (static_cast<long> (reinterpret_cast<ptrdiff_t> (r.stub ())));
00310               rt_transport_descriptor.insert
00311                 (&private_connection_descriptor_property);
00312             }
00313 
00314           if (match_bands)
00315             {
00316               banded_connection_descriptor_property.init
00317                 (min_priority, max_priority);
00318 
00319               rt_transport_descriptor.insert
00320                 (&banded_connection_descriptor_property);
00321             }
00322 
00323           // Check if the invocation has completed.
00324           if (r.try_connect (&rt_transport_descriptor, val))
00325             return 1;
00326         }
00327 
00328       // Go to the next endpoint in this profile.
00329       ep = ep->next();
00330     }
00331 
00332   return 0;
00333 }
00334 
00335 TAO_END_VERSIONED_NAMESPACE_DECL
00336 
00337 #endif /* TAO_HAS_CORBA_MESSAGING && TAO_HAS_CORBA_MESSAGING != 0 */

Generated on Tue Feb 2 17:42:49 2010 for TAO_RTCORBA by  doxygen 1.4.7