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"
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
25 TAO_RT_Invocation_Endpoint_Selector::select_endpoint (
26 TAO::Profile_Transport_Resolver
*r
,
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)
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.
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 (
70 client_protocol_policy
.in (),
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
,
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 ();
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 ();
105 profile
= mprofile
.get_profile (i
);
107 if (profile
->tag () == client_protocols
[protocol_index
].protocol_type
)
109 valid_profile_found
= true;
113 if (this->endpoint_from_profile (r
, val
) == 1)
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 ();
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
,
147 // Narrow to the RT Stub.
148 TAO_RT_Stub
*rt_stub
= dynamic_cast <TAO_RT_Stub
*> (r
.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 ();
179 (*p
)[0u] = CORBA::Policy::_duplicate (bands_policy
.in ());
182 throw ::CORBA::INV_POLICY ();
185 // No priority model policy (and no bands policy): all endpoints
187 all_endpoints_are_valid
= true;
189 // If the priority model policy is set.
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
203 protocol_hooks
->get_selector_hook (priority_model_policy
.in (),
204 is_client_propagated
,
207 if (!is_client_propagated
)
209 // Server declared: all endpoints are fair game.
210 all_endpoints_are_valid
= true;
212 // Client propagated.
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)
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
236 match_priority
= true;
241 // Check which band range we fall in.
242 bool in_range
= false;
243 protocol_hooks
->get_selector_bands_policy_hook (
245 client_thread_priority
,
250 // If priority doesn't fall into any of the bands.
253 CORBA::PolicyList
*p
= r
.inconsistent_policies ();
257 (*p
)[0u] = CORBA::Policy::_duplicate (bands_policy
.in ());
259 CORBA::Policy::_duplicate (
260 priority_model_policy
.in ());
264 throw ::CORBA::INV_POLICY ();
267 // Match the priority of the band with the endpoint.
274 TAO_Endpoint
*ep
= r
.profile ()->endpoint ();
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)
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
||
293 client_thread_priority
== endpoint_priority
) ||
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
);
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
))
333 // Go to the next endpoint in this profile.
340 TAO_END_VERSIONED_NAMESPACE_DECL
342 #endif /* TAO_HAS_CORBA_MESSAGING && TAO_HAS_CORBA_MESSAGING != 0 */