RT_Policy_Validator.cpp

Go to the documentation of this file.
00001 #include "tao/RTPortableServer/RT_Policy_Validator.h"
00002 
00003 #if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0
00004 
00005 #include "tao/PortableServer/POA_Cached_Policies.h"
00006 #include "tao/PortableServer/PortableServer.h"
00007 #include "tao/RTCORBA/RT_Policy_i.h"
00008 #include "tao/RTCORBA/Thread_Pool.h"
00009 #include "tao/RTCORBA/RT_ORB.h"
00010 #include "tao/Thread_Lane_Resources_Manager.h"
00011 #include "tao/Thread_Lane_Resources.h"
00012 #include "tao/Acceptor_Registry.h"
00013 #include "tao/ORB_Core.h"
00014 #include "tao/Policy_Set.h"
00015 #include "tao/Transport_Acceptor.h"
00016 
00017 ACE_RCSID (RTPortableServer,
00018            RT_Policy_Validator,
00019            "RT_Policy_Validator.cpp,v 1.20 2006/03/10 07:19:16 jtc Exp")
00020 
00021 
00022 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00023 
00024 TAO_POA_RT_Policy_Validator::TAO_POA_RT_Policy_Validator (TAO_ORB_Core &orb_core)
00025   : TAO_Policy_Validator (orb_core),
00026     thread_pool_ (0)
00027 {
00028   // No-Op.
00029 }
00030 
00031 TAO_POA_RT_Policy_Validator::~TAO_POA_RT_Policy_Validator (void)
00032 {
00033   // No-Op.
00034 }
00035 
00036 void
00037 TAO_POA_RT_Policy_Validator::validate_impl (TAO_Policy_Set &policies
00038                                             ACE_ENV_ARG_DECL)
00039 {
00040   this->validate_thread_pool (policies ACE_ENV_ARG_PARAMETER);
00041   ACE_CHECK;
00042 
00043   this->validate_server_protocol (policies ACE_ENV_ARG_PARAMETER);
00044   ACE_CHECK;
00045 
00046   this->validate_priorities (policies ACE_ENV_ARG_PARAMETER);
00047   ACE_CHECK;
00048 }
00049 
00050 CORBA::Boolean
00051 TAO_POA_RT_Policy_Validator::legal_policy_impl (CORBA::PolicyType type)
00052 {
00053   return (type == RTCORBA::PRIORITY_MODEL_POLICY_TYPE ||
00054           type == RTCORBA::THREADPOOL_POLICY_TYPE ||
00055           type == RTCORBA::CLIENT_PROTOCOL_POLICY_TYPE ||
00056           type == RTCORBA::SERVER_PROTOCOL_POLICY_TYPE ||
00057           type == RTCORBA::PRIORITY_BANDED_CONNECTION_POLICY_TYPE);
00058 }
00059 
00060 void
00061 TAO_POA_RT_Policy_Validator::validate_server_protocol (TAO_Policy_Set &policies
00062                                                        ACE_ENV_ARG_DECL)
00063 {
00064   // Make sure we have an endpoint for at least one of the protocols
00065   // specified in the RTCORBA::ServerProtocolPolicy.  This ensure we
00066   // will be able to create non-nil object references.
00067   CORBA::Policy_var protocol =
00068     policies.get_cached_policy (TAO_CACHED_POLICY_RT_SERVER_PROTOCOL
00069                                 ACE_ENV_ARG_PARAMETER);
00070   ACE_CHECK;
00071 
00072   if (CORBA::is_nil (protocol.in ()))
00073     {
00074       // If the server protocol policy has not been specified, then
00075       // add a server policy that reflects the protocols supported by
00076       // the acceptor registries of the POA's thread pool.
00077       protocol =
00078         TAO_POA_RT_Policy_Validator::server_protocol_policy_from_thread_pool (this->thread_pool_,
00079                                                                               this->orb_core_);
00080 
00081       if (!CORBA::is_nil (protocol.in ()))
00082         {
00083           // If so, we'll use that policy.
00084           policies.set_policy (protocol.in () ACE_ENV_ARG_PARAMETER);
00085           ACE_CHECK;
00086         }
00087     }
00088 
00089   RTCORBA::ServerProtocolPolicy_var server_protocol_policy =
00090     RTCORBA::ServerProtocolPolicy::_narrow (protocol.in ()
00091                                             ACE_ENV_ARG_PARAMETER);
00092   ACE_CHECK;
00093 
00094   TAO_ServerProtocolPolicy *server_protocol =
00095     dynamic_cast <TAO_ServerProtocolPolicy *>
00096                       (server_protocol_policy.in ());
00097 
00098   RTCORBA::ProtocolList &protocols =
00099     server_protocol->protocols_rep ();
00100 
00101   for (CORBA::ULong j = 0; j < protocols.length (); ++j)
00102     {
00103       int found = 0;
00104       CORBA::ULong protocol_type = protocols[j].protocol_type;
00105 
00106       if (this->thread_pool_)
00107         {
00108           TAO_Thread_Lane **lanes =
00109             this->thread_pool_->lanes ();
00110 
00111           for (CORBA::ULong i = 0;
00112                i != this->thread_pool_->number_of_lanes ();
00113                ++i)
00114             {
00115               TAO_Thread_Lane_Resources &resources =
00116                 lanes[i]->resources ();
00117 
00118               TAO_Acceptor_Registry &acceptor_registry =
00119                 resources.acceptor_registry ();
00120 
00121               for (TAO_AcceptorSetIterator a = acceptor_registry.begin ();
00122                    a != acceptor_registry.end ();
00123                    ++a)
00124                 {
00125                   if ((*a)->tag () == protocol_type)
00126                     {
00127                       found = 1;
00128                       break;
00129                     }
00130                 }
00131             }
00132         }
00133       else
00134         {
00135           TAO_Thread_Lane_Resources_Manager &thread_lane_resources_manager =
00136             this->orb_core_.thread_lane_resources_manager ();
00137 
00138           TAO_Thread_Lane_Resources &resources =
00139             thread_lane_resources_manager.default_lane_resources ();
00140 
00141           TAO_Acceptor_Registry &acceptor_registry =
00142             resources.acceptor_registry ();
00143 
00144           for (TAO_AcceptorSetIterator a = acceptor_registry.begin ();
00145                a != acceptor_registry.end ();
00146                ++a)
00147             {
00148               if ((*a)->tag () == protocol_type)
00149                 {
00150                   found = 1;
00151                   break;
00152                 }
00153             }
00154         }
00155 
00156       if (!found)
00157         ACE_THROW (PortableServer::POA::InvalidPolicy ());
00158     }
00159 }
00160 
00161 void
00162 TAO_POA_RT_Policy_Validator::validate_priorities (TAO_Policy_Set &policies
00163                                                   ACE_ENV_ARG_DECL)
00164 {
00165   // Initialize to the default priority/priority model.
00166   CORBA::Short priority =
00167     TAO_INVALID_PRIORITY;
00168   TAO::Portable_Server::Cached_Policies::PriorityModel rt_priority_model =
00169     TAO::Portable_Server::Cached_Policies::NOT_SPECIFIED;
00170 
00171   CORBA::Policy_var policy =
00172     policies.get_cached_policy (TAO_CACHED_POLICY_PRIORITY_MODEL
00173                                 ACE_ENV_ARG_PARAMETER);
00174   ACE_CHECK;
00175 
00176   RTCORBA::PriorityModelPolicy_var priority_model =
00177     RTCORBA::PriorityModelPolicy::_narrow (policy.in ()
00178                                            ACE_ENV_ARG_PARAMETER);
00179   ACE_CHECK;
00180 
00181   if (!CORBA::is_nil (priority_model.in ()))
00182     {
00183       priority = priority_model->server_priority (ACE_ENV_SINGLE_ARG_PARAMETER);
00184       ACE_CHECK;
00185 
00186       rt_priority_model =
00187         TAO::Portable_Server::Cached_Policies::PriorityModel (
00188           priority_model->priority_model (ACE_ENV_SINGLE_ARG_PARAMETER));
00189       ACE_CHECK;
00190 
00191       // Check that the priority is in bounds.
00192       if (priority < RTCORBA::minPriority
00193                // The line below will always be false unless the value of
00194                // RTCORBA::maxPriority, which is now assigned the value of
00195                // 32767, is changed in RTCORBA.pidl.
00196 //          || priority > RTCORBA::maxPriority
00197          )
00198         {
00199           ACE_THROW (PortableServer::POA::InvalidPolicy ());
00200         }
00201     }
00202   else
00203     // If priority model was not specified, then we better not have a
00204     // thread pool with lanes.
00205     {
00206       if (this->thread_pool_ != 0 &&
00207           this->thread_pool_->with_lanes ())
00208         ACE_THROW (PortableServer::POA::InvalidPolicy ());
00209     }
00210 
00211   policy =
00212     policies.get_cached_policy (TAO_CACHED_POLICY_RT_PRIORITY_BANDED_CONNECTION
00213                                 ACE_ENV_ARG_PARAMETER);
00214   ACE_CHECK;
00215 
00216   RTCORBA::PriorityBandedConnectionPolicy_var priority_bands
00217     = RTCORBA::PriorityBandedConnectionPolicy::_narrow (policy.in ()
00218                                                         ACE_ENV_ARG_PARAMETER);
00219   ACE_CHECK;
00220 
00221   TAO_PriorityBandedConnectionPolicy *bands_policy =
00222     dynamic_cast<TAO_PriorityBandedConnectionPolicy *> (priority_bands.in ());
00223 
00224   // If priority banded connections are set, make sure that:
00225   //  0. A priority model was specified.
00226   //  1. There is at least one band.
00227   //  2a. low is not < RTCORBA::minPriority
00228   //  2b. low <= high
00229   //  2c. high is not > RTCORBA::maxPriority
00230   //  3. If priority model is SERVER_DECLARED, server_priority must
00231   //  match one of the bands.
00232   //  4. If this POA has a thread pool with lanes, then for each band,
00233   //  there must be at least one thread lane that can service it,
00234   //  i.e., whose priority falls into the band's range.
00235   if (bands_policy != 0)
00236     {
00237       // Checks 0.
00238       if (rt_priority_model == TAO::Portable_Server::Cached_Policies::NOT_SPECIFIED)
00239         ACE_THROW (PortableServer::POA::InvalidPolicy ());
00240 
00241       RTCORBA::PriorityBands &bands =
00242         bands_policy->priority_bands_rep ();
00243 
00244       // Checks 1.
00245       if (bands.length () == 0)
00246         ACE_THROW (PortableServer::POA::InvalidPolicy ());
00247 
00248       // Checks 2.
00249       for (CORBA::ULong i = 0; i < bands.length (); ++i)
00250         {
00251           //  2a. low is not < RTCORBA::minPriority
00252           //  2b. low is not > high
00253           //  2c. high is not > RTCORBA::maxPriority
00254           if (bands[i].low < RTCORBA::minPriority
00255               || bands[i].low > bands[i].high
00256                    // The line below will always be false unless the value of
00257                    // RTCORBA::maxPriority, which is now assigned the value of
00258                    // 32767, is changed in RTCORBA.pidl.
00259 //              || bands[i].high > RTCORBA::maxPriority
00260              )
00261             {
00262               ACE_THROW (PortableServer::POA::InvalidPolicy ());
00263             }
00264         }
00265 
00266       // Check 3.
00267       if (rt_priority_model == TAO::Portable_Server::Cached_Policies::SERVER_DECLARED)
00268         {
00269           int match = 0;
00270           for (CORBA::ULong i = 0; i < bands.length (); ++i)
00271             {
00272               if (priority <= bands[i].high &&
00273                   priority >= bands[i].low)
00274                 {
00275                   match = 1;
00276                   break;
00277                 }
00278             }
00279 
00280           if (!match)
00281             ACE_THROW (PortableServer::POA::InvalidPolicy ());
00282         }
00283 
00284       //
00285       // Check 4.
00286       //
00287 
00288       // If this POA is using the default thread pool (which doesn't
00289       // have lanes) or a thread pool without lanes, we are done with
00290       // the checks.
00291       if (this->thread_pool_ == 0 ||
00292           !this->thread_pool_->with_lanes ())
00293         return;
00294 
00295       // If this POA is using a thread pool with lanes, make sure we
00296       // have at least one thread lane that corresponds to these
00297       // each band.
00298       TAO_Thread_Lane **lanes =
00299         this->thread_pool_->lanes ();
00300 
00301       for (CORBA::ULong band = 0;
00302            band < bands.length ();
00303            ++band)
00304         {
00305           int match = 0;
00306           for (CORBA::ULong lane = 0;
00307                lane != this->thread_pool_->number_of_lanes () && !match;
00308                ++lane)
00309             {
00310               CORBA::Short lane_priority =
00311                 lanes[lane]->lane_priority ();
00312 
00313               if (lane_priority <= bands[band].high &&
00314                   lane_priority >= bands[band].low)
00315                 match = 1;
00316             }
00317           if (!match)
00318             ACE_THROW (PortableServer::POA::InvalidPolicy ());
00319         }
00320 
00321       // Done with checks.
00322       return;
00323     }
00324 
00325   // If priority banded connections are not set, and the priority
00326   // model is SERVER_DECLARED, make sure we have at least one thread
00327   // lane that can provide service for the specified SERVER_DECLARED
00328   // priority.
00329   if (rt_priority_model == TAO::Portable_Server::Cached_Policies::SERVER_DECLARED)
00330     {
00331       // If this POA is using the default thread pool (which doesn't
00332       // have lanes) or a thread pool without lanes, we are done with
00333       // the checks.
00334       if (this->thread_pool_ == 0 ||
00335           !this->thread_pool_->with_lanes ())
00336         return;
00337 
00338       // If this POA is using a thread pool with lanes, make sure we
00339       // have at least one thread lane that can provide service for
00340       // the specified SERVER_DECLARED priority.
00341       TAO_Thread_Lane **lanes =
00342         this->thread_pool_->lanes ();
00343 
00344       int match = 0;
00345       for (CORBA::ULong lane = 0;
00346            lane != this->thread_pool_->number_of_lanes () && !match;
00347            ++lane)
00348         {
00349           CORBA::Short lane_priority =
00350             lanes[lane]->lane_priority ();
00351 
00352           if (lane_priority <= priority &&
00353               lane_priority >= priority)
00354             match = 1;
00355         }
00356       if (!match)
00357         ACE_THROW (PortableServer::POA::InvalidPolicy ());
00358 
00359       // Done with checks.
00360       return;
00361     }
00362 
00363 }
00364 
00365 void
00366 TAO_POA_RT_Policy_Validator::validate_thread_pool (TAO_Policy_Set &policies
00367                                                    ACE_ENV_ARG_DECL)
00368 {
00369   this->thread_pool_ =
00370     TAO_POA_RT_Policy_Validator::extract_thread_pool (this->orb_core_,
00371                                                       policies
00372                                                       ACE_ENV_ARG_PARAMETER);
00373   ACE_CHECK;
00374 }
00375 
00376 void
00377 TAO_POA_RT_Policy_Validator::merge_policies_impl (TAO_Policy_Set &policies
00378                                                   ACE_ENV_ARG_DECL)
00379 {
00380   // Check if the user has specified the priority model policy.
00381   CORBA::Policy_var priority_model =
00382     policies.get_cached_policy (TAO_CACHED_POLICY_PRIORITY_MODEL
00383                                 ACE_ENV_ARG_PARAMETER);
00384   ACE_CHECK;
00385 
00386   if (CORBA::is_nil (priority_model.in ()))
00387     {
00388       // If not, check if the priority model policy has been specified
00389       // at the ORB level.
00390       priority_model =
00391         this->orb_core_.get_cached_policy (TAO_CACHED_POLICY_PRIORITY_MODEL
00392                                            ACE_ENV_ARG_PARAMETER);
00393       ACE_CHECK;
00394 
00395       if (!CORBA::is_nil (priority_model.in ()))
00396         {
00397           // If so, we'll use that policy.
00398           policies.set_policy (priority_model.in () ACE_ENV_ARG_PARAMETER);
00399           ACE_CHECK;
00400         }
00401     }
00402 
00403   // Check if the user has specified the server protocol policy.
00404   CORBA::Policy_var server_protocol =
00405     policies.get_cached_policy (TAO_CACHED_POLICY_RT_SERVER_PROTOCOL
00406                                 ACE_ENV_ARG_PARAMETER);
00407   ACE_CHECK;
00408 
00409   if (CORBA::is_nil (server_protocol.in ()))
00410     {
00411       // If not, check if the server protocol policy has been
00412       // specified at the ORB level.
00413       server_protocol =
00414         this->orb_core_.get_cached_policy (
00415           TAO_CACHED_POLICY_RT_SERVER_PROTOCOL
00416           ACE_ENV_ARG_PARAMETER);
00417       ACE_CHECK;
00418 
00419       if (!CORBA::is_nil (server_protocol.in ()))
00420         {
00421           // If so, we'll use that policy.
00422           policies.set_policy (server_protocol.in () ACE_ENV_ARG_PARAMETER);
00423           ACE_CHECK;
00424         }
00425     }
00426 
00427   // Check if the user has specified the thread pool policy.
00428   CORBA::Policy_var thread_pool =
00429     policies.get_cached_policy (TAO_CACHED_POLICY_THREADPOOL
00430                                 ACE_ENV_ARG_PARAMETER);
00431   ACE_CHECK;
00432 
00433   if (CORBA::is_nil (thread_pool.in ()))
00434     {
00435       // If not, check if the thread pool policy has been specified at
00436       // the ORB level.
00437       thread_pool =
00438         this->orb_core_.get_cached_policy (TAO_CACHED_POLICY_THREADPOOL
00439                                            ACE_ENV_ARG_PARAMETER);
00440       ACE_CHECK;
00441 
00442       if (!CORBA::is_nil (thread_pool.in ()))
00443         {
00444           // If so, we'll use that policy.
00445           policies.set_policy (thread_pool.in () ACE_ENV_ARG_PARAMETER);
00446           ACE_CHECK;
00447         }
00448     }
00449 }
00450 
00451 /* static */
00452 RTCORBA::ServerProtocolPolicy_ptr
00453 TAO_POA_RT_Policy_Validator::server_protocol_policy_from_thread_pool (TAO_Thread_Pool *thread_pool,
00454                                                                       TAO_ORB_Core &orb_core)
00455 {
00456   RTCORBA::ProtocolList protocols;
00457 
00458   if (thread_pool)
00459     {
00460       TAO_Thread_Lane **lanes =
00461         thread_pool->lanes ();
00462 
00463       for (CORBA::ULong i = 0;
00464            i != thread_pool->number_of_lanes ();
00465            ++i)
00466         {
00467           TAO_Thread_Lane_Resources &resources =
00468             lanes[i]->resources ();
00469 
00470           TAO_Acceptor_Registry &acceptor_registry =
00471             resources.acceptor_registry ();
00472 
00473           TAO_POA_RT_Policy_Validator::server_protocol_policy_from_acceptor_registry (protocols,
00474                                                                                       acceptor_registry,
00475                                                                                       orb_core);
00476         }
00477     }
00478   else
00479     {
00480       TAO_Thread_Lane_Resources_Manager &thread_lane_resources_manager =
00481         orb_core.thread_lane_resources_manager ();
00482 
00483       TAO_Thread_Lane_Resources &resources =
00484         thread_lane_resources_manager.default_lane_resources ();
00485 
00486       TAO_Acceptor_Registry &acceptor_registry =
00487         resources.acceptor_registry ();
00488 
00489       TAO_POA_RT_Policy_Validator::server_protocol_policy_from_acceptor_registry (protocols,
00490                                                                                   acceptor_registry,
00491                                                                                   orb_core);
00492     }
00493 
00494   // Set ServerProtocolPolicy.
00495   TAO_ServerProtocolPolicy *server_protocol_policy = 0;
00496   ACE_NEW_RETURN (server_protocol_policy,
00497                   TAO_ServerProtocolPolicy (protocols),
00498                   0);
00499 
00500   return server_protocol_policy;
00501 }
00502 
00503 /* static */
00504 void
00505 TAO_POA_RT_Policy_Validator::server_protocol_policy_from_acceptor_registry (RTCORBA::ProtocolList &protocols,
00506                                                                             TAO_Acceptor_Registry &acceptor_registry,
00507                                                                             TAO_ORB_Core &orb_core)
00508 {
00509   TAO_AcceptorSetIterator end =
00510     acceptor_registry.end ();
00511 
00512   for (TAO_AcceptorSetIterator acceptor =
00513          acceptor_registry.begin ();
00514        acceptor != end;
00515        ++acceptor)
00516     {
00517       if (*acceptor == 0)
00518         continue;
00519 
00520       CORBA::ULong current_length =
00521         protocols.length ();
00522 
00523       // Make sure that this protocol is not already in the protocol
00524       // list.
00525       bool protocol_already_present = false;
00526       for (CORBA::ULong i = 0;
00527            i < current_length && !protocol_already_present;
00528            ++i)
00529         {
00530           if (protocols[i].protocol_type == (*acceptor)->tag ())
00531             protocol_already_present = true;
00532         }
00533 
00534       if (protocol_already_present)
00535         continue;
00536 
00537       protocols.length (current_length + 1);
00538 
00539       protocols[current_length].protocol_type =
00540         (*acceptor)->tag ();
00541 
00542       protocols[current_length].orb_protocol_properties =
00543         RTCORBA::ProtocolProperties::_nil ();
00544 
00545       protocols[current_length].transport_protocol_properties =
00546         TAO_Protocol_Properties_Factory::create_transport_protocol_property ((*acceptor)->tag (),
00547                                                                              &orb_core);
00548     }
00549 }
00550 
00551 /* static */
00552 TAO_Thread_Pool *
00553 TAO_POA_RT_Policy_Validator::extract_thread_pool (TAO_ORB_Core &orb_core,
00554                                                   TAO_Policy_Set &policies
00555                                                   ACE_ENV_ARG_DECL)
00556 {
00557   CORBA::Policy_var policy =
00558     policies.get_cached_policy (TAO_CACHED_POLICY_THREADPOOL
00559                                 ACE_ENV_ARG_PARAMETER);
00560   ACE_CHECK_RETURN (0);
00561 
00562   RTCORBA::ThreadpoolPolicy_var thread_pool_policy =
00563     RTCORBA::ThreadpoolPolicy::_narrow (policy.in ()
00564                                         ACE_ENV_ARG_PARAMETER);
00565   ACE_CHECK_RETURN (0);
00566 
00567   if (CORBA::is_nil (thread_pool_policy.in ()))
00568     return 0;
00569 
00570   RTCORBA::ThreadpoolId thread_pool_id =
00571     thread_pool_policy->threadpool (ACE_ENV_SINGLE_ARG_PARAMETER);
00572   ACE_CHECK_RETURN (0);
00573 
00574   // Get the RTORB.
00575   CORBA::Object_var object =
00576     orb_core.resolve_rt_orb ();
00577 
00578   RTCORBA::RTORB_var rt_orb =
00579     RTCORBA::RTORB::_narrow (object.in ()
00580                              ACE_ENV_ARG_PARAMETER);
00581   ACE_CHECK_RETURN (0);
00582 
00583   TAO_RT_ORB *tao_rt_orb =
00584     dynamic_cast <TAO_RT_ORB *> (rt_orb.in ());
00585 
00586   TAO_Thread_Pool_Manager &tp_manager =
00587     tao_rt_orb->tp_manager ();
00588 
00589   TAO_Thread_Pool *thread_pool =
00590     tp_manager.get_threadpool (thread_pool_id ACE_ENV_ARG_PARAMETER);
00591   ACE_CHECK_RETURN (0);
00592 
00593   if (thread_pool == 0)
00594     ACE_THROW_RETURN (PortableServer::POA::InvalidPolicy (),
00595                       0);
00596 
00597   return thread_pool;
00598 }
00599 
00600 TAO_END_VERSIONED_NAMESPACE_DECL
00601 
00602 #endif /* TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0 */

Generated on Thu Nov 9 12:55:46 2006 for TAO_RTPortableServer by doxygen 1.3.6