Revert "Minor modernization of DynamicAny code"
[ACE_TAO.git] / TAO / tao / RTCORBA / RT_Invocation_Endpoint_Selectors.cpp
blob7ae293e34500b1005cef79d38e1217411f69b0ae
1 #include "tao/RTCORBA/RT_Invocation_Endpoint_Selectors.h"
3 #if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
5 #include "tao/RTCORBA/RT_Policy_i.h"
6 #include "tao/RTCORBA/RT_Stub.h"
7 #include "tao/RTCORBA/RT_Transport_Descriptor.h"
8 #include "tao/RTCORBA/RT_Transport_Descriptor_Property.h"
9 #include "tao/RTCORBA/RT_Endpoint_Utils.h"
10 #include "tao/RTCORBA/RT_Protocols_Hooks.h"
11 #include "tao/Stub.h"
12 #include "tao/ORB_Core.h"
13 #include "tao/Profile.h"
14 #include "tao/Endpoint.h"
15 #include "tao/debug.h"
16 #include "tao/Profile.h"
17 #include "tao/Endpoint.h"
18 #include "tao/Profile_Transport_Resolver.h"
19 #include "tao/ORB_Core.h"
20 #include "tao/SystemException.h"
22 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
24 void
25 TAO_RT_Invocation_Endpoint_Selector::select_endpoint (
26 TAO::Profile_Transport_Resolver *r,
27 ACE_Time_Value *val)
29 if (r == 0)
30 throw ::CORBA::INTERNAL ();
32 CORBA::Policy_var client_protocol_policy_base =
33 TAO_RT_Endpoint_Utils::policy (TAO_CACHED_POLICY_RT_CLIENT_PROTOCOL, *r);
35 if (CORBA::is_nil(client_protocol_policy_base.in ()))
39 r->profile (r->stub ()->profile_in_use ());
41 if (this->endpoint_from_profile (*r, val) == 1)
42 return;
44 while (r->stub ()->next_profile_retry () != 0);
46 // If we get here, we completely failed to find an endpoint
47 // that we know how to use. We used to throw an exception
48 // but that would prevent any request interception points
49 // being called. They may know how to fix the problem so
50 // we wait to throw the exception in
51 // Synch_Twoway_Invocation::remote_twoway and
52 // Synch_Oneway_Invocation::remote_oneway instead.
54 else
56 RTCORBA::ClientProtocolPolicy_var client_protocol_policy =
57 RTCORBA::ClientProtocolPolicy::_narrow (
58 client_protocol_policy_base.in ());
60 /// Cast to TAO_ClientProtocolPolicy
61 TAO_ClientProtocolPolicy *tao_client_protocol_policy =
62 static_cast<TAO_ClientProtocolPolicy *> (client_protocol_policy.in ());
64 /// Get the ProtocolList
65 RTCORBA::ProtocolList &client_protocols =
66 tao_client_protocol_policy->protocols_rep ();
68 this->select_endpoint_based_on_client_protocol_policy (
69 *r,
70 client_protocol_policy.in (),
71 client_protocols,
72 val);
76 void
77 TAO_RT_Invocation_Endpoint_Selector::select_endpoint_based_on_client_protocol_policy (
78 TAO::Profile_Transport_Resolver &r,
79 RTCORBA::ClientProtocolPolicy_ptr client_protocol_policy,
80 RTCORBA::ProtocolList &client_protocols,
81 ACE_Time_Value *val)
83 CORBA::Boolean valid_profile_found = false;
85 // Even though cycling through all the protocols is the correct
86 // things to do to find a match, starting from the start of the
87 // profile list is not. In addition, this code is also ignoring the
88 // forwarded reference (if it exists). This behavior is caused by
89 // problems with the profile management in TAO which are documented
90 // in bugzilla bugs 1237, 1238, and 1239. Once the above problems
91 // are fixed, this behavior should be fixed to do the right thing.
92 for (CORBA::ULong protocol_index = 0;
93 protocol_index < client_protocols.length ();
94 ++protocol_index)
96 // Find the profiles that match the current protocol.
97 TAO_Profile *profile = 0;
98 TAO_MProfile &mprofile = (r.stub ()->forward_profiles() == 0) ?
99 r.stub ()->base_profiles () : *r.stub ()->forward_profiles();
101 for (TAO_PHandle i = 0;
102 i < mprofile.profile_count ();
103 ++i)
105 profile = mprofile.get_profile (i);
107 if (profile->tag () == client_protocols[protocol_index].protocol_type)
109 valid_profile_found = true;
111 r.profile (profile);
113 if (this->endpoint_from_profile (r, val) == 1)
114 return;
115 // @@ Else we should check for potential forwarding here.
120 // We have tried all the profiles specified in the client protocol
121 // policy with no success. Throw exception.
122 if (!valid_profile_found)
124 CORBA::PolicyList *p = r.inconsistent_policies ();
125 if (p)
127 p->length (1);
128 (*p)[0u] = CORBA::Policy::_duplicate (client_protocol_policy);
130 throw ::CORBA::INV_POLICY ();
133 // If we get here, we completely failed to find an endpoint
134 // that we know how to use. We used to throw an exception
135 // but that would prevent any request interception points
136 // being called. They may know how to fix the problem so
137 // we wait to throw the exception in
138 // Synch_Twoway_Invocation::remote_twoway and
139 // Synch_Oneway_Invocation::remote_oneway instead.
143 TAO_RT_Invocation_Endpoint_Selector::endpoint_from_profile (
144 TAO::Profile_Transport_Resolver &r,
145 ACE_Time_Value *val)
147 // Narrow to the RT Stub.
148 TAO_RT_Stub *rt_stub = dynamic_cast <TAO_RT_Stub *> (r.stub ());
150 if (!rt_stub)
151 throw CORBA::INTERNAL ();
153 // Get the priority model policy.
154 CORBA::Policy_var priority_model_policy =
155 rt_stub->get_cached_policy (TAO_CACHED_POLICY_PRIORITY_MODEL);
157 // Get the bands policy.
158 CORBA::Policy_var bands_policy =
159 TAO_RT_Endpoint_Utils::policy (
160 TAO_CACHED_POLICY_RT_PRIORITY_BANDED_CONNECTION, r);
162 bool all_endpoints_are_valid = false;
163 bool match_priority = false;
164 bool match_bands = false;
165 CORBA::Short client_thread_priority = 0;
166 CORBA::Short min_priority = 0;
167 CORBA::Short max_priority = 0;
169 // If the priority model policy is not set.
170 if (CORBA::is_nil (priority_model_policy.in ()))
172 // Bands without priority model do not make sense.
173 if (!CORBA::is_nil (bands_policy.in ()))
175 CORBA::PolicyList *p = r.inconsistent_policies ();
176 if (p)
178 p->length (1);
179 (*p)[0u] = CORBA::Policy::_duplicate (bands_policy.in ());
181 // Indicate error.
182 throw ::CORBA::INV_POLICY ();
185 // No priority model policy (and no bands policy): all endpoints
186 // are fair game.
187 all_endpoints_are_valid = true;
189 // If the priority model policy is set.
190 else
192 // Get the protocol hooks.
193 TAO_Protocols_Hooks *protocol_hooks =
194 r.stub ()->orb_core ()->get_protocols_hooks ();
196 if (protocol_hooks != 0)
198 CORBA::Short server_priority = 0;
199 CORBA::Boolean is_client_propagated = false;
201 // Check the priority model policy to see if it is client
202 // propagated.
203 protocol_hooks->get_selector_hook (priority_model_policy.in (),
204 is_client_propagated,
205 server_priority);
207 if (!is_client_propagated)
209 // Server declared: all endpoints are fair game.
210 all_endpoints_are_valid = true;
212 // Client propagated.
213 else
215 // Get client thread priority from 'Current' or if not set by implying one
216 // from the native thread priority via the mapping.
217 if (protocol_hooks->get_thread_CORBA_priority (client_thread_priority) != -1 ||
218 protocol_hooks->get_thread_implicit_CORBA_priority (client_thread_priority) != -1)
220 // OK
222 else
224 if (TAO_debug_level > 0)
225 TAOLIB_DEBUG ((LM_DEBUG, "ERROR: TAO_RT_Invocation_Endpoint_Selector::endpoint_from_profile. "
226 "Unable to access RT CORBA Priority in client thread "
227 "accessing object with CLIENT_PROPAGATED priority model.\n"));
228 throw CORBA::DATA_CONVERSION (CORBA::OMGVMCID | 2, CORBA::COMPLETED_NO);
231 // If there are no bands.
232 if (bands_policy.ptr () == 0)
234 // Match the priority of the client thread with the
235 // endpoint.
236 match_priority = true;
238 // There are bands.
239 else
241 // Check which band range we fall in.
242 bool in_range = false;
243 protocol_hooks->get_selector_bands_policy_hook (
244 bands_policy.in (),
245 client_thread_priority,
246 min_priority,
247 max_priority,
248 in_range);
250 // If priority doesn't fall into any of the bands.
251 if (!in_range)
253 CORBA::PolicyList *p = r.inconsistent_policies ();
254 if (p)
256 p->length (2);
257 (*p)[0u] = CORBA::Policy::_duplicate (bands_policy.in ());
258 (*p)[1u] =
259 CORBA::Policy::_duplicate (
260 priority_model_policy.in ());
263 // Indicate error.
264 throw ::CORBA::INV_POLICY ();
267 // Match the priority of the band with the endpoint.
268 match_bands = true;
274 TAO_Endpoint *ep = r.profile ()->endpoint ();
276 while (ep != 0)
278 // Get the priority of the endpoint.
279 CORBA::Short endpoint_priority = ep->priority ();
281 // If <all_endpoints_are_valid> or match the priority of the
282 // client thread or match the priority of the band or
283 // profile contains just one endpoint. This happens when:
284 // a) we are talking to a nonTAO server (which doesn't have
285 // the concept of multiple endpoints per profile)
286 // or
287 // b) we have TAO server with a non-lane threadpool, in which
288 // case there is only one acceptor
289 // In both cases we should use the endpoint regardless of its priority.
291 if (all_endpoints_are_valid ||
292 (match_priority &&
293 client_thread_priority == endpoint_priority) ||
294 (match_bands &&
295 endpoint_priority <= max_priority &&
296 endpoint_priority >= min_priority) ||
297 (r.profile ()->endpoint_count () == 1 &&
298 endpoint_priority == TAO_INVALID_PRIORITY))
300 TAO_RT_Transport_Descriptor_Private_Connection_Property
301 private_connection_descriptor_property;
303 TAO_RT_Transport_Descriptor_Banded_Connection_Property
304 banded_connection_descriptor_property;
306 TAO_RT_Transport_Descriptor rt_transport_descriptor (ep);
308 CORBA::Policy_var private_connection_policy =
309 rt_stub->get_cached_policy (TAO_CACHED_POLICY_RT_PRIVATE_CONNECTION);
311 if (!CORBA::is_nil (private_connection_policy.in ()))
313 private_connection_descriptor_property.init
314 (static_cast<long> (reinterpret_cast<ptrdiff_t> (r.stub ())));
315 rt_transport_descriptor.insert
316 (&private_connection_descriptor_property);
319 if (match_bands)
321 banded_connection_descriptor_property.init
322 (min_priority, max_priority);
324 rt_transport_descriptor.insert
325 (&banded_connection_descriptor_property);
328 // Check if the invocation has completed.
329 if (r.try_connect (&rt_transport_descriptor, val))
330 return 1;
333 // Go to the next endpoint in this profile.
334 ep = ep->next();
337 return 0;
340 TAO_END_VERSIONED_NAMESPACE_DECL
342 #endif /* TAO_HAS_CORBA_MESSAGING && TAO_HAS_CORBA_MESSAGING != 0 */