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 78627 2007-06-28 08:50:01Z 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 
00077 void
00078 TAO_RT_Invocation_Endpoint_Selector::select_endpoint_based_on_client_protocol_policy (
00079     TAO::Profile_Transport_Resolver &r,
00080     RTCORBA::ClientProtocolPolicy_ptr client_protocol_policy,
00081     RTCORBA::ProtocolList &client_protocols,
00082     ACE_Time_Value *val)
00083 {
00084   CORBA::Boolean valid_profile_found = false;
00085 
00086   // Even though cycling through all the protocols is the correct
00087   // things to do to find a match, starting from the start of the
00088   // profile list is not.  In addition, this code is also ignoring the
00089   // forwarded reference (if it exists).  This behavior is caused by
00090   // problems with the profile management in TAO which are documented
00091   // in bugzilla bugs 1237, 1238, and 1239.  Once the above problems
00092   // are fixed, this behavior should be fixed to do the right thing.
00093   for (CORBA::ULong protocol_index = 0;
00094        protocol_index < client_protocols.length ();
00095        ++protocol_index)
00096     {
00097       // Find the profiles that match the current protocol.
00098       TAO_Profile *profile = 0;
00099       TAO_MProfile &mprofile = r.stub ()->base_profiles ();
00100 
00101       for (TAO_PHandle i = 0;
00102            i < mprofile.profile_count ();
00103            ++i)
00104         {
00105           profile = mprofile.get_profile (i);
00106 
00107           if (profile->tag () == client_protocols[protocol_index].protocol_type)
00108             {
00109               valid_profile_found = true;
00110 
00111               r.profile (profile);
00112 
00113               int const status = this->endpoint_from_profile (r, val);
00114 
00115               if (status == 1)
00116                 return;
00117               // @@ Else we should check for potential forwarding here.
00118             }
00119         }
00120     }
00121 
00122   // We have tried all the profiles specified in the client protocol
00123   // policy with no success.  Throw exception.
00124   if (!valid_profile_found)
00125     {
00126       if (r.inconsistent_policies ())
00127         {
00128           CORBA::PolicyList *p = r.inconsistent_policies ();
00129 
00130           p->length (1);
00131           (*p)[0u] = CORBA::Policy::_duplicate (client_protocol_policy);
00132         }
00133       throw ::CORBA::INV_POLICY ();
00134     }
00135 
00136   // If we get here, we found at least one pertinent profile, but no
00137   // usable endpoints.
00138   throw ::CORBA::TRANSIENT (CORBA::OMGVMCID | 2, CORBA::COMPLETED_NO);
00139 
00140 }
00141 
00142 int
00143 TAO_RT_Invocation_Endpoint_Selector::endpoint_from_profile (
00144     TAO::Profile_Transport_Resolver &r,
00145     ACE_Time_Value *val)
00146 {
00147   // Narrow to the RT Stub.
00148   TAO_RT_Stub *rt_stub = dynamic_cast <TAO_RT_Stub *> (r.stub ());
00149 
00150   if (!rt_stub)
00151     throw CORBA::INTERNAL ();
00152 
00153   // Get the priority model policy.
00154   CORBA::Policy_var priority_model_policy =
00155     rt_stub->get_cached_policy (TAO_CACHED_POLICY_PRIORITY_MODEL);
00156 
00157   // Get the bands policy.
00158   CORBA::Policy_var bands_policy =
00159     TAO_RT_Endpoint_Utils::policy (
00160       TAO_CACHED_POLICY_RT_PRIORITY_BANDED_CONNECTION, r);
00161 
00162   int all_endpoints_are_valid = 0;
00163   int match_priority = 0;
00164   int match_bands = 0;
00165   CORBA::Short client_thread_priority = 0;
00166   CORBA::Short min_priority = 0;
00167   CORBA::Short max_priority = 0;
00168 
00169   // If the priority model policy is not set.
00170   if (priority_model_policy.ptr () == 0)
00171     {
00172       // Bands without priority model do not make sense.
00173       if (bands_policy.ptr () != 0)
00174         {
00175           if (r.inconsistent_policies ())
00176             {
00177               CORBA::PolicyList *p = r.inconsistent_policies ();
00178 
00179               p->length (1);
00180               (*p)[0u] = CORBA::Policy::_duplicate (bands_policy.in ());
00181             }
00182           // Indicate error.
00183           throw ::CORBA::INV_POLICY ();
00184         }
00185 
00186       // No priority model policy (and no bands policy): all endpoints
00187       // are fair game.
00188       all_endpoints_are_valid = 1;
00189     }
00190   // If the priority model policy is set.
00191   else
00192     {
00193       // Get the protocol hooks.
00194       TAO_Protocols_Hooks *protocol_hooks =
00195         r.stub ()->orb_core ()->get_protocols_hooks ();
00196 
00197       if (protocol_hooks != 0)
00198         {
00199           CORBA::Short server_priority = 0;
00200           CORBA::Boolean is_client_propagated = false;
00201 
00202           // Check the priority model policy to see if it is client
00203           // propagated.
00204           protocol_hooks->get_selector_hook (priority_model_policy.in (),
00205                                              is_client_propagated,
00206                                              server_priority);
00207 
00208           if (!is_client_propagated)
00209             {
00210               // Server declared: all endpoints are fair game.
00211               all_endpoints_are_valid = 1;
00212             }
00213           // Client propagated.
00214           else
00215             {
00216               // Get client thread priority.
00217               int status =
00218                 protocol_hooks->get_thread_CORBA_priority (
00219                   client_thread_priority  // side effect
00220                  );
00221               if (status == -1)
00222                 {
00223                   throw ::CORBA::DATA_CONVERSION (
00224                     CORBA::OMGVMCID | 1,
00225                     CORBA::COMPLETED_NO);
00226                 }
00227 
00228               // If there are no bands.
00229               if (bands_policy.ptr () == 0)
00230                 {
00231 
00232                   // Match the priority of the client thread with the
00233                   // endpoint.
00234                   match_priority = 1;
00235                 }
00236               // There are bands.
00237               else
00238                 {
00239                   // Check which band range we fall in.
00240                   bool in_range = false;
00241                   protocol_hooks->get_selector_bands_policy_hook (
00242                     bands_policy.in (),
00243                     client_thread_priority,
00244                     min_priority,
00245                     max_priority,
00246                     in_range);
00247 
00248                   // If priority doesn't fall into any of the bands.
00249                   if (!in_range)
00250                     {
00251                       if (r.inconsistent_policies ())
00252                         {
00253 
00254                           CORBA::PolicyList *p = r.inconsistent_policies ();
00255                           p->length (2);
00256                           (*p)[0u] = CORBA::Policy::_duplicate (bands_policy.in ());
00257                           (*p)[1u] =
00258                             CORBA::Policy::_duplicate (
00259                               priority_model_policy.in ());
00260                         }
00261 
00262                       // Indicate error.
00263                       throw ::CORBA::INV_POLICY ();
00264                     }
00265 
00266                   // Match the priority of the band with the endpoint.
00267                   match_bands = 1;
00268                 }
00269             }
00270         }
00271     }
00272 
00273   TAO_Endpoint *ep =
00274     r.profile ()->endpoint ();
00275 
00276   while (ep != 0)
00277     {
00278       // Get the priority of the endpoint.
00279       CORBA::Short endpoint_priority = ep->priority ();
00280 
00281       // If <all_endpoints_are_valid> or match the priority of the
00282       // client thread or match the priority of the band or
00283       // profile contains just one endpoint.  This happens when:
00284       //    a) we are talking to a nonTAO server (which doesn't have
00285       //       the concept of multiple endpoints per profile)
00286       //    or
00287       //    b) we have TAO server with a non-lane threadpool, in which
00288       //    case there is only one acceptor
00289       // In both cases we should use the endpoint regardless of its priority.
00290 
00291       if (all_endpoints_are_valid ||
00292           (match_priority &&
00293            client_thread_priority == endpoint_priority) ||
00294           (match_bands &&
00295            endpoint_priority <= max_priority &&
00296            endpoint_priority >= min_priority) ||
00297           r.profile ()->endpoint_count () == 1 &&
00298           endpoint_priority == TAO_INVALID_PRIORITY)
00299         {
00300           TAO_RT_Transport_Descriptor_Private_Connection_Property
00301             private_connection_descriptor_property;
00302 
00303           TAO_RT_Transport_Descriptor_Banded_Connection_Property
00304             banded_connection_descriptor_property;
00305 
00306           TAO_RT_Transport_Descriptor
00307             rt_transport_descriptor (ep);
00308 
00309           CORBA::Policy_var private_connection_policy =
00310             rt_stub->get_cached_policy (TAO_CACHED_POLICY_RT_PRIVATE_CONNECTION
00311                                        );
00312 
00313           if (!CORBA::is_nil (private_connection_policy.in ()))
00314             {
00315               private_connection_descriptor_property.init
00316                 (static_cast<long> (reinterpret_cast<ptrdiff_t> (r.stub ())));
00317               rt_transport_descriptor.insert
00318                 (&private_connection_descriptor_property);
00319             }
00320 
00321           if (match_bands)
00322             {
00323               banded_connection_descriptor_property.init
00324                 (min_priority, max_priority);
00325 
00326               rt_transport_descriptor.insert
00327                 (&banded_connection_descriptor_property);
00328             }
00329 
00330           bool status =
00331             r.try_connect (&rt_transport_descriptor,
00332                            val
00333                           );
00334 
00335           // Check if the invocation has completed.
00336           if (status == true)
00337             return 1;
00338         }
00339 
00340       // Go to the next endpoint in this profile.
00341       ep = ep->next();
00342     }
00343 
00344   return 0;
00345 }
00346 
00347 TAO_END_VERSIONED_NAMESPACE_DECL
00348 
00349 #endif /* TAO_HAS_CORBA_MESSAGING && TAO_HAS_CORBA_MESSAGING != 0 */

Generated on Sun Jan 27 13:33:22 2008 for TAO_RTCORBA by doxygen 1.3.6