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
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
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
00087
00088
00089
00090
00091
00092
00093 for (CORBA::ULong protocol_index = 0;
00094 protocol_index < client_protocols.length ();
00095 ++protocol_index)
00096 {
00097
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
00118 }
00119 }
00120 }
00121
00122
00123
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
00137
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
00148 TAO_RT_Stub *rt_stub = dynamic_cast <TAO_RT_Stub *> (r.stub ());
00149
00150 if (!rt_stub)
00151 throw CORBA::INTERNAL ();
00152
00153
00154 CORBA::Policy_var priority_model_policy =
00155 rt_stub->get_cached_policy (TAO_CACHED_POLICY_PRIORITY_MODEL);
00156
00157
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
00170 if (priority_model_policy.ptr () == 0)
00171 {
00172
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
00183 throw ::CORBA::INV_POLICY ();
00184 }
00185
00186
00187
00188 all_endpoints_are_valid = 1;
00189 }
00190
00191 else
00192 {
00193
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
00203
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
00211 all_endpoints_are_valid = 1;
00212 }
00213
00214 else
00215 {
00216
00217 int status =
00218 protocol_hooks->get_thread_CORBA_priority (
00219 client_thread_priority
00220 );
00221 if (status == -1)
00222 {
00223 throw ::CORBA::DATA_CONVERSION (
00224 CORBA::OMGVMCID | 1,
00225 CORBA::COMPLETED_NO);
00226 }
00227
00228
00229 if (bands_policy.ptr () == 0)
00230 {
00231
00232
00233
00234 match_priority = 1;
00235 }
00236
00237 else
00238 {
00239
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
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
00263 throw ::CORBA::INV_POLICY ();
00264 }
00265
00266
00267 match_bands = 1;
00268 }
00269 }
00270 }
00271 }
00272
00273 TAO_Endpoint *ep =
00274 r.profile ()->endpoint ();
00275
00276 while (ep != 0)
00277 {
00278
00279 CORBA::Short endpoint_priority = ep->priority ();
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
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
00336 if (status == true)
00337 return 1;
00338 }
00339
00340
00341 ep = ep->next();
00342 }
00343
00344 return 0;
00345 }
00346
00347 TAO_END_VERSIONED_NAMESPACE_DECL
00348
00349 #endif