diff options
Diffstat (limited to 'TAO/tao/RTPortableServer/RT_POA.cpp')
-rw-r--r-- | TAO/tao/RTPortableServer/RT_POA.cpp | 719 |
1 files changed, 719 insertions, 0 deletions
diff --git a/TAO/tao/RTPortableServer/RT_POA.cpp b/TAO/tao/RTPortableServer/RT_POA.cpp new file mode 100644 index 00000000000..1a79cf2b377 --- /dev/null +++ b/TAO/tao/RTPortableServer/RT_POA.cpp @@ -0,0 +1,719 @@ +// $Id$ + +#include "tao/RTPortableServer/RT_POA.h" + +#if defined (TAO_HAS_CORBA_MESSAGING) && TAO_HAS_CORBA_MESSAGING != 0 + +#include "tao/RTPortableServer/RT_Acceptor_Filters.h" + +#include "tao/ORB_Core.h" +#include "tao/ORB.h" +#include "tao/Server_Strategy_Factory.h" +#include "tao/Exception.h" +#include "tao/Stub.h" +#include "tao/Policy_Manager.h" +#include "tao/debug.h" +#include "tao/RTCORBA/Thread_Pool.h" +#include "tao/Thread_Lane_Resources.h" +#include "tao/Acceptor_Registry.h" +#include "tao/Thread_Lane_Resources.h" +#include "tao/Thread_Lane_Resources_Manager.h" + +#include "tao/RTCORBA/RT_Policy_i.h" + +#include "tao/PortableServer/Default_Acceptor_Filter.h" +#include "tao/RTPortableServer/RT_Policy_Validator.h" + +#include "ace/Auto_Ptr.h" + +#if !defined (__ACE_INLINE__) +# include "tao/RTPortableServer/RT_POA.inl" +#endif /* ! __ACE_INLINE__ */ + +ACE_RCSID (RTPortableServer, + RT_POA, + "$Id$") + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +TAO_RT_POA::TAO_RT_POA (const TAO_Root_POA::String &name, + PortableServer::POAManager_ptr poa_manager, + const TAO_POA_Policy_Set &policies, + TAO_Root_POA *parent, + ACE_Lock &lock, + TAO_SYNCH_MUTEX &thread_lock, + TAO_ORB_Core &orb_core, + TAO_Object_Adapter *object_adapter + ) + : TAO_Regular_POA (name, + poa_manager, + policies, + parent, + lock, + thread_lock, + orb_core, + object_adapter), + thread_pool_ (0) +{ + // Parse the RT policies and update our policy cache. + this->parse_rt_policies (this->policies ()); +} + +TAO_RT_POA::~TAO_RT_POA (void) +{ +} + +TAO_Root_POA * +TAO_RT_POA::new_POA (const String &name, + PortableServer::POAManager_ptr poa_manager, + const TAO_POA_Policy_Set &policies, + TAO_Root_POA *parent, + ACE_Lock &lock, + TAO_SYNCH_MUTEX &thread_lock, + TAO_ORB_Core &orb_core, + TAO_Object_Adapter *object_adapter) +{ + TAO_RT_POA *poa = 0; + + ACE_NEW_THROW_EX (poa, + TAO_RT_POA (name, + poa_manager, + policies, + parent, + lock, + thread_lock, + orb_core, + object_adapter + ), + CORBA::NO_MEMORY ()); + + return poa; +} + +void +TAO_RT_POA::parse_rt_policies (TAO_POA_Policy_Set &policies) +{ + { + CORBA::Policy_var policy = + policies.get_cached_policy (TAO_CACHED_POLICY_PRIORITY_MODEL); + + RTCORBA::PriorityModelPolicy_var priority_model = + RTCORBA::PriorityModelPolicy::_narrow (policy.in ()); + + if (!CORBA::is_nil (priority_model.in ())) + { + RTCORBA::PriorityModel rt_priority_model = + priority_model->priority_model (); + + this->cached_policies_.priority_model ( + TAO::Portable_Server::Cached_Policies::PriorityModel (rt_priority_model)); + + RTCORBA::Priority priority = + priority_model->server_priority (); + + this->cached_policies_.server_priority (priority); + } + } + + this->thread_pool_ = + TAO_POA_RT_Policy_Validator::extract_thread_pool (this->orb_core_, + policies.policies ()); +} + +void +TAO_RT_POA::validate_priority (RTCORBA::Priority priority) +{ + if (priority < RTCORBA::minPriority + // The line below will always be false unless the value of + // RTCORBA::maxPriority, which is now assigned the value of + // 32767, is changed in RTCORBA.pidl. +// || priority > RTCORBA::maxPriority + ) + { + throw ::CORBA::BAD_PARAM (); + } + + // If this POA is using a thread pool with lanes, make sure the + // priority matches one of the thread lanes. Note that in this + // case, bands do not matter since matching the lanes priority is a + // stricter condition than meeting the band ranges. In addition, + // when the POA was created, the bands had to match the lanes. + if (this->thread_pool_ != 0 && this->thread_pool_->with_lanes ()) + { + TAO_Thread_Lane **lanes = this->thread_pool_->lanes (); + + for (CORBA::ULong i = 0; + i != this->thread_pool_->number_of_lanes (); + ++i) + { + if (lanes[i]->lane_priority () == priority) + return; + } + + throw ::CORBA::BAD_PARAM (); + } + else + // Else we are dealing with a thread pool without lanes. + { + // Check if we have bands. + CORBA::Policy_var bands = + this->policies ().get_cached_policy ( + TAO_CACHED_POLICY_RT_PRIORITY_BANDED_CONNECTION); + + RTCORBA::PriorityBandedConnectionPolicy_var priority_bands + = RTCORBA::PriorityBandedConnectionPolicy::_narrow (bands.in ()); + + TAO_PriorityBandedConnectionPolicy *priority_bands_i = + dynamic_cast <TAO_PriorityBandedConnectionPolicy *> + (priority_bands.in ()); + + if (priority_bands_i) + { + // If we do have bands, make sure that the priority is + // matching one of the bands. + RTCORBA::PriorityBands &bands = + priority_bands_i->priority_bands_rep (); + + for (CORBA::ULong i = 0; + i < bands.length (); + ++i) + { + if (bands[i].low <= priority && + bands[i].high >= priority) + return; + } + + throw ::CORBA::BAD_PARAM (); + } + } +} + +void +TAO_RT_POA::validate_policies (void) +{ + // For each of the above operations, if the POA supports the + // IMPLICIT_ACTIVATION option for the ImplicitActivationPolicy then + // the ORB shall raise a WrongPolicy user exception. This relieves + // an ORB implementation of the need to retrieve the target object's + // priority from "somewhere" when a request arrives for an inactive + // object. + if (this->cached_policies_.implicit_activation () == + PortableServer::IMPLICIT_ACTIVATION) + { + throw PortableServer::POA::WrongPolicy (); + } + + // For each of the above operations, if the POA does not support the + // SERVER_DECLARED option for the PriorityModelPolicy then the ORB + // shall raise a WrongPolicy user exception. + if (this->cached_policies_.priority_model () != + TAO::Portable_Server::Cached_Policies::SERVER_DECLARED) + { + throw PortableServer::POA::WrongPolicy (); + } + + // In all other respects the semantics of the corresponding + // (i.e. without the name extensions "_with_priority" and + // "_and_priority") PortableServer::POA operations shall be + // observed. +} + +TAO_Stub * +TAO_RT_POA::key_to_stub_i (const TAO::ObjectKey &object_key, + const char *type_id, + CORBA::Short priority) +{ + // Client exposed policies. + CORBA::PolicyList_var client_exposed_policies = + this->client_exposed_policies (priority); + + // Server protocol policy. + CORBA::Policy_var protocol = + this->policies ().get_cached_policy (TAO_CACHED_POLICY_RT_SERVER_PROTOCOL); + + RTCORBA::ServerProtocolPolicy_var server_protocol_policy = + RTCORBA::ServerProtocolPolicy::_narrow (protocol.in ()); + + TAO_ServerProtocolPolicy *server_protocol = + dynamic_cast <TAO_ServerProtocolPolicy *> (server_protocol_policy.in ()); + + // Filter for server protocol. + TAO_Server_Protocol_Acceptor_Filter filter (server_protocol->protocols_rep ()); + + // If this POA is using the default thread pool or a thread pool + // without lanes, create the IOR with the acceptors in the thread + // pool. + if (this->thread_pool_ == 0 || + !this->thread_pool_->with_lanes ()) + { + TAO_Acceptor_Registry *acceptor_registry = 0; + + if (this->thread_pool_ == 0) + { + TAO_Thread_Lane_Resources_Manager &thread_lane_resources_manager = + this->orb_core_.thread_lane_resources_manager (); + + TAO_Thread_Lane_Resources &resources = + thread_lane_resources_manager.default_lane_resources (); + + acceptor_registry = &resources.acceptor_registry (); + } + else + { + TAO_Thread_Lane **lanes = this->thread_pool_->lanes (); + + TAO_Thread_Lane_Resources &resources = lanes[0]->resources (); + + acceptor_registry = &resources.acceptor_registry (); + } + + return + this->TAO_Regular_POA::create_stub_object (object_key, + type_id, + client_exposed_policies._retn (), + &filter, + *acceptor_registry); + } + + // If this POA has the SERVER_DECLARED policy, create the IOR with + // the acceptors in the only thread lane that matches the priority + // of the object. + if (this->cached_policies_.priority_model () == + TAO::Portable_Server::Cached_Policies::SERVER_DECLARED) + { + TAO_Thread_Lane **lanes = + this->thread_pool_->lanes (); + + for (CORBA::ULong i = 0; + i != this->thread_pool_->number_of_lanes (); + ++i) + { + if (lanes[i]->lane_priority () == priority) + return this->TAO_Regular_POA::create_stub_object (object_key, + type_id, + client_exposed_policies._retn (), + &filter, + lanes[i]->resources ().acceptor_registry () + ); + } + + ACE_ASSERT (0); + } + + // If this POA has the CLIENT_PROPAGATED policy, create the IOR with + // the acceptors in the thread lanes that matches the bands in this + // POA. If there are no bands, all the thread lanes are used. + CORBA::Policy_var bands = + this->policies ().get_cached_policy ( + TAO_CACHED_POLICY_RT_PRIORITY_BANDED_CONNECTION + ); + + RTCORBA::PriorityBandedConnectionPolicy_var priority_bands + = RTCORBA::PriorityBandedConnectionPolicy::_narrow (bands.in ()); + + TAO_PriorityBandedConnectionPolicy *priority_bands_i = + dynamic_cast <TAO_PriorityBandedConnectionPolicy *> (priority_bands.in ()); + + return this->create_stub_object (object_key, + type_id, + client_exposed_policies._retn (), + &filter, + priority_bands_i); +} + +TAO_Stub * +TAO_RT_POA::create_stub_object (const TAO::ObjectKey &object_key, + const char *type_id, + CORBA::PolicyList *policy_list, + TAO_Acceptor_Filter *filter, + TAO_PriorityBandedConnectionPolicy *priority_bands) +{ + int error = 0; + + // Count the number of endpoints. + size_t profile_count = + this->endpoint_count (); + + // Create a profile container and have acceptor registries populate + // it with profiles as appropriate. + TAO_MProfile mprofile (0); + + // Allocate space for storing the profiles. There can never be more + // profiles than there are endpoints. In some cases, there can be + // less profiles than endpoints. + int result = + mprofile.set (static_cast <CORBA::ULong> (profile_count)); + if (result == -1) + error = 1; + + TAO_Thread_Lane **lanes = + this->thread_pool_->lanes (); + + // Leave it to the filter to decide which acceptors/in which order + // go into the mprofile. + for (CORBA::ULong i = 0; + i != this->thread_pool_->number_of_lanes () && + !error; + ++i) + { + if (this->lane_required (lanes[i], + priority_bands)) + { + TAO_Acceptor_Registry &acceptor_registry = + lanes[i]->resources ().acceptor_registry (); + + result = + filter->fill_profile (object_key, + mprofile, + acceptor_registry.begin (), + acceptor_registry.end (), + lanes[i]->lane_priority ()); + if (result == -1) + error = 1; + } + } + + if (!error) + result = filter->encode_endpoints (mprofile); + if (result == -1) + error = 1; + + if (error) + throw ::CORBA::INTERNAL ( + CORBA::SystemException::_tao_minor_code ( + TAO_MPROFILE_CREATION_ERROR, + 0), + CORBA::COMPLETED_NO); + + // Make sure we have at least one profile. <mp> may end up being + // empty if none of the acceptor endpoints have the right priority + // for this object, for example. + if (mprofile.profile_count () == 0) + throw ::CORBA::BAD_PARAM ( + CORBA::SystemException::_tao_minor_code ( + TAO_MPROFILE_CREATION_ERROR, + 0), + CORBA::COMPLETED_NO); + + return + this->orb_core_.create_stub_object (mprofile, type_id, policy_list); +} + +size_t +TAO_RT_POA::endpoint_count (void) +{ + size_t profile_count = 0; + + TAO_Thread_Lane **lanes = + this->thread_pool_->lanes (); + + for (CORBA::ULong i = 0; + i != this->thread_pool_->number_of_lanes (); + ++i) + profile_count += + lanes[i]->resources ().acceptor_registry ().endpoint_count (); + + return profile_count; +} + +int +TAO_RT_POA::lane_required (TAO_Thread_Lane *lane, + TAO_PriorityBandedConnectionPolicy *priority_bands) +{ + if (priority_bands == 0) + return 1; + + RTCORBA::PriorityBands &bands = + priority_bands->priority_bands_rep (); + + for (CORBA::ULong i = 0; + i < bands.length (); + ++i) + { + if (bands[i].low <= lane->lane_priority () && + bands[i].high >= lane->lane_priority ()) + return 1; + } + + return 0; +} + +CORBA::PolicyList * +TAO_RT_POA::client_exposed_policies (CORBA::Short object_priority) +{ + CORBA::PolicyList *client_exposed_policies = 0; + ACE_NEW_THROW_EX (client_exposed_policies, + CORBA::PolicyList (), + CORBA::NO_MEMORY (TAO::VMCID, + CORBA::COMPLETED_NO)); + + CORBA::PolicyList_var safe_client_exposed_policies = client_exposed_policies; + + // Add in all of the client exposed policies. + this->policies_.add_client_exposed_fixed_policies (client_exposed_policies); + + // Check if the priority model policy has been set, and if so, let + // the client know about it. + CORBA::Short poa_priority = + this->cached_policies_.server_priority (); + + if (poa_priority != TAO_INVALID_PRIORITY) + { + TAO::Portable_Server::Cached_Policies::PriorityModel priority_model = + this->cached_policies_.priority_model (); + + // If the priority model is client propagated, let the client + // about the default server priority (the POA priority). If + // the priority model is server declared, tell the client the + // servant's priority. + CORBA::Short priority; + if (priority_model == TAO::Portable_Server::Cached_Policies::CLIENT_PROPAGATED) + priority = poa_priority; + else + priority = object_priority; + + const CORBA::ULong current_length = + client_exposed_policies->length (); + client_exposed_policies->length (current_length + 1); + + TAO_PriorityModelPolicy *priority_model_policy; + ACE_NEW_THROW_EX (priority_model_policy, + TAO_PriorityModelPolicy (RTCORBA::PriorityModel (priority_model), + priority), + CORBA::NO_MEMORY (TAO::VMCID, + CORBA::COMPLETED_NO)); + + (*client_exposed_policies)[current_length] = priority_model_policy; + } + + return safe_client_exposed_policies._retn (); +} + + +// Standard POA interfaces +PortableServer::POA_ptr +TAO_RT_POA::create_POA (const char *adapter_name, + PortableServer::POAManager_ptr poa_manager, + const CORBA::PolicyList &policies) +{ + return this->TAO_Regular_POA::create_POA (adapter_name, poa_manager, policies); +} + +PortableServer::POA_ptr +TAO_RT_POA::find_POA (const char *adapter_name, CORBA::Boolean activate_it) +{ + return this->TAO_Regular_POA::find_POA (adapter_name, activate_it); +} + +void +TAO_RT_POA::destroy (CORBA::Boolean etherealize_objects, + CORBA::Boolean wait_for_completion) +{ + this->TAO_Regular_POA::destroy (etherealize_objects, wait_for_completion); +} + + +#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) + +PortableServer::ThreadPolicy_ptr +TAO_RT_POA::create_thread_policy (PortableServer::ThreadPolicyValue value) +{ + return this->TAO_Regular_POA::create_thread_policy (value); +} + +#endif /* TAO_HAS_MINIMUM_POA == 0 */ + +#if !defined (CORBA_E_MICRO) +PortableServer::LifespanPolicy_ptr +TAO_RT_POA::create_lifespan_policy (PortableServer::LifespanPolicyValue value) +{ + return this->TAO_Regular_POA::create_lifespan_policy (value); +} +#endif + +#if !defined (CORBA_E_MICRO) +PortableServer::IdUniquenessPolicy_ptr +TAO_RT_POA::create_id_uniqueness_policy (PortableServer::IdUniquenessPolicyValue value) +{ + return this->TAO_Regular_POA::create_id_uniqueness_policy (value); +} +#endif + +#if !defined (CORBA_E_MICRO) +PortableServer::IdAssignmentPolicy_ptr +TAO_RT_POA::create_id_assignment_policy (PortableServer::IdAssignmentPolicyValue value) +{ + return this->TAO_Regular_POA::create_id_assignment_policy (value); +} +#endif + +#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) + +PortableServer::ImplicitActivationPolicy_ptr +TAO_RT_POA::create_implicit_activation_policy ( + PortableServer::ImplicitActivationPolicyValue value) +{ + return this->TAO_Regular_POA::create_implicit_activation_policy (value); +} + +PortableServer::ServantRetentionPolicy_ptr +TAO_RT_POA::create_servant_retention_policy ( + PortableServer::ServantRetentionPolicyValue value) +{ + return this->TAO_Regular_POA::create_servant_retention_policy (value); +} + + +PortableServer::RequestProcessingPolicy_ptr +TAO_RT_POA::create_request_processing_policy ( + PortableServer::RequestProcessingPolicyValue value) +{ + return this->TAO_Regular_POA::create_request_processing_policy (value); +} + +#endif /* TAO_HAS_MINIMUM_POA == 0 && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) */ + +char * +TAO_RT_POA::the_name (void) +{ + return this->TAO_Regular_POA::the_name (); +} + +PortableServer::POA_ptr +TAO_RT_POA::the_parent (void) +{ + return this->TAO_Regular_POA::the_parent (); +} + +PortableServer::POAList * +TAO_RT_POA::the_children (void) +{ + return this->TAO_Regular_POA::the_children (); +} + +PortableServer::POAManager_ptr +TAO_RT_POA::the_POAManager (void) +{ + return this->TAO_Regular_POA::the_POAManager (); +} + + +#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) + +PortableServer::AdapterActivator_ptr +TAO_RT_POA::the_activator (void) +{ + return this->TAO_Regular_POA::the_activator ();; +} + +void +TAO_RT_POA::the_activator (PortableServer::AdapterActivator_ptr adapter_activator) +{ + this->TAO_Regular_POA::the_activator (adapter_activator); +} + +PortableServer::ServantManager_ptr +TAO_RT_POA::get_servant_manager (void) +{ + return this->TAO_Regular_POA::get_servant_manager (); +} + +void +TAO_RT_POA::set_servant_manager (PortableServer::ServantManager_ptr imgr) +{ + this->TAO_Regular_POA::set_servant_manager (imgr); +} + +PortableServer::Servant +TAO_RT_POA::get_servant (void) +{ + return this->TAO_Regular_POA::get_servant (); +} + +void +TAO_RT_POA::set_servant (PortableServer::Servant servant) +{ + this->TAO_Regular_POA::set_servant (servant); +} + +#endif /* TAO_HAS_MINIMUM_POA == 0 */ + +PortableServer::ObjectId * +TAO_RT_POA::activate_object (PortableServer::Servant p_servant) +{ + return this->TAO_Regular_POA::activate_object (p_servant); +} + +#if !defined (CORBA_E_MICRO) +void +TAO_RT_POA::activate_object_with_id (const PortableServer::ObjectId &id, + PortableServer::Servant p_servant) +{ + this->TAO_Regular_POA::activate_object_with_id (id, p_servant); +} +#endif + +void +TAO_RT_POA::deactivate_object (const PortableServer::ObjectId &oid) +{ + this->TAO_Regular_POA::deactivate_object (oid); +} + +CORBA::Object_ptr +TAO_RT_POA::create_reference (const char *intf) +{ + return this->TAO_Regular_POA::create_reference (intf); +} + +CORBA::Object_ptr +TAO_RT_POA::create_reference_with_id (const PortableServer::ObjectId &oid, + const char *intf) +{ + return this->TAO_Regular_POA::create_reference_with_id (oid, intf); +} + +PortableServer::ObjectId * +TAO_RT_POA::servant_to_id (PortableServer::Servant p_servant) +{ + return this->TAO_Regular_POA::servant_to_id (p_servant); +} + +CORBA::Object_ptr +TAO_RT_POA::servant_to_reference (PortableServer::Servant p_servant) +{ + return this->TAO_Regular_POA::servant_to_reference (p_servant); +} + +PortableServer::Servant +TAO_RT_POA::reference_to_servant (CORBA::Object_ptr reference) +{ + return this->TAO_Regular_POA::reference_to_servant (reference); +} + +PortableServer::ObjectId * +TAO_RT_POA::reference_to_id (CORBA::Object_ptr reference) +{ + return this->TAO_Regular_POA::reference_to_id (reference); +} + +PortableServer::Servant +TAO_RT_POA::id_to_servant (const PortableServer::ObjectId &oid) +{ + return this->TAO_Regular_POA::id_to_servant (oid); +} + +CORBA::Object_ptr +TAO_RT_POA::id_to_reference (const PortableServer::ObjectId &oid) +{ + return this->TAO_Regular_POA::id_to_reference (oid); +} + +CORBA::OctetSeq * +TAO_RT_POA::id (void) +{ + return this->TAO_Regular_POA::id (); +} + +TAO_END_VERSIONED_NAMESPACE_DECL + +#endif /* TAO_HAS_CORBA_MESSAGING && TAO_HAS_CORBA_MESSAGING != 0 */ |