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

Generated on Sun Jan 27 13:31:11 2008 for TAO_RTPortableServer by doxygen 1.3.6