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
00051
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
00061 TAO_ClientProtocolPolicy *tao_client_protocol_policy =
00062 static_cast<TAO_ClientProtocolPolicy *> (client_protocol_policy.in ());
00063
00064
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
00086
00087
00088
00089
00090
00091
00092 for (CORBA::ULong protocol_index = 0;
00093 protocol_index < client_protocols.length ();
00094 ++protocol_index)
00095 {
00096
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
00115 }
00116 }
00117 }
00118
00119
00120
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
00134
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
00145 TAO_RT_Stub *rt_stub = dynamic_cast <TAO_RT_Stub *> (r.stub ());
00146
00147 if (!rt_stub)
00148 throw CORBA::INTERNAL ();
00149
00150
00151 CORBA::Policy_var priority_model_policy =
00152 rt_stub->get_cached_policy (TAO_CACHED_POLICY_PRIORITY_MODEL);
00153
00154
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
00167 if (priority_model_policy.ptr () == 0)
00168 {
00169
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
00180 throw ::CORBA::INV_POLICY ();
00181 }
00182
00183
00184
00185 all_endpoints_are_valid = true;
00186 }
00187
00188 else
00189 {
00190
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
00200
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
00208 all_endpoints_are_valid = true;
00209 }
00210
00211 else
00212 {
00213
00214 int status =
00215 protocol_hooks->get_thread_CORBA_priority (
00216 client_thread_priority);
00217 if (status == -1)
00218 {
00219 throw ::CORBA::DATA_CONVERSION (
00220 CORBA::OMGVMCID | 1,
00221 CORBA::COMPLETED_NO);
00222 }
00223
00224
00225 if (bands_policy.ptr () == 0)
00226 {
00227
00228
00229
00230 match_priority = true;
00231 }
00232
00233 else
00234 {
00235
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
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
00259 throw ::CORBA::INV_POLICY ();
00260 }
00261
00262
00263 match_bands = true;
00264 }
00265 }
00266 }
00267 }
00268
00269 TAO_Endpoint *ep = r.profile ()->endpoint ();
00270
00271 while (ep != 0)
00272 {
00273
00274 CORBA::Short endpoint_priority = ep->priority ();
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
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
00324 if (r.try_connect (&rt_transport_descriptor, val))
00325 return 1;
00326 }
00327
00328
00329 ep = ep->next();
00330 }
00331
00332 return 0;
00333 }
00334
00335 TAO_END_VERSIONED_NAMESPACE_DECL
00336
00337 #endif