=default for generated implementation copy ctor
[ACE_TAO.git] / TAO / tao / RTPortableServer / RT_Policy_Validator.cpp
blob40e48515c15801c8f54baddfe83b2bda3d8aec40
1 // -*- C++ -*-
2 #include "tao/RTPortableServer/RT_Policy_Validator.h"
4 #if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
6 #include "tao/PortableServer/POA_Cached_Policies.h"
7 #include "tao/PortableServer/PortableServer.h"
8 #include "tao/RTCORBA/RT_Policy_i.h"
9 #include "tao/RTCORBA/Thread_Pool.h"
10 #include "tao/RTCORBA/RT_ORB.h"
11 #include "tao/Thread_Lane_Resources_Manager.h"
12 #include "tao/Thread_Lane_Resources.h"
13 #include "tao/Acceptor_Registry.h"
14 #include "tao/ORB_Core.h"
15 #include "tao/Policy_Set.h"
16 #include "tao/Transport_Acceptor.h"
18 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
20 TAO_POA_RT_Policy_Validator::TAO_POA_RT_Policy_Validator (TAO_ORB_Core &orb_core)
21 : TAO_Policy_Validator (orb_core),
22 thread_pool_ (0)
26 void
27 TAO_POA_RT_Policy_Validator::validate_impl (TAO_Policy_Set &policies)
29 this->validate_thread_pool (policies);
31 this->validate_server_protocol (policies);
33 this->validate_priorities (policies);
36 CORBA::Boolean
37 TAO_POA_RT_Policy_Validator::legal_policy_impl (CORBA::PolicyType type)
39 return (type == RTCORBA::PRIORITY_MODEL_POLICY_TYPE ||
40 type == RTCORBA::THREADPOOL_POLICY_TYPE ||
41 type == RTCORBA::CLIENT_PROTOCOL_POLICY_TYPE ||
42 type == RTCORBA::SERVER_PROTOCOL_POLICY_TYPE ||
43 type == RTCORBA::PRIORITY_BANDED_CONNECTION_POLICY_TYPE);
46 void
47 TAO_POA_RT_Policy_Validator::validate_server_protocol (TAO_Policy_Set &policies)
49 // Make sure we have an endpoint for at least one of the protocols
50 // specified in the RTCORBA::ServerProtocolPolicy. This ensure we
51 // will be able to create non-nil object references.
52 CORBA::Policy_var protocol =
53 policies.get_cached_policy (TAO_CACHED_POLICY_RT_SERVER_PROTOCOL);
55 if (CORBA::is_nil (protocol.in ()))
57 // If the server protocol policy has not been specified, then
58 // add a server policy that reflects the protocols supported by
59 // the acceptor registries of the POA's thread pool.
60 protocol =
61 TAO_POA_RT_Policy_Validator::server_protocol_policy_from_thread_pool (this->thread_pool_,
62 this->orb_core_);
64 if (!CORBA::is_nil (protocol.in ()))
66 // If so, we'll use that policy.
67 policies.set_policy (protocol.in ());
71 RTCORBA::ServerProtocolPolicy_var server_protocol_policy =
72 RTCORBA::ServerProtocolPolicy::_narrow (protocol.in ());
74 TAO_ServerProtocolPolicy *server_protocol =
75 dynamic_cast <TAO_ServerProtocolPolicy *>
76 (server_protocol_policy.in ());
78 RTCORBA::ProtocolList &protocols =
79 server_protocol->protocols_rep ();
81 for (CORBA::ULong j = 0; j < protocols.length (); ++j)
83 bool found = false;
84 CORBA::ULong const protocol_type = protocols[j].protocol_type;
86 if (this->thread_pool_)
88 TAO_Thread_Lane **lanes =
89 this->thread_pool_->lanes ();
91 for (CORBA::ULong i = 0;
92 i != this->thread_pool_->number_of_lanes ();
93 ++i)
95 TAO_Thread_Lane_Resources &resources =
96 lanes[i]->resources ();
98 TAO_Acceptor_Registry &acceptor_registry =
99 resources.acceptor_registry ();
101 for (TAO_AcceptorSetIterator a = acceptor_registry.begin ();
102 a != acceptor_registry.end ();
103 ++a)
105 if ((*a)->tag () == protocol_type)
107 found = true;
108 break;
113 else
115 TAO_Thread_Lane_Resources_Manager &thread_lane_resources_manager =
116 this->orb_core_.thread_lane_resources_manager ();
118 TAO_Thread_Lane_Resources &resources =
119 thread_lane_resources_manager.default_lane_resources ();
121 TAO_Acceptor_Registry &acceptor_registry =
122 resources.acceptor_registry ();
124 for (TAO_AcceptorSetIterator a = acceptor_registry.begin ();
125 a != acceptor_registry.end ();
126 ++a)
128 if ((*a)->tag () == protocol_type)
130 found = true;
131 break;
136 if (!found)
137 throw PortableServer::POA::InvalidPolicy ();
141 void
142 TAO_POA_RT_Policy_Validator::validate_priorities (TAO_Policy_Set &policies)
144 // Initialize to the default priority/priority model.
145 CORBA::Short priority =
146 TAO_INVALID_PRIORITY;
147 TAO::Portable_Server::Cached_Policies::PriorityModel rt_priority_model =
148 TAO::Portable_Server::Cached_Policies::NOT_SPECIFIED;
150 CORBA::Policy_var policy =
151 policies.get_cached_policy (TAO_CACHED_POLICY_PRIORITY_MODEL);
153 RTCORBA::PriorityModelPolicy_var priority_model =
154 RTCORBA::PriorityModelPolicy::_narrow (policy.in ());
156 if (!CORBA::is_nil (priority_model.in ()))
158 priority = priority_model->server_priority ();
160 rt_priority_model =
161 TAO::Portable_Server::Cached_Policies::PriorityModel (
162 priority_model->priority_model ());
164 // Check that the priority is in bounds.
165 if (priority < RTCORBA::minPriority
166 // The line below will always be false unless the value of
167 // RTCORBA::maxPriority, which is now assigned the value of
168 // 32767, is changed in RTCORBA.pidl.
169 // || priority > RTCORBA::maxPriority
172 throw PortableServer::POA::InvalidPolicy ();
175 else
176 // If priority model was not specified, then we better not have a
177 // thread pool with lanes.
179 if (this->thread_pool_ != 0 &&
180 this->thread_pool_->with_lanes ())
181 throw PortableServer::POA::InvalidPolicy ();
184 policy =
185 policies.get_cached_policy (TAO_CACHED_POLICY_RT_PRIORITY_BANDED_CONNECTION);
187 RTCORBA::PriorityBandedConnectionPolicy_var priority_bands
188 = RTCORBA::PriorityBandedConnectionPolicy::_narrow (policy.in ());
190 TAO_PriorityBandedConnectionPolicy *bands_policy =
191 dynamic_cast<TAO_PriorityBandedConnectionPolicy *> (priority_bands.in ());
193 // If priority banded connections are set, make sure that:
194 // 0. A priority model was specified.
195 // 1. There is at least one band.
196 // 2a. low is not < RTCORBA::minPriority
197 // 2b. low <= high
198 // 2c. high is not > RTCORBA::maxPriority
199 // 3. If priority model is SERVER_DECLARED, server_priority must
200 // match one of the bands.
201 // 4. If this POA has a thread pool with lanes, then for each band,
202 // there must be at least one thread lane that can service it,
203 // i.e., whose priority falls into the band's range.
204 if (bands_policy != 0)
206 // Checks 0.
207 if (rt_priority_model == TAO::Portable_Server::Cached_Policies::NOT_SPECIFIED)
208 throw PortableServer::POA::InvalidPolicy ();
210 RTCORBA::PriorityBands &bands =
211 bands_policy->priority_bands_rep ();
213 // Checks 1.
214 if (bands.length () == 0)
215 throw PortableServer::POA::InvalidPolicy ();
217 // Checks 2.
218 for (CORBA::ULong i = 0; i < bands.length (); ++i)
220 // 2a. low is not < RTCORBA::minPriority
221 // 2b. low is not > high
222 // 2c. high is not > RTCORBA::maxPriority
223 if (bands[i].low < RTCORBA::minPriority
224 || bands[i].low > bands[i].high
225 // The line below will always be false unless the value of
226 // RTCORBA::maxPriority, which is now assigned the value of
227 // 32767, is changed in RTCORBA.pidl.
228 // || bands[i].high > RTCORBA::maxPriority
231 throw PortableServer::POA::InvalidPolicy ();
235 // Check 3.
236 if (rt_priority_model == TAO::Portable_Server::Cached_Policies::SERVER_DECLARED)
238 int match = 0;
239 for (CORBA::ULong i = 0; i < bands.length (); ++i)
241 if (priority <= bands[i].high &&
242 priority >= bands[i].low)
244 match = 1;
245 break;
249 if (!match)
250 throw PortableServer::POA::InvalidPolicy ();
254 // Check 4.
257 // If this POA is using the default thread pool (which doesn't
258 // have lanes) or a thread pool without lanes, we are done with
259 // the checks.
260 if (this->thread_pool_ == 0 ||
261 !this->thread_pool_->with_lanes ())
262 return;
264 // If this POA is using a thread pool with lanes, make sure we
265 // have at least one thread lane that corresponds to these
266 // each band.
267 TAO_Thread_Lane **lanes =
268 this->thread_pool_->lanes ();
270 for (CORBA::ULong band = 0;
271 band < bands.length ();
272 ++band)
274 int match = 0;
275 for (CORBA::ULong lane = 0;
276 lane != this->thread_pool_->number_of_lanes () && !match;
277 ++lane)
279 CORBA::Short lane_priority =
280 lanes[lane]->lane_priority ();
282 if (lane_priority <= bands[band].high &&
283 lane_priority >= bands[band].low)
284 match = 1;
286 if (!match)
287 throw PortableServer::POA::InvalidPolicy ();
290 // Done with checks.
291 return;
294 // If priority banded connections are not set, and the priority
295 // model is SERVER_DECLARED, make sure we have at least one thread
296 // lane that can provide service for the specified SERVER_DECLARED
297 // priority.
298 if (rt_priority_model == TAO::Portable_Server::Cached_Policies::SERVER_DECLARED)
300 // If this POA is using the default thread pool (which doesn't
301 // have lanes) or a thread pool without lanes, we are done with
302 // the checks.
303 if (this->thread_pool_ == 0 ||
304 !this->thread_pool_->with_lanes ())
305 return;
307 // If this POA is using a thread pool with lanes, make sure we
308 // have at least one thread lane that can provide service for
309 // the specified SERVER_DECLARED priority.
310 TAO_Thread_Lane **lanes =
311 this->thread_pool_->lanes ();
313 int match = 0;
314 for (CORBA::ULong lane = 0;
315 lane != this->thread_pool_->number_of_lanes () && !match;
316 ++lane)
318 CORBA::Short lane_priority =
319 lanes[lane]->lane_priority ();
321 if (lane_priority <= priority &&
322 lane_priority >= priority)
323 match = 1;
325 if (!match)
326 throw PortableServer::POA::InvalidPolicy ();
328 // Done with checks.
329 return;
334 void
335 TAO_POA_RT_Policy_Validator::validate_thread_pool (TAO_Policy_Set &policies)
337 this->thread_pool_ =
338 TAO_POA_RT_Policy_Validator::extract_thread_pool (this->orb_core_, policies);
341 void
342 TAO_POA_RT_Policy_Validator::merge_policies_impl (TAO_Policy_Set &policies)
344 // Check if the user has specified the priority model policy.
345 CORBA::Policy_var priority_model =
346 policies.get_cached_policy (TAO_CACHED_POLICY_PRIORITY_MODEL);
348 if (CORBA::is_nil (priority_model.in ()))
350 // If not, check if the priority model policy has been specified
351 // at the ORB level.
352 priority_model =
353 this->orb_core_.get_cached_policy (TAO_CACHED_POLICY_PRIORITY_MODEL);
355 if (!CORBA::is_nil (priority_model.in ()))
357 // If so, we'll use that policy.
358 policies.set_policy (priority_model.in ());
362 // Check if the user has specified the server protocol policy.
363 CORBA::Policy_var server_protocol =
364 policies.get_cached_policy (TAO_CACHED_POLICY_RT_SERVER_PROTOCOL);
366 if (CORBA::is_nil (server_protocol.in ()))
368 // If not, check if the server protocol policy has been
369 // specified at the ORB level.
370 server_protocol =
371 this->orb_core_.get_cached_policy (TAO_CACHED_POLICY_RT_SERVER_PROTOCOL);
373 if (!CORBA::is_nil (server_protocol.in ()))
375 // If so, we'll use that policy.
376 policies.set_policy (server_protocol.in ());
380 // Check if the user has specified the thread pool policy.
381 CORBA::Policy_var thread_pool =
382 policies.get_cached_policy (TAO_CACHED_POLICY_THREADPOOL);
384 if (CORBA::is_nil (thread_pool.in ()))
386 // If not, check if the thread pool policy has been specified at
387 // the ORB level.
388 thread_pool =
389 this->orb_core_.get_cached_policy (TAO_CACHED_POLICY_THREADPOOL);
391 if (!CORBA::is_nil (thread_pool.in ()))
393 // If so, we'll use that policy.
394 policies.set_policy (thread_pool.in ());
399 /* static */
400 RTCORBA::ServerProtocolPolicy_ptr
401 TAO_POA_RT_Policy_Validator::server_protocol_policy_from_thread_pool (TAO_Thread_Pool *thread_pool,
402 TAO_ORB_Core &orb_core)
404 RTCORBA::ProtocolList protocols;
406 if (thread_pool)
408 TAO_Thread_Lane **lanes =
409 thread_pool->lanes ();
411 for (CORBA::ULong i = 0;
412 i != thread_pool->number_of_lanes ();
413 ++i)
415 TAO_Thread_Lane_Resources &resources =
416 lanes[i]->resources ();
418 TAO_Acceptor_Registry &acceptor_registry =
419 resources.acceptor_registry ();
421 TAO_POA_RT_Policy_Validator::server_protocol_policy_from_acceptor_registry (protocols,
422 acceptor_registry,
423 orb_core);
426 else
428 TAO_Thread_Lane_Resources_Manager &thread_lane_resources_manager =
429 orb_core.thread_lane_resources_manager ();
431 TAO_Thread_Lane_Resources &resources =
432 thread_lane_resources_manager.default_lane_resources ();
434 TAO_Acceptor_Registry &acceptor_registry =
435 resources.acceptor_registry ();
437 TAO_POA_RT_Policy_Validator::server_protocol_policy_from_acceptor_registry (protocols,
438 acceptor_registry,
439 orb_core);
442 // Set ServerProtocolPolicy.
443 TAO_ServerProtocolPolicy *server_protocol_policy = 0;
444 ACE_NEW_RETURN (server_protocol_policy,
445 TAO_ServerProtocolPolicy (protocols),
448 return server_protocol_policy;
451 /* static */
452 void
453 TAO_POA_RT_Policy_Validator::server_protocol_policy_from_acceptor_registry (RTCORBA::ProtocolList &protocols,
454 TAO_Acceptor_Registry &acceptor_registry,
455 TAO_ORB_Core &orb_core)
457 TAO_AcceptorSetIterator end = acceptor_registry.end ();
459 for (TAO_AcceptorSetIterator acceptor = acceptor_registry.begin ();
460 acceptor != end;
461 ++acceptor)
463 if (*acceptor == 0)
464 continue;
466 CORBA::ULong current_length = protocols.length ();
468 // Make sure that this protocol is not already in the protocol
469 // list.
470 bool protocol_already_present = false;
471 for (CORBA::ULong i = 0;
472 i < current_length && !protocol_already_present;
473 ++i)
475 if (protocols[i].protocol_type == (*acceptor)->tag ())
476 protocol_already_present = true;
479 if (protocol_already_present)
480 continue;
482 protocols.length (current_length + 1);
484 protocols[current_length].protocol_type =
485 (*acceptor)->tag ();
487 protocols[current_length].orb_protocol_properties =
488 RTCORBA::ProtocolProperties::_nil ();
490 protocols[current_length].transport_protocol_properties =
491 TAO_Protocol_Properties_Factory::create_transport_protocol_property ((*acceptor)->tag (),
492 &orb_core);
496 /* static */
497 TAO_Thread_Pool *
498 TAO_POA_RT_Policy_Validator::extract_thread_pool (TAO_ORB_Core &orb_core,
499 TAO_Policy_Set &policies)
501 CORBA::Policy_var policy =
502 policies.get_cached_policy (TAO_CACHED_POLICY_THREADPOOL);
504 RTCORBA::ThreadpoolPolicy_var thread_pool_policy =
505 RTCORBA::ThreadpoolPolicy::_narrow (policy.in ());
507 if (CORBA::is_nil (thread_pool_policy.in ()))
508 return 0;
510 RTCORBA::ThreadpoolId thread_pool_id = thread_pool_policy->threadpool ();
512 // Get the RTORB.
513 CORBA::Object_var object = orb_core.resolve_rt_orb ();
515 RTCORBA::RTORB_var rt_orb = RTCORBA::RTORB::_narrow (object.in ());
517 TAO_RT_ORB * const tao_rt_orb =
518 dynamic_cast <TAO_RT_ORB *> (rt_orb.in ());
520 if (!tao_rt_orb)
521 throw CORBA::INTERNAL ();
523 TAO_Thread_Pool_Manager & tp_manager = tao_rt_orb->tp_manager ();
525 TAO_Thread_Pool * const thread_pool =
526 tp_manager.get_threadpool (thread_pool_id);
528 if (thread_pool == 0)
529 throw PortableServer::POA::InvalidPolicy ();
531 return thread_pool;
534 TAO_END_VERSIONED_NAMESPACE_DECL
536 #endif /* TAO_HAS_CORBA_MESSAGING && TAO_HAS_CORBA_MESSAGING != 0 */