diff options
Diffstat (limited to 'ACE/TAO/tao/PortableServer/Root_POA.cpp')
-rw-r--r-- | ACE/TAO/tao/PortableServer/Root_POA.cpp | 2728 |
1 files changed, 2728 insertions, 0 deletions
diff --git a/ACE/TAO/tao/PortableServer/Root_POA.cpp b/ACE/TAO/tao/PortableServer/Root_POA.cpp new file mode 100644 index 00000000000..2dbda275c25 --- /dev/null +++ b/ACE/TAO/tao/PortableServer/Root_POA.cpp @@ -0,0 +1,2728 @@ +// $Id$ + +#include "tao/PortableServer/Root_POA.h" +#include "tao/PortableServer/Regular_POA.h" + +#include "tao/PortableServer/ThreadPolicy.h" +#include "tao/PortableServer/LifespanPolicy.h" +#include "tao/PortableServer/IdAssignmentPolicy.h" +#include "tao/PortableServer/IdUniquenessPolicy.h" +#include "tao/PortableServer/ImplicitActivationPolicy.h" +#include "tao/PortableServer/RequestProcessingPolicy.h" +#include "tao/PortableServer/ServantRetentionPolicy.h" +#include "tao/PortableServer/Active_Object_Map.h" +#include "tao/PortableServer/Default_Acceptor_Filter.h" +#include "tao/PortableServer/ORT_Adapter.h" +#include "tao/PortableServer/ORT_Adapter_Factory.h" +#include "tao/PortableServer/POA_Current_Impl.h" +#include "tao/PortableServer/Servant_Upcall.h" +#include "tao/PortableServer/AdapterActivatorC.h" +#include "tao/PortableServer/Non_Servant_Upcall.h" +#include "tao/PortableServer/POAManager.h" +#include "tao/PortableServer/POAManagerFactory.h" +#include "tao/PortableServer/ServantManagerC.h" +#include "tao/PortableServer/poa_macros.h" +#include "tao/PortableServer/POA_Guard.h" +#include "tao/PortableServer/Creation_Time.h" +#include "tao/PortableServer/RequestProcessingStrategy.h" +#include "tao/PortableServer/LifespanStrategy.h" +#include "tao/PortableServer/IdUniquenessStrategy.h" +#include "tao/PortableServer/IdAssignmentStrategy.h" +#include "tao/PortableServer/ServantRetentionStrategy.h" +#include "tao/PortableServer/ImplicitActivationStrategy.h" +#include "tao/PortableServer/ThreadStrategy.h" +#include "tao/PortableServer/Acceptor_Filter_Factory.h" +#include "tao/PortableServer/Network_Priority_Hook.h" + +#include "tao/StringSeqC.h" +#include "tao/PortableInterceptorC.h" +#include "tao/PolicyC.h" +#include "tao/ORB_Core.h" +#include "tao/ORB.h" +#include "tao/Server_Strategy_Factory.h" +#include "tao/Acceptor_Registry.h" +#include "tao/Thread_Lane_Resources.h" +#include "tao/Exception.h" +#include "tao/Stub.h" +#include "tao/Profile.h" +#include "tao/TSS_Resources.h" +#include "tao/IORInterceptor_Adapter.h" +#include "tao/debug.h" + +// auto_ptr class +#include "ace/Auto_Ptr.h" +#include "ace/Dynamic_Service.h" +#include "ace/OS_NS_netdb.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_unistd.h" +#include "ace/Log_Msg.h" + +#if !defined (__ACE_INLINE__) +# include "tao/PortableServer/Root_POA.inl" +#endif /* ! __ACE_INLINE__ */ + +ACE_RCSID (PortableServer, + Root_POA, + "$Id$") + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +// This is the TAO_Object_key-prefix that is appended to all TAO Object keys. +// It's an array of octets representing ^t^a^o/0 in octal. +CORBA::Octet const +TAO_Root_POA::objectkey_prefix [TAO_Root_POA::TAO_OBJECTKEY_PREFIX_SIZE] = { + 024, // octal for ^t + 001, // octal for ^a + 017, // octal for ^o + 000 +}; + +#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) + +PortableServer::ThreadPolicy_ptr +TAO_Root_POA::create_thread_policy (PortableServer::ThreadPolicyValue value) +{ + TAO::Portable_Server::ThreadPolicy *policy = 0; + ACE_NEW_THROW_EX (policy, + TAO::Portable_Server::ThreadPolicy (value), + CORBA::NO_MEMORY ()); + + return policy; +} + +#endif /* TAO_HAS_MINIMUM_POA == 0 && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) */ + +#if !defined (CORBA_E_MICRO) + +PortableServer::LifespanPolicy_ptr +TAO_Root_POA::create_lifespan_policy (PortableServer::LifespanPolicyValue value) +{ + TAO::Portable_Server::LifespanPolicy *policy = 0; + ACE_NEW_THROW_EX (policy, + TAO::Portable_Server::LifespanPolicy (value), + CORBA::NO_MEMORY ()); + + return policy; +} + +#endif + +#if !defined (CORBA_E_MICRO) +PortableServer::IdUniquenessPolicy_ptr +TAO_Root_POA::create_id_uniqueness_policy (PortableServer::IdUniquenessPolicyValue value) +{ + TAO::Portable_Server::IdUniquenessPolicy *policy = 0; + ACE_NEW_THROW_EX (policy, + TAO::Portable_Server::IdUniquenessPolicy (value), + CORBA::NO_MEMORY ()); + + return policy; +} +#endif + +#if !defined (CORBA_E_MICRO) +PortableServer::IdAssignmentPolicy_ptr +TAO_Root_POA::create_id_assignment_policy (PortableServer::IdAssignmentPolicyValue value) +{ + TAO::Portable_Server::IdAssignmentPolicy *policy = 0; + ACE_NEW_THROW_EX (policy, + TAO::Portable_Server::IdAssignmentPolicy (value), + CORBA::NO_MEMORY ()); + + return policy; +} +#endif + +#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) + +PortableServer::ImplicitActivationPolicy_ptr +TAO_Root_POA::create_implicit_activation_policy (PortableServer::ImplicitActivationPolicyValue value) +{ + TAO::Portable_Server::ImplicitActivationPolicy *policy = 0; + ACE_NEW_THROW_EX (policy, + TAO::Portable_Server::ImplicitActivationPolicy (value), + CORBA::NO_MEMORY ()); + + return policy; +} + +PortableServer::ServantRetentionPolicy_ptr +TAO_Root_POA::create_servant_retention_policy (PortableServer::ServantRetentionPolicyValue value) +{ + TAO::Portable_Server::ServantRetentionPolicy *policy = 0; + ACE_NEW_THROW_EX (policy, + TAO::Portable_Server::ServantRetentionPolicy (value), + CORBA::NO_MEMORY ()); + + return policy; +} + +PortableServer::RequestProcessingPolicy_ptr +TAO_Root_POA::create_request_processing_policy (PortableServer::RequestProcessingPolicyValue value) +{ + TAO::Portable_Server::RequestProcessingPolicy *policy = 0; + ACE_NEW_THROW_EX (policy, + TAO::Portable_Server::RequestProcessingPolicy (value), + CORBA::NO_MEMORY ()); + + return policy; +} + +#endif /* TAO_HAS_MINIMUM_POA == 0 */ + +void +TAO_Root_POA::set_obj_ref_factory ( + PortableInterceptor::ObjectReferenceFactory *current_factory) +{ + TAO::ORT_Adapter *adapter = this->ORT_adapter (); + + if (adapter) + { + // Activate a different factory + this->ort_adapter_->set_obj_ref_factory (current_factory); + } +} + +TAO_Root_POA::TAO_Root_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) + : name_ (name), + poa_manager_ (* (dynamic_cast <TAO_POA_Manager*> (poa_manager))), + +#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) + poa_manager_factory_ (* (object_adapter->poa_manager_factory_)), +#endif + + tagged_component_ (), + tagged_component_id_ (), + profile_id_array_ (0), + policies_ (policies), + ort_adapter_ (0), + adapter_state_ (PortableInterceptor::HOLDING), + network_priority_hook_ (0), +#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) + adapter_activator_ (), +#endif /* TAO_HAS_MINIMUM_POA == 0 */ + children_ (), + lock_ (lock), + orb_core_ (orb_core), + object_adapter_ (object_adapter), + cleanup_in_progress_ (false), + outstanding_requests_ (0), + outstanding_requests_condition_ (thread_lock), + wait_for_completion_pending_ (0), + waiting_destruction_ (false), + servant_deactivation_condition_ (thread_lock), +#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) + filter_factory_ (0), +#endif + caller_key_to_object_ (0), + servant_for_key_to_object_ (0) +{ + // Since we are keeping a reference to a POAManager, we need to + // increment the reference count but we do this safely. + PortableServer::POAManager_var pm_guard ( + PortableServer::POAManager::_duplicate(&this->poa_manager_)); + + // Parse the policies that are used in the critical path in + // a cache. + this->cached_policies_.update (this->policies_); + +#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) + this->filter_factory_ + = ACE_Dynamic_Service<TAO_Acceptor_Filter_Factory>::instance ( + "TAO_Acceptor_Filter_Factory"); +#endif + + this->network_priority_hook_ + = ACE_Dynamic_Service<TAO_Network_Priority_Hook>::instance ( + "TAO_Network_Priority_Hook"); + + if (this->network_priority_hook_ != 0) + { + this->network_priority_hook_->update_network_priority ( + *this, this->policies_); + } + +#if (TAO_HAS_MINIMUM_POA == 1) + // If this is the RootPOA, set the value of the ImplicitActivationPolicy + // to IMPLICIT_ACTIVATION since it is impossible to pass the policy + // as it is not compiled into the library. + // + // If the ImplicitActivationPolicy policy is ever compiled in the + // minimum POA builds, remove this code and remove the guards + // in Object_Adapter.cpp when changing the default policy for the + // RootPOA. + if (ACE_OS::strcmp (this->name_.c_str (), + TAO_DEFAULT_ROOTPOA_NAME) == 0) + { + this->cached_policies_.implicit_activation + (PortableServer::IMPLICIT_ACTIVATION); + } +#endif /* TAO_HAS_MINIMUM_POA == 1 */ + + // Set the active strategies to be used by this POA + this->active_policy_strategies_.update (this->cached_policies_, + this); + TAO::Portable_Server::Active_Policy_Strategies_Cleanup_Guard aps_cleanup_guard ( + &this->active_policy_strategies_); + + // Set the folded name of this POA. + this->set_folded_name (parent); + + // Register self with manager. + int result = this->poa_manager_.register_poa (this); + if (result != 0) + { + throw ::CORBA::OBJ_ADAPTER (); + } + + // Add self to Object Adapter class. + result = + this->object_adapter ().bind_poa (this->folded_name_, + this, + this->system_name_.out ()); + if (result != 0) + { + // Remove from POA Manager in case of errors. No checks of + // further errors... + this->poa_manager_.remove_poa (this); + + throw ::CORBA::OBJ_ADAPTER (); + } + + // Set the id for this POA. + this->set_id (parent); + + // Notify the Lifespan strategy of our startup + try + { + this->active_policy_strategies_.lifespan_strategy()->notify_startup (); + } + catch (const ::CORBA::Exception&) + { + this->poa_manager_.remove_poa (this); + this->object_adapter ().unbind_poa (this, + this->folded_name_, + this->system_name_.in ()); + throw; + } + + // Now when everything is fine we can release the quards. + pm_guard._retn (); + aps_cleanup_guard._retn (); +} + +TAO_Root_POA::~TAO_Root_POA (void) +{ + this->poa_manager_._remove_ref(); +} + +void +TAO_Root_POA::complete_destruction_i (void) +{ + bool doing_complete_destruction = + this->waiting_destruction_ != false; + + // No longer awaiting destruction. + this->waiting_destruction_ = false; + + PortableServer::POA_var poa; + TAO::ORT_Array my_array_obj_ref_template; + TAO::ORT_Adapter *ort_adapter = 0; + if (doing_complete_destruction) + { + ort_adapter = + this->ORT_adapter_i (); + + // In case no ORT library is linked we get zero. + if (ort_adapter != 0) + { + // Get the ObjectReferenceTemplate. + PortableInterceptor::ObjectReferenceTemplate * const ort = + ort_adapter->get_adapter_template (); + + // Add it to the sequence of object reference templates, we + // just notify for ourselves that we are now non_existent, + // our childs will do it for themselves. + my_array_obj_ref_template.size (1); + my_array_obj_ref_template[0] = ort; + } + + poa = PortableServer::POA::_duplicate (this); + } + + // Remove POA from the POAManager. + if (this->poa_manager_.remove_poa (this) != 0) + throw ::CORBA::OBJ_ADAPTER (); + + // Remove POA from the Object Adapter. + int result = this->object_adapter ().unbind_poa (this, + this->folded_name_, + this->system_name_.in ()); + if (result != 0) + throw ::CORBA::OBJ_ADAPTER (); + + // Cleanup all strategies + this->active_policy_strategies_.cleanup (); + + // Forced cleanup. The new memory management scheme is evil and can + // lead to reference deadlock, i.e., POA holds object A, but POA + // cannot die because object A hold POA. + { + // + // If new things are added to this cleanup code, make sure to move + // the minimum CORBA #define after the declaration of + // <non_servant_upcall>. + // + +#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) + + // ATTENTION: Trick locking here, see class header for details + TAO::Portable_Server::Non_Servant_Upcall non_servant_upcall (*this); + ACE_UNUSED_ARG (non_servant_upcall); + + this->adapter_activator_ = PortableServer::AdapterActivator::_nil (); + +#endif /* TAO_HAS_MINIMUM_POA == 0 */ + + } + + ::CORBA::release (this); + + if (doing_complete_destruction) + { + this->adapter_state_ = PortableInterceptor::NON_EXISTENT; + + this->adapter_state_changed (my_array_obj_ref_template, + this->adapter_state_); + + if (ort_adapter != 0) + { + ort_adapter->release (my_array_obj_ref_template[0]); + + TAO::ORT_Adapter_Factory *ort_factory = + this->ORT_adapter_factory (); + + ort_factory->destroy (ort_adapter); + + this->ort_adapter_ = 0; + } + } +} + +#if ! defined (CORBA_E_MICRO) +PortableServer::POA_ptr +TAO_Root_POA::create_POA_i (const char *adapter_name, + PortableServer::POAManager_ptr poa_manager, + const CORBA::PolicyList &policies) +{ + // Initialize a TAO_POA_Policy_Set instance so that it contains the + // default POA policies. + TAO_POA_Policy_Set tao_policies (this->object_adapter ().default_poa_policies ()); + + // Merge policies from the ORB level. + this->object_adapter ().validator ().merge_policies (tao_policies.policies ()); + + // Merge in any policies that the user may have specified. + tao_policies.merge_policies (policies); + + // If any of the policy objects specified are not valid for the ORB + // implementation, if conflicting policy objects are specified, or + // if any of the specified policy objects require prior + // administrative action that has not been performed, an + // InvalidPolicy exception is raised containing the index in the + // policies parameter value of the first offending policy object. + tao_policies.validate_policies (this->object_adapter ().validator (), + this->orb_core_); + + // If the poa_manager parameter is null, a new POAManager object is + // created and associated with the new POA. Otherwise, the specified + // POAManager object is associated with the new POA. The POAManager + // object can be obtained using the attribute name the_POAManager. + + PortableServer::POAManager_var the_poa_manager; + + if (CORBA::is_nil (poa_manager)) + { +#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) + + PortableServer::POA_var poa = PortableServer::POA::_duplicate (this); + PortableServer::POA_var root_poa; + + // Find the RootPOA by traversing the POA hierarchy until the + // RootPOA is reached. The RootPOA has no parent. + while (!CORBA::is_nil (poa.in ())) + { + root_poa = poa; + poa = poa->the_parent (); + } + + // Get the POAManagerFactory instance owned by RootPOA. + PortableServer::POAManagerFactory_var tao_poa_manager_factory + = root_poa->the_POAManagerFactory (); + + CORBA::PolicyList empty_policies; + + // The POAManager name will be generated when the POAManager instance + // is created. + the_poa_manager + = tao_poa_manager_factory->create_POAManager (0, empty_policies); +#else + + PortableServer::POAManager_ptr the_poa_manager_ptr; + ACE_NEW_THROW_EX (the_poa_manager_ptr, + TAO_POA_Manager (this->object_adapter (), 0), + CORBA::NO_MEMORY ()); + the_poa_manager = the_poa_manager_ptr; +#endif /* TAO_HAS_MINIMUM_POA == 0 && ! CORBA_E_COMPACT) */ + + } + else + { + the_poa_manager = PortableServer::POAManager::_duplicate (poa_manager); + } + + PortableServer::POA_var poa = this->create_POA_i (adapter_name, + the_poa_manager.in (), + tao_policies); + + return poa._retn (); +} +#endif /* !CORBA_E_MICRO */ + +#if ! defined (CORBA_E_MICRO) +TAO_Root_POA * +TAO_Root_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_Regular_POA *poa = 0; + + ACE_NEW_THROW_EX (poa, + TAO_Regular_POA (name, + poa_manager, + policies, + parent, + lock, + thread_lock, + orb_core, + object_adapter), + CORBA::NO_MEMORY ()); + + return poa; +} + +PortableServer::POA_ptr +TAO_Root_POA::create_POA_i (const TAO_Root_POA::String &adapter_name, + PortableServer::POAManager_ptr poa_manager, + const TAO_POA_Policy_Set &policies) +{ + // This operaton creates a new POA as a child of the target POA. The + // specified name identifies the new POA with respect to other POAs + // with the same parent POA. If the target POA already has a child + // POA with the specified name, the AdapterAlreadyExists exception + // is raised. + // Child was found + if (this->children_.find (adapter_name) != -1) + { + throw PortableServer::POA::AdapterAlreadyExists (); + } + + // + // Child was not found. Create one. + // + + // The specified policy objects are associated with the POA and used + // to control its behavior. The policy objects are effectively + // copied before this operation returns, so the application is free + // to destroy them while the POA is in use. Policies are not + // inherited from the parent POA. + TAO_Root_POA * poa = this->new_POA (adapter_name, + poa_manager, + policies, + this, + this->object_adapter ().lock (), + this->object_adapter ().thread_lock (), + this->orb_core_, + this->object_adapter_); + + // Give ownership of the new map to the POA_var. Note, that it + // is important for the POA_var to take ownership before + // checking for exception since we may need to delete the new map. + PortableServer::POA_var new_poa = poa; + + // Check for exception in construction of the POA. + + // Add to children map + if (this->children_.bind (adapter_name, poa) != 0) + { + throw ::CORBA::OBJ_ADAPTER (); + } + + // Increment the reference count on the child POA since the children + // map must retain ownership. Do so immediately before any other + // operations to prevent memory cleanup problems induced from + // errors below. + poa->_add_ref (); + + // Iterate over the registered IOR interceptors so that they may be + // given the opportunity to add tagged components to the profiles + // for this servant. + poa->establish_components (); + + // Note: Creating a POA using a POA manager that is in the active + // state can lead to race conditions if the POA supports preexisting + // objects, because the new POA may receive a request before its + // adapter activator, servant manager, or default servant have been + // initialized. These problems do not occur if the POA is created by + // an adapter activator registered with a parent of the new POA, + // because requests are queued until the adapter activator + // returns. To avoid these problems when a POA must be explicitly + // initialized, the application can initialize the POA by invoking + // find_POA with a TRUE activate parameter. + + // Everything is fine. Don't let the POA_var release the + // implementation. + return new_poa._retn (); +} +#endif + +#if ! defined (CORBA_E_MICRO) +PortableServer::POA_ptr +TAO_Root_POA::find_POA (const char *adapter_name, + CORBA::Boolean activate_it) +{ + // Lock access for the duration of this transaction. + TAO_POA_GUARD_RETURN (0); + + TAO_Root_POA *poa = this->find_POA_i (adapter_name, activate_it); + + return PortableServer::POA::_duplicate (poa); +} +#endif + +#if ! defined (CORBA_E_MICRO) +TAO_Root_POA * +TAO_Root_POA::find_POA_i (const ACE_CString &child_name, + CORBA::Boolean activate_it) +{ + TAO_Root_POA *child = 0; + int result = this->children_.find (child_name, child); + +#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) + + if (result != 0) + { + if (activate_it) + { + if (!CORBA::is_nil (this->adapter_activator_.in ())) + { + // Check our state + this->check_state (); + + CORBA::Boolean success = false; + + { + // ATTENTION: Trick locking here, see class header for details + TAO::Portable_Server::Non_Servant_Upcall non_servant_upcall ( + *this); + ACE_UNUSED_ARG (non_servant_upcall); + + // When unknown_adapter gives a system exception, the POA + // should just pass the system exception through + // See 15.3.9.2 of the 3.1 CORBA spec + success = + this->adapter_activator_->unknown_adapter ( + this, + child_name.c_str ()); + } + + if (success) + { + result = this->children_.find (child_name, + child); + } + else + { + result = -1; + } + } + else + { + result = -1; + } + } + else + { + result = -1; + } + } +#else + ACE_UNUSED_ARG (activate_it); +#endif /* TAO_HAS_MINIMUM_POA == 0 */ + + if (result == 0) + { + return child; + } + else + { + // Otherwise, the AdapterNonExistent exception is raised. + throw PortableServer::POA::AdapterNonExistent (); + } +} +#endif + +TAO_POA_Manager & +TAO_Root_POA::tao_poa_manager () +{ + return poa_manager_; +} + +#if ! defined (CORBA_E_MICRO) +PortableServer::POA_ptr +TAO_Root_POA::create_POA (const char *adapter_name, + PortableServer::POAManager_ptr poa_manager, + const CORBA::PolicyList &policies) +{ + // Lock access for the duration of this transaction. + TAO_POA_GUARD_RETURN (0); + + return this->create_POA_i (adapter_name, poa_manager, policies); +} +#endif + +PortableServer::ObjectId * +TAO_Root_POA::servant_to_id (PortableServer::Servant servant) +{ + // If we had upgradeable locks, this would initially be a read lock + // + // Lock access for the duration of this transaction. + TAO_POA_GUARD_RETURN (0); + + return this->servant_to_id_i (servant); +} + +PortableServer::ObjectId * +TAO_Root_POA::servant_to_user_id (PortableServer::Servant servant) +{ + return this->active_policy_strategies_.servant_retention_strategy()-> + servant_to_user_id (servant); +} + +PortableServer::Servant +TAO_Root_POA::reference_to_servant (CORBA::Object_ptr reference) +{ + // Lock access for the duration of this transaction. + TAO_POA_GUARD_RETURN (0); + + return this->reference_to_servant_i (reference); +} + +CORBA::Object_ptr +TAO_Root_POA::servant_to_reference (PortableServer::Servant servant) +{ + TAO_POA_GUARD_RETURN (CORBA::Object::_nil ()); + + return this->servant_to_reference_i (servant); +} + +PortableServer::POAList * +TAO_Root_POA::the_children (void) +{ + // Lock access for the duration of this transaction. + TAO_POA_GUARD_RETURN (0); + + return this->the_children_i (); +} + + +PortableServer::Servant +TAO_Root_POA::id_to_servant (const PortableServer::ObjectId &oid) +{ + // Lock access for the duration of this transaction. + TAO_POA_GUARD_RETURN (0); + + return this->id_to_servant_i (oid); +} + +CORBA::Object_ptr +TAO_Root_POA::id_to_reference (const PortableServer::ObjectId &oid) +{ + // Lock access for the duration of this transaction. + TAO_POA_GUARD_RETURN (0); + + return this->id_to_reference_i (oid, true); +} + + +#if ! defined (CORBA_E_MICRO) +CORBA::Object_ptr +TAO_Root_POA::create_reference_with_id (const PortableServer::ObjectId &id, + const char *intf) +{ + // Lock access for the duration of this transaction. + TAO_POA_GUARD_RETURN (CORBA::Object::_nil ()); + + return this->create_reference_with_id_i (id, + intf, + this->server_priority ()); +} +#endif + +void +TAO_Root_POA::destroy (CORBA::Boolean etherealize_objects, + CORBA::Boolean wait_for_completion) +{ + // Lock access for the duration of this transaction. + TAO::Portable_Server::POA_Guard poa_guard (*this , 0); + ACE_UNUSED_ARG (poa_guard); + + this->destroy_i (etherealize_objects, wait_for_completion); +} + +void +TAO_Root_POA::remove_from_parent_i (void) +{ + // The root poa has no parent, so this is a noop +} + +void +TAO_Root_POA::destroy_i (CORBA::Boolean etherealize_objects, + CORBA::Boolean wait_for_completion) +{ + if (this->cleanup_in_progress_) + return; + + // Is the <wait_for_completion> semantics for this thread correct? + TAO_Root_POA::check_for_valid_wait_for_completions (this->orb_core (), + wait_for_completion); + + this->cleanup_in_progress_ = true; + + // Inform the custom servant dispatching strategy to stop the working + // threads when the poa is destroyed. + this->poa_deactivated_hook (); + + // This operation destroys the POA and all descendant POAs. The POA + // so destroyed (that is, the POA with its name) may be re-created + // later in the same process. (This differs from the + // POAManager::deactivate operation that does not allow a + // re-creation of its associated POA in the same process.) + + // Remove POA from the parent + this->remove_from_parent_i (); + + TAO::ORT_Array array_obj_ref_template (1); + + CORBA::ULong i = 0; + + // Gather all ObjectReferenceTemplates and change all adapter states + // to INACTIVE. + for (CHILDREN::iterator iterator = this->children_.begin (); + iterator != this->children_.end (); + ++iterator) + { + TAO_Root_POA * const child_poa = (*iterator).int_id_; + + TAO::ORT_Adapter * const adapter = child_poa->ORT_adapter_i (); + + // In case no ORT library is linked we get zero. + if (adapter != 0) + { + // Get the ObjectReferenceTemplate for the child POA. + PortableInterceptor::ObjectReferenceTemplate * const ort = + adapter->get_adapter_template (); + + // Add it to the sequence of object reference templates that + // will be destroyed. + array_obj_ref_template.size (1); + + array_obj_ref_template[0] = ort; + } + + child_poa->adapter_state_ = + PortableInterceptor::INACTIVE; + + // Notify the state changes to the IORInterceptors + this->adapter_state_changed (array_obj_ref_template, + PortableInterceptor::INACTIVE); + + if (adapter != 0) + adapter->release (array_obj_ref_template[0]); + + ++i; + } + + // Destroy all child POA's now. + for (CHILDREN::iterator destroy_iterator = this->children_.begin (); + destroy_iterator != this->children_.end (); + ++destroy_iterator) + { + TAO_Root_POA *destroy_child_poa = (*destroy_iterator).int_id_; + + destroy_child_poa->destroy_i (etherealize_objects, + wait_for_completion); + } + + // Notify the lifespan strategy of our shutdown + this->active_policy_strategies_.lifespan_strategy()->notify_shutdown (); + +// @todo, is the exception handling above correct, should we just fail when +// the notify above fails + + // When a POA is destroyed, any requests that have started execution + // continue to completion. Any requests that have not started + // execution are processed as if they were newly arrived, that is, + // the POA will attempt to cause recreation of the POA by invoking + // one or more adapter activators as described in Section 3.3.3. + // If the wait_for_completion parameter is TRUE, the destroy + // operation will return only after all requests in process have + // completed and all invocations of etherealize have + // completed. Otherwise, the destroy operation returns after + // destroying the POAs. + + this->deactivate_all_objects_i (etherealize_objects, + wait_for_completion); + + // If there are no outstanding requests and that we are not in a + // non-servant upcall or if we are in a non-servant upcall, make + // sure we are the POA related to the non-servant upcall. + TAO::Portable_Server::Non_Servant_Upcall *non_servant_upcall_in_progress = + this->object_adapter ().non_servant_upcall_in_progress (); + if (this->outstanding_requests_ == 0 && + (non_servant_upcall_in_progress == 0 || + &non_servant_upcall_in_progress->poa () != this)) + { + TAO::ORT_Array my_array_obj_ref_template; + + TAO::ORT_Adapter * const ort_adapter = + this->ORT_adapter_i (); + + // In case no ORT library is linked we get zero. + if (ort_adapter != 0) + { + // Get the ObjectReferenceTemplate. + PortableInterceptor::ObjectReferenceTemplate * const ort = + ort_adapter->get_adapter_template (); + + // Add it to the sequence of object reference templates, we + // just notify for ourselves that we are now non_existent, + // our childs will do it for themselves. + my_array_obj_ref_template.size (1); + my_array_obj_ref_template[0] = ort; + } + + // According to the ORT spec, after a POA is destroyed, its state + // has to be changed to NON_EXISTENT and all the registered + // interceptors are to be informed. Since, the POA is destroyed + // and is released in the complete_destruction_i method, we are + // trying to keep the poa still around by doing a duplicate of + // it. (a hack). + PortableServer::POA_var poa = PortableServer::POA::_duplicate (this); + + this->complete_destruction_i (); + + this->adapter_state_ = PortableInterceptor::NON_EXISTENT; + + this->adapter_state_changed (my_array_obj_ref_template, + this->adapter_state_); + + if (ort_adapter != 0) + { + ort_adapter->release (my_array_obj_ref_template[0]); + + TAO::ORT_Adapter_Factory *ort_factory = + this->ORT_adapter_factory (); + + ort_factory->destroy (ort_adapter); + + this->ort_adapter_ = 0; + } + } + else + { + // Mark that we are ready for destruction. + this->waiting_destruction_ = true; + } +} + +int +TAO_Root_POA::delete_child (const TAO_Root_POA::String &child) +{ + int result = 0; + + // If we are not closing down, we must remove this child from our + // collection. + if (!this->cleanup_in_progress_) + result = this->children_.unbind (child); + + // Otherwise, if we are closing down, we are currently iterating + // over our children and there is not need to remove this child from + // our collection. + + return result; +} + +PortableServer::POAList * +TAO_Root_POA::the_children_i (void) +{ + PortableServer::POAList_var children; + CORBA::ULong child_current = static_cast <CORBA::ULong> + (this->children_.current_size ()); + ACE_NEW_THROW_EX (children, + PortableServer::POAList (child_current), + CORBA::NO_MEMORY ()); + + children->length (child_current); + + CORBA::ULong index = 0; + for (CHILDREN::iterator iterator = this->children_.begin (); + iterator != this->children_.end (); + ++iterator, ++index) + { + TAO_Root_POA *child_poa = (*iterator).int_id_; + children[index] = PortableServer::POA::_duplicate (child_poa); + } + + return children._retn (); +} + +PortableInterceptor::AdapterName * +TAO_Root_POA::adapter_name_i (void) +{ + // The adapter name is the sequence of names starting from the + // RootPOA to the one whose name is requested. The name of the + // RootPOA is "RootPOA". + + PortableServer::POA_var poa = PortableServer::POA::_duplicate (this); + + CORBA::ULong len = 0; + + // Find the length of the adapter name sequence by traversing the + // POA hierarchy until the RootPOA is reached. The RootPOA has no + // parent. + while (!CORBA::is_nil (poa.in ())) + { + poa = poa->the_parent (); + ++len; + } + + // Empty adapter name sequence. + PortableInterceptor::AdapterName *names = 0; + ACE_NEW_THROW_EX (names, + PortableInterceptor::AdapterName (len), + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO::VMCID, + ENOMEM), + CORBA::COMPLETED_NO)); + + PortableInterceptor::AdapterName_var safe_names (names); + + names->length (len); + + poa = PortableServer::POA::_duplicate (this); + + (*names)[0] = CORBA::string_dup ("RootPOA"); + + // Fill in the AdapterName sequence as the POA hierarchy is + // traversed. + CORBA::ULong ilen = len; + for (CORBA::ULong i = 1; i < len; ++i) + { + (*names)[--ilen] = poa->the_name (); + + poa = poa->the_parent (); + + // If this condition asserts, the POA hierarchy was modified + // (i.e. reduced in size) by another thread! + ACE_ASSERT ((ilen > 0 ? !CORBA::is_nil (poa.in ()) : 1)); + } + + return safe_names._retn (); +} + +void +TAO_Root_POA::add_ior_component (TAO_MProfile & mprofile, + const IOP::TaggedComponent &component) +{ + // Add the given tagged component to all profiles. + const CORBA::ULong profile_count = mprofile.profile_count (); + + for (CORBA::ULong i = 0; i < profile_count; ++i) + { + TAO_Profile *profile = mprofile.get_profile (i); + + profile->add_tagged_component (component); + } +} + +void +TAO_Root_POA::add_ior_component_to_profile ( + TAO_MProfile & mprofile, + const IOP::TaggedComponent &component, + IOP::ProfileId profile_id) +{ + // Add the given tagged component to all profiles matching the given + // ProfileId. + bool found_profile = false; + + CORBA::ULong const profile_count = mprofile.profile_count (); + + for (CORBA::ULong i = 0; i < profile_count; ++i) + { + TAO_Profile *profile = mprofile.get_profile (i); + + if (profile->tag () == profile_id) + { + profile->add_tagged_component (component); + + found_profile = true; + } + } + + // According to the Portable Interceptor specification, we're + // supposed to throw a CORBA::BAD_PARAM exception if no profile + // matched the given ProfileId. + if (found_profile == false) + throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 29, CORBA::COMPLETED_NO); +} + +void +TAO_Root_POA::adapter_state_changed ( + const TAO::ORT_Array &array_obj_ref_template, + PortableInterceptor::AdapterState state) +{ + TAO_IORInterceptor_Adapter *ior_adapter = + this->orb_core_.ior_interceptor_adapter (); + + if (ior_adapter) + { + ior_adapter->adapter_state_changed (array_obj_ref_template, state); + } +} + +PortableServer::ObjectId * +TAO_Root_POA::activate_object_i (PortableServer::Servant servant, + CORBA::Short priority, + bool &wait_occurred_restart_call) +{ + return this->active_policy_strategies_.servant_retention_strategy()-> + activate_object (servant, + priority, + wait_occurred_restart_call); +} + +PortableServer::ObjectId * +TAO_Root_POA::activate_object (PortableServer::Servant servant) +{ + while (1) + { + bool wait_occurred_restart_call = false; + + // Lock access for the duration of this transaction. + TAO_POA_GUARD_RETURN (0); + + PortableServer::ObjectId *result = + this->activate_object_i (servant, + this->server_priority (), + wait_occurred_restart_call); + + // If we ended up waiting on a condition variable, the POA state + // may have changed while we are waiting. Therefore, we need to + // restart this call. + if (wait_occurred_restart_call) + continue; + else + return result; + } +} + +void +TAO_Root_POA::activate_object_with_id (const PortableServer::ObjectId &id, + PortableServer::Servant servant) +{ + while (1) + { + bool wait_occurred_restart_call = false; + + // Lock access for the duration of this transaction. + TAO_POA_GUARD; + + this->activate_object_with_id_i (id, + servant, + this->server_priority (), + wait_occurred_restart_call); + + // If we ended up waiting on a condition variable, the POA state + // may have changed while we are waiting. Therefore, we need to + // restart this call. + if (wait_occurred_restart_call) + continue; + else + return; + } +} + +void +TAO_Root_POA::activate_object_with_id_i (const PortableServer::ObjectId &id, + PortableServer::Servant servant, + CORBA::Short priority, + bool &wait_occurred_restart_call) +{ + this->active_policy_strategies_.servant_retention_strategy()-> + activate_object_with_id (id, + servant, + priority, + wait_occurred_restart_call); +} + +void +TAO_Root_POA::deactivate_all_objects_i (CORBA::Boolean etherealize_objects, + CORBA::Boolean wait_for_completion) +{ + this->deactivate_all_objects_i (etherealize_objects); + + this->wait_for_completions (wait_for_completion); +} + +void +TAO_Root_POA::wait_for_completions (CORBA::Boolean wait_for_completion) +{ + while (this->object_adapter ().enable_locking_ && + wait_for_completion && + this->outstanding_requests_ > 0) + { + this->wait_for_completion_pending_ = 1; + + int result = this->outstanding_requests_condition_.wait (); + if (result == -1) + { + throw ::CORBA::OBJ_ADAPTER (); + } + } +} + +/* static */ +void +TAO_Root_POA::check_for_valid_wait_for_completions (const TAO_ORB_Core &orb_core, + CORBA::Boolean wait_for_completion) +{ + if (wait_for_completion) + { + TAO::Portable_Server::POA_Current_Impl *poa_current_impl = + static_cast <TAO::Portable_Server::POA_Current_Impl *> + (TAO_TSS_Resources::instance ()->poa_current_impl_); + + while (1) + { + // If wait_for_completion is TRUE and the current thread is + // in an invocation context dispatched from some POA + // belonging to the same ORB as this POA, the BAD_INV_ORDER + // system exception with standard minor code 3 is raised and + // POA destruction does not occur. + if ((poa_current_impl != 0) && (poa_current_impl->poa () != 0)) + { + if (&orb_core == &poa_current_impl->orb_core ()) + { + // CORBA 2.3 specifies which minor code corresponds + // to this particular problem. + throw ::CORBA::BAD_INV_ORDER (CORBA::OMGVMCID | 3, + CORBA::COMPLETED_NO); + } + } + else + break; + + poa_current_impl = + poa_current_impl->previous_current_impl_; + } + } +} + +void +TAO_Root_POA::deactivate_all_objects_i (CORBA::Boolean etherealize_objects) +{ + this->active_policy_strategies_.request_processing_strategy ()-> + etherealize_objects (etherealize_objects); + + this->active_policy_strategies_.servant_retention_strategy ()-> + deactivate_all_objects (); +} + +void +TAO_Root_POA::deactivate_object (const PortableServer::ObjectId &oid) +{ + // Lock access for the duration of this transaction. + TAO_POA_GUARD; + + this->deactivate_object_i (oid); +} + +void +TAO_Root_POA::deactivate_object_i (const PortableServer::ObjectId &id) +{ + this->active_policy_strategies_.servant_retention_strategy()-> + deactivate_object (id); +} + +CORBA::Boolean +TAO_Root_POA::is_persistent (void) const +{ + return active_policy_strategies_.lifespan_strategy()->is_persistent (); +} + +CORBA::Object_ptr +TAO_Root_POA::create_reference (const char *intf) +{ + // Lock access for the duration of this transaction. + TAO_POA_GUARD_RETURN (CORBA::Object::_nil ()); + + return this->create_reference_i (intf, + this->server_priority ()); +} + +CORBA::Object_ptr +TAO_Root_POA::create_reference_i (const char *intf, + CORBA::Short priority) +{ + if (!this->has_system_id ()) + { + throw PortableServer::POA::WrongPolicy (); + } + + return this->active_policy_strategies_.servant_retention_strategy()-> + create_reference (intf, priority); +} + +CORBA::Object_ptr +TAO_Root_POA::invoke_key_to_object_helper_i (const char * repository_id, + const PortableServer::ObjectId & id) +{ + const PortableInterceptor::ObjectId &user_oid = + reinterpret_cast <const PortableInterceptor::ObjectId &>(id); + + // Ask the ORT to create the object. + if (this->ORT_adapter_i ()) + { + // Ask the ORT to create the object. + return this->ort_adapter_->make_object (repository_id, + user_oid); + } + else + { + return this->invoke_key_to_object (); + } +} + +#if ! defined (CORBA_E_MICRO) +CORBA::Object_ptr +TAO_Root_POA::create_reference_with_id_i (const PortableServer::ObjectId &user_id, + const char *intf, + CORBA::Short priority) +{ + // If the POA has the SYSTEM_ID policy and it detects that the + // Object Id value was not generated by the system or for this POA, + // the create_reference_with_id operation may raise the BAD_PARAM + // system exception. An ORB is not required to detect all such + // invalid Object Id values, but a portable application must not + // invoke this operation on a POA that has the SYSTEM_ID policy with + // an Object Id value that was not previously generated by the + // system for that POA, or, if the POA also has the PERSISTENT + // policy, for a previous instantiation of the same POA. + if (this->has_system_id () && + !this->is_poa_generated_id (user_id)) + { + throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 14, CORBA::COMPLETED_NO); + } + + return this->active_policy_strategies_.servant_retention_strategy()-> + create_reference_with_id (user_id, intf, priority); +} +#endif + +PortableServer::ObjectId * +TAO_Root_POA::servant_to_id_i (PortableServer::Servant servant) +{ + return this->active_policy_strategies_.request_processing_strategy()-> + servant_to_id (servant); +} + +CORBA::Object_ptr +TAO_Root_POA::servant_to_reference_i (PortableServer::Servant servant) +{ + return this->active_policy_strategies_.servant_retention_strategy()-> + servant_to_reference (servant); +} + +PortableServer::Servant +TAO_Root_POA::reference_to_servant_i (CORBA::Object_ptr reference) +{ + // Make sure that the reference is valid. + if (CORBA::is_nil (reference)) + { + throw ::CORBA::BAD_PARAM (); + } + + PortableServer::ObjectId system_id; + bool const is_generated = + this->is_poa_generated (reference, system_id); + + if (!is_generated) + { + // In case this object reference is not generated by this POA throw + // an exception + throw PortableServer::POA::WrongAdapter (); + } + + PortableServer::Servant servant = + this->active_policy_strategies_.request_processing_strategy()-> + system_id_to_servant (system_id); + + if (servant != 0) + { + // ATTENTION: Trick locking here, see class header for details + TAO::Portable_Server::Non_Servant_Upcall non_servant_upcall (*this); + ACE_UNUSED_ARG (non_servant_upcall); + + // The POA invokes _add_ref once on the Servant before returning + // it. If the application uses reference counting, the caller of + // id_to_servant is responsible for invoking _remove_ref once on + // the returned Servant when it is finished with it. A + // conforming caller need not invoke _remove_ref on the returned + // Servant if the type of the Servant uses the default reference + // counting inherited from ServantBase. + servant->_add_ref (); + } + + return servant; +} + +bool +TAO_Root_POA::is_poa_generated (CORBA::Object_ptr reference, + PortableServer::ObjectId &system_id) +{ + TAO::ObjectKey_var key = reference->_key (); + + TAO_Object_Adapter::poa_name poa_system_name; + CORBA::Boolean is_root = false; + CORBA::Boolean is_persistent = false; + CORBA::Boolean is_system_id = false; + TAO::Portable_Server::Temporary_Creation_Time poa_creation_time; + + int const result = this->parse_key (key.in (), + poa_system_name, + system_id, + is_root, + is_persistent, + is_system_id, + poa_creation_time); + if (result != 0 + || (this->root () == 0 && poa_system_name != this->system_name ()) + || is_root != this->root () + || is_system_id != this->system_id () + || !this->validate_lifespan (is_persistent, poa_creation_time)) + { + // The passed reference is NOT generated by this POA. + return false; + } + else + { + // The passed reference is generated by this POA. + return true; + } +} + +PortableServer::ObjectId * +TAO_Root_POA::reference_to_id (CORBA::Object_ptr reference) +{ + // Make sure that the reference is valid. + if (CORBA::is_nil (reference)) + { + throw ::CORBA::BAD_PARAM (); + } + + // The WrongPolicy exception is declared to allow future extensions. + + // This operation is valid only if the reference was created by the + // POA on which the operation is being performed. If the object + // reference was not created by this POA, the WrongAdapter exception + // is raised. + PortableServer::ObjectId system_id; + bool const is_generated = this->is_poa_generated (reference, system_id); + + if (!is_generated) + { + throw PortableServer::POA::WrongAdapter (); + } + + // Lock access for the duration of this transaction. + TAO_POA_GUARD_RETURN (0); + + return this->active_policy_strategies_.servant_retention_strategy()-> + system_id_to_object_id (system_id); +} + +PortableServer::Servant +TAO_Root_POA::find_servant (const PortableServer::ObjectId &system_id) +{ + return this->active_policy_strategies_.servant_retention_strategy()-> + find_servant (system_id); +} + +int +TAO_Root_POA::unbind_using_user_id (const PortableServer::ObjectId &user_id) +{ + return this->active_policy_strategies_.servant_retention_strategy()-> + unbind_using_user_id (user_id); +} + +void +TAO_Root_POA::cleanup_servant ( + PortableServer::Servant servant, + const PortableServer::ObjectId &user_id) +{ + this->active_policy_strategies_.request_processing_strategy()-> + cleanup_servant (servant, user_id); +} + +PortableServer::Servant +TAO_Root_POA::id_to_servant_i (const PortableServer::ObjectId &id) +{ + + PortableServer::Servant servant = + this->active_policy_strategies_.request_processing_strategy()-> + id_to_servant (id); + + if (servant != 0) + { + // ATTENTION: Trick locking here, see class header for details + TAO::Portable_Server::Non_Servant_Upcall non_servant_upcall (*this); + ACE_UNUSED_ARG (non_servant_upcall); + + // The POA invokes _add_ref once on the Servant before returning + // it. If the application uses reference counting, the caller of + // id_to_servant is responsible for invoking _remove_ref once on + // the returned Servant when it is finished with it. A + // conforming caller need not invoke _remove_ref on the returned + // Servant if the type of the Servant uses the default reference + // counting inherited from ServantBase. + servant->_add_ref (); + } + + return servant; +} + +PortableServer::Servant +TAO_Root_POA::user_id_to_servant_i (const PortableServer::ObjectId &id) +{ + return this->active_policy_strategies_.servant_retention_strategy()-> + user_id_to_servant (id); +} + +CORBA::Object_ptr +TAO_Root_POA::id_to_reference_i (const PortableServer::ObjectId &id, + bool indirect) +{ + return this->active_policy_strategies_.servant_retention_strategy()-> + id_to_reference (id, indirect); +} + +CORBA::OctetSeq * +TAO_Root_POA::id (void) +{ + CORBA::OctetSeq *id = 0; + ACE_NEW_THROW_EX (id, + CORBA::OctetSeq (this->id_), + CORBA::NO_MEMORY ()); + + return id; +} + +PortableServer::Servant +TAO_Root_POA::locate_servant_i (const char *operation, + const PortableServer::ObjectId &system_id, + TAO::Portable_Server::Servant_Upcall &servant_upcall, + TAO::Portable_Server::POA_Current_Impl &poa_current_impl, + bool &wait_occurred_restart_call) +{ + return this->active_policy_strategies_.request_processing_strategy()-> + locate_servant (operation, + system_id, + servant_upcall, + poa_current_impl, + wait_occurred_restart_call); +} + +/* static */ +int +TAO_Root_POA::parse_key (const TAO::ObjectKey &key, + TAO_Object_Adapter::poa_name &poa_system_name, + PortableServer::ObjectId &system_id, + CORBA::Boolean &is_root, + CORBA::Boolean &is_persistent, + CORBA::Boolean &is_system_id, + TAO::Portable_Server::Temporary_Creation_Time &poa_creation_time) +{ + // Get the object key octets. + const CORBA::Octet *key_data = key.get_buffer (); + + // Skip the object key prefix since we have already checked for this. + CORBA::ULong starting_at = TAO_OBJECTKEY_PREFIX_SIZE; + + // Check the root indicator. + char root_key_type = key_data[starting_at]; + if (root_key_type == TAO_Root_POA::root_key_char ()) + { + is_root = true; + } + else if (root_key_type == TAO_Root_POA::non_root_key_char ()) + { + is_root = false; + } + else + { + // Incorrect key + return -1; + } + + // Skip past the system id indicator + starting_at += TAO_Root_POA::root_key_type_length (); + + // Check the system id indicator. + char system_id_key_type = key_data[starting_at]; + if (system_id_key_type == TAO_Root_POA::system_id_key_char ()) + { + is_system_id = true; + } + else if (system_id_key_type == TAO_Root_POA::user_id_key_char ()) + { + is_system_id = false; + } + else + { + // Incorrect key + return -1; + } + + // Skip past the system id indicator + starting_at += TAO_Root_POA::system_id_key_type_length (); + + // Check the persistence indicator + char persistent_key_type = key_data[starting_at]; + if (persistent_key_type == TAO_Root_POA::persistent_key_char ()) + { + is_persistent = true; + } + else if (persistent_key_type == TAO_Root_POA::transient_key_char ()) + { + is_persistent = false; + } + else + { + // Incorrect key + return -1; + } + + // Skip past the persistent indicator + starting_at += TAO_Root_POA::persistent_key_type_length (); + +#if (POA_NO_TIMESTAMP == 0) + // Grab the timestamp for transient POAs. + if (!is_persistent) + { + // Take the creation time for the timestamp + poa_creation_time.creation_time (key_data + starting_at); + + // Skip past the timestamp + starting_at += TAO::Portable_Server::Creation_Time::creation_time_length (); + } +#else + ACE_UNUSED_ARG (poa_creation_time); +#endif /* POA_NO_TIMESTAMP */ + + // Calculate the size of the POA name. + CORBA::ULong poa_name_size = 0; + if (!is_persistent) + { + // Transient POAs have fixed size. + poa_name_size = TAO_Object_Adapter::transient_poa_name_size (); + } + else if (is_system_id) + { + // System ids have fixed size. + poa_name_size = static_cast <CORBA::ULong> + (key.length () - starting_at - + TAO_Active_Object_Map::system_id_size ()); + } + else + { + // Get the size from the object key. + ACE_OS::memcpy (&poa_name_size, + key_data + starting_at, + sizeof (poa_name_size)); + poa_name_size = ACE_NTOHL (poa_name_size); + + starting_at += sizeof (poa_name_size); + } + + // Grep the name if there is a name + if (!is_root) + { + poa_system_name.replace (poa_name_size, + poa_name_size, + (CORBA::Octet *) key_data + starting_at, + 0); + + starting_at += poa_name_size; + } + + // The rest is the system id. + CORBA::ULong system_id_size = key.length () - starting_at; + + // Reset <system_id>. + system_id.length (system_id_size); + CORBA::Octet * buf = system_id.get_buffer (); + ACE_OS::memcpy (buf, key_data + starting_at, system_id_size); + + // Success + return 0; +} + +TAO::ObjectKey * +TAO_Root_POA::create_object_key (const PortableServer::ObjectId &id) +{ + // Calculate the space required for the key. + CORBA::ULong buffer_size = + this->id_.length () + + id.length (); + + // Create the buffer for the key. + CORBA::Octet *buffer = TAO::ObjectKey::allocbuf (buffer_size); + + // First copy the POA id into the key. + ACE_OS::memcpy (&buffer[0], + this->id_.get_buffer (), + this->id_.length ()); + + // Then copy the object id into the key. + ACE_OS::memcpy (&buffer[this->id_.length ()], + id.get_buffer (), + id.length ()); + + // Create the key, giving the ownership of the buffer to the + // sequence. + TAO::ObjectKey *key = 0; + ACE_NEW_RETURN (key, + TAO::ObjectKey (buffer_size, + buffer_size, + buffer, + 1), + 0); + + return key; +} + +void +TAO_Root_POA::set_id (TAO_Root_POA *parent) +{ + // Calculate the prefix size. + CORBA::ULong prefix_size = 0; + prefix_size += TAO_OBJECTKEY_PREFIX_SIZE; + + // If we are dealing with a persistent POA and user ids are being + // used, then we need to add the POA name length field to the object + // key. Otherwise, the POA name length can be calculated by looking + // at the remainder after extracting other parts of the key. + bool const add_poa_name_length = + this->is_persistent () && + !this->system_id (); + + // Size required by the POA name. + CORBA::ULong poa_name = 0; + + // Calculate the space required for the POA name. + CORBA::ULong poa_name_length = this->system_name_->length (); + if (parent != 0) + { + poa_name += poa_name_length; + } + + // Check if we need to added the length of the POA name. + if (add_poa_name_length) + { + poa_name += sizeof (poa_name_length); + } + + // Get the space needed for the lifespan length + // byte. + CORBA::ULong const lifespan_key_length = + this->active_policy_strategies_.lifespan_strategy()->key_length (); + + CORBA::ULong const id_assignment_key_length = + this->active_policy_strategies_.id_assignment_strategy()->key_type_length (); + + // Calculate the space required for the POA id. + CORBA::ULong const buffer_size = + prefix_size + + this->root_key_type_length () + + id_assignment_key_length + + lifespan_key_length + + poa_name; + + // Create the buffer for the POA id. + this->id_.length (buffer_size); + CORBA::Octet *buffer = &this->id_[0]; + + // Keeps track of where the next infomation goes; start at 0 byte. + CORBA::ULong starting_at = 0; + + // Add the object key prefix. + ACE_OS::memcpy (&buffer[starting_at], + &objectkey_prefix[0], + TAO_OBJECTKEY_PREFIX_SIZE); + + starting_at += TAO_OBJECTKEY_PREFIX_SIZE; + + // Copy the root byte. + if (parent != 0) + { + buffer[starting_at] = (CORBA::Octet) TAO_Root_POA::non_root_key_char (); + } + else + { + buffer[starting_at] = (CORBA::Octet) TAO_Root_POA::root_key_char (); + } + starting_at += this->root_key_type_length (); + + // Add the id_assignment part + this->active_policy_strategies_.id_assignment_strategy()->create_key (buffer, starting_at); + + // Add the lifespan part + this->active_policy_strategies_.lifespan_strategy()->create_key (buffer, starting_at); + + // Check if we need to added the length of the POA name. + if (add_poa_name_length) + { + poa_name_length = ACE_HTONL (poa_name_length); + ACE_OS::memcpy (&buffer[starting_at], + &poa_name_length, + sizeof (poa_name_length)); + starting_at += sizeof (poa_name_length); + } + + // Put the POA name into the key (for non-root POAs). + if (parent != 0) + { + ACE_OS::memcpy (&buffer[starting_at], + this->system_name_->get_buffer (), + this->system_name_->length ()); + starting_at += this->system_name_->length (); + } +} + +int +TAO_Root_POA::is_poa_generated_id (const PortableServer::ObjectId &id) +{ +#if defined (POA_NAME_IN_POA_GENERATED_ID) + + // Grab the buffer + const char *id_buffer = (const char *) id.get_buffer (); + + // Check to see if the POA name is the first part of the id + return + this->name_.length () < id.length () && + ACE_OS::strncmp (id_buffer, + this->name_.c_str (), + this->name_.length ()) == 0; +#else /* POA_NAME_IN_POA_GENERATED_ID */ + + ACE_UNUSED_ARG (id); + return 1; + +#endif /* POA_NAME_IN_POA_GENERATED_ID */ +} + +void +TAO_Root_POA::set_folded_name (TAO_Root_POA *parent) +{ + size_t length = 0; + size_t parent_length = 0; + + if (parent != 0) + { + parent_length = parent->folded_name ().length (); + length += parent_length; + } + + length += this->name_.length (); + length += TAO_Root_POA::name_separator_length (); + + this->folded_name_.length (static_cast <CORBA::ULong> (length)); + CORBA::Octet *folded_name_buffer = this->folded_name_.get_buffer (); + + if (parent != 0) + { + ACE_OS::memcpy (folded_name_buffer, + parent->folded_name ().get_buffer (), + parent_length); + } + + ACE_OS::memcpy (&folded_name_buffer[parent_length], + this->name_.c_str (), + this->name_.length ()); + + folded_name_buffer[length - TAO_Root_POA::name_separator_length ()] = TAO_Root_POA::name_separator (); +} + +int +TAO_Root_POA::parse_ir_object_key (const TAO::ObjectKey &object_key, + PortableServer::ObjectId &user_id) +{ + TAO_Object_Adapter::poa_name poa_system_name; + CORBA::Boolean is_root = false; + CORBA::Boolean is_persistent = false; + CORBA::Boolean is_system_id = false; + TAO::Portable_Server::Temporary_Creation_Time poa_creation_time; + + return TAO_Root_POA::parse_key (object_key, + poa_system_name, + user_id, + is_root, + is_persistent, + is_system_id, + poa_creation_time); +} + +TAO_Object_Adapter & +TAO_Root_POA::object_adapter (void) +{ + return *this->object_adapter_; +} + +CORBA::Object_ptr +TAO_Root_POA::invoke_key_to_object (void) +{ + PortableServer::ObjectId_var &system_id = + *this->key_to_object_params_.system_id_; + + // Create object key. + TAO::ObjectKey_var key = + this->create_object_key (system_id.in ()); + + return this->key_to_object (key.in (), + this->key_to_object_params_.type_id_, + this->key_to_object_params_.servant_, + this->key_to_object_params_.collocated_, + this->key_to_object_params_.priority_, + this->key_to_object_params_.indirect_); +} + +CORBA::Object_ptr +TAO_Root_POA::key_to_object (const TAO::ObjectKey &key, + const char *type_id, + TAO_ServantBase *servant, + CORBA::Boolean collocated, + CORBA::Short priority, + bool indirect) +{ + // Check if the ORB is still running, otherwise throw an exception. + // @@ What if the ORB was destroyed? In that case we shouldn't even + // get here! + this->orb_core_.check_shutdown (); + + // + // ImplRepo related. + // +#if (TAO_HAS_MINIMUM_CORBA == 0) + + CORBA::Object_ptr obj = CORBA::Object::_nil (); + + if (indirect && this->active_policy_strategies_.lifespan_strategy()->use_imr () + && this->orb_core ().imr_endpoints_in_ior ()) + { + // Check to see if we alter the IOR. + CORBA::Object_var imr = this->orb_core ().implrepo_service (); + + if (CORBA::is_nil (imr.in ()) + || !imr->_stubobj () + || !imr->_stubobj ()->profile_in_use ()) + { + if (TAO_debug_level > 1) + { + ACE_DEBUG ((LM_DEBUG, + "Missing ImR IOR, will not use the ImR\n")); + } + goto orbkey; + } + + CORBA::String_var imr_str = + imr->_stubobj ()->profile_in_use ()->to_string (); + + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "IMR IOR =\n%C\n", + imr_str.in ())); + + // Search for "corbaloc:" alone, without the protocol. This code + // should be protocol neutral. + const char corbaloc[] = "corbaloc:"; + char *pos = ACE_OS::strstr (imr_str.inout (), corbaloc); + pos = ACE_OS::strchr (pos + sizeof (corbaloc), ':'); + + pos = ACE_OS::strchr (pos + 1, + imr->_stubobj ()->profile_in_use ()->object_key_delimiter ()); + + if (pos) + pos[1] = 0; // Crop the string. + else + { + if (TAO_debug_level > 0) + ACE_ERROR ((LM_ERROR, + "Could not parse ImR IOR, skipping ImRification\n")); + goto orbkey; + } + + ACE_CString ior (imr_str.in ()); + + // Add the key. + + CORBA::String_var key_str; + TAO::ObjectKey::encode_sequence_to_string (key_str.inout (), key); + + ior += key_str.in (); + + if (TAO_debug_level > 0) + ACE_DEBUG ((LM_DEBUG, + "ImR-ified IOR =\n%C\n", + ior.c_str ())); + + obj = this->orb_core_.orb ()->string_to_object (ior.c_str ()); + + return obj; + } + +orbkey: + +#else + ACE_UNUSED_ARG (indirect); +#endif /* TAO_HAS_MINIMUM_CORBA */ + + TAO_Stub *data = this->key_to_stub_i (key, type_id, priority); + + TAO_Stub_Auto_Ptr safe_data (data); + + CORBA::Object_ptr tmp; + + if (this->orb_core_.optimize_collocation_objects ()) + { + ACE_NEW_THROW_EX (tmp, CORBA::Object (data, + collocated, + servant), + CORBA::INTERNAL ()); + + } + else + { + ACE_NEW_THROW_EX (tmp, + CORBA::Object (data, + collocated), + CORBA::INTERNAL ()); + } + + data->servant_orb (this->orb_core_.orb ()); + + // Transfer ownership to the Object. + (void) safe_data.release (); + + return tmp; +} + +TAO_Stub * +TAO_Root_POA::key_to_stub (const TAO::ObjectKey &key, + const char *type_id, + CORBA::Short priority) +{ + // Check if the ORB is still running, otherwise throw an exception. + // @@ What if the ORB was destroyed? In that case we shouldn't even + // get here! + this->orb_core_.check_shutdown (); + + return this->key_to_stub_i (key, type_id, priority); +} + +TAO_Stub * +TAO_Root_POA::key_to_stub_i (const TAO::ObjectKey &key, + const char *type_id, + CORBA::Short priority) +{ + CORBA::PolicyList_var client_exposed_policies = + this->client_exposed_policies (priority); + + TAO_Acceptor_Filter* filter = 0; + +#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) + if (this->filter_factory_) + { + filter = this->filter_factory_->create_object (this->poa_manager_); + } + else +#endif + { + ACE_NEW_RETURN (filter, + TAO_Default_Acceptor_Filter (), + 0); + } + + // Give ownership to the auto pointer. + auto_ptr<TAO_Acceptor_Filter> new_filter (filter); + + TAO_Stub *data = + this->create_stub_object ( + key, + type_id, + client_exposed_policies._retn (), + filter, + this->orb_core_.lane_resources ().acceptor_registry ()); + + return data; +} + +void +TAO_Root_POA::establish_components (void) +{ + TAO_IORInterceptor_Adapter *ior_adapter = + this->orb_core_.ior_interceptor_adapter (); + + if (ior_adapter) + { + ior_adapter->establish_components (this); + } +} + +void +TAO_Root_POA::components_established (PortableInterceptor::IORInfo_ptr info) +{ + TAO_IORInterceptor_Adapter *ior_adapter = + this->orb_core_.ior_interceptor_adapter (); + + if (ior_adapter) + { + ior_adapter->components_established (info); + } +} + +void +TAO_Root_POA::save_ior_component (const IOP::TaggedComponent &component) +{ + CORBA::ULong const old_len = this->tagged_component_.length (); + + this->tagged_component_.length (old_len + 1); + this->tagged_component_[old_len] = component; +} + +void +TAO_Root_POA:: +save_ior_component_and_profile_id (const IOP::TaggedComponent &component, + IOP::ProfileId profile_id) +{ + // The length of this->tagged_component_id_ is the same as the + // length of the profile_id_array_ since we are trying to make a + // one-to-one link between these two arrays. So, whenever + // this->tagged_component_id_ is increased, we need to increase the + // size of this->profile_id_array_ also. + + CORBA::ULong const old_len = this->tagged_component_id_.length (); + + CORBA::ULong const new_len = old_len + 1; + + this->tagged_component_id_.length (new_len); + this->tagged_component_id_[old_len] = component; + + this->profile_id_array_.size (new_len); + this->profile_id_array_[old_len] = profile_id; +} + +TAO_Stub * +TAO_Root_POA::create_stub_object (const TAO::ObjectKey &object_key, + const char *type_id, + CORBA::PolicyList *policy_list, + TAO_Acceptor_Filter *filter, + TAO_Acceptor_Registry &acceptor_registry) +{ + bool error = false; + + // Count the number of endpoints. + size_t const profile_count = acceptor_registry.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 = true; + + if (!error) + { + result = + filter->fill_profile (object_key, + mprofile, + acceptor_registry.begin (), + acceptor_registry.end ()); + if (result == -1) + error = true; + } + + if (!error) + result = filter->encode_endpoints (mprofile); + + if (result == -1) + error = true; + + 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); + + TAO_Stub *stub = + this->orb_core_.create_stub_object (mprofile, type_id, policy_list); + + // Add the saved tagged components methods to the profiles. + CORBA::ULong len = this->tagged_component_.length (); + for (CORBA::ULong i = 0; i != len; ++i) + { + this->add_ior_component (mprofile, this->tagged_component_[i]); + } + + len = this->tagged_component_id_.length (); + + for (CORBA::ULong k = 0; k != len; ++k) + { + this->add_ior_component_to_profile (mprofile, + this->tagged_component_id_[k], + this->profile_id_array_[k]); + } + + return stub; +} + +CORBA::PolicyList * +TAO_Root_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 policies = client_exposed_policies; + + // Add in all of the client exposed policies. + this->policies_.add_client_exposed_fixed_policies (client_exposed_policies); + + return policies._retn (); +} + +TAO_SERVANT_LOCATION +TAO_Root_POA::locate_servant_i (const PortableServer::ObjectId &system_id, + PortableServer::Servant &servant) +{ + return this->active_policy_strategies_.request_processing_strategy()-> + locate_servant (system_id, servant); +} + +TAO_SERVANT_LOCATION +TAO_Root_POA::servant_present (const PortableServer::ObjectId &system_id, + PortableServer::Servant &servant) +{ + return this->active_policy_strategies_.servant_retention_strategy()-> + servant_present (system_id, servant); +} + +PortableServer::Servant +TAO_Root_POA::find_servant ( + const PortableServer::ObjectId &system_id, + TAO::Portable_Server::Servant_Upcall &servant_upcall, + TAO::Portable_Server::POA_Current_Impl &poa_current_impl) +{ + return this->active_policy_strategies_.servant_retention_strategy()-> + find_servant (system_id, + servant_upcall, + poa_current_impl); +} + +int +TAO_Root_POA::find_servant_priority ( + const PortableServer::ObjectId &system_id, + CORBA::Short &priority) +{ + return this->active_policy_strategies_.servant_retention_strategy()-> + find_servant_priority (system_id, priority); +} + +TAO::ORT_Adapter_Factory * +TAO_Root_POA::ORT_adapter_factory (void) +{ + return ACE_Dynamic_Service<TAO::ORT_Adapter_Factory>::instance + (orb_core_.configuration (), + TAO_Root_POA::ort_adapter_factory_name ()); +} + +TAO::ORT_Adapter * +TAO_Root_POA::ORT_adapter_i (void) +{ + if (this->ort_adapter_ != 0) + return this->ort_adapter_; + + try + { + TAO::ORT_Adapter_Factory * ort_ap_factory = this->ORT_adapter_factory (); + + if (!ort_ap_factory) + return 0; + + // Get the full adapter name of this POA, do this before we + // create the adapter so that in case this fails, we just + // return 0 and not a not activated adapter + PortableInterceptor::AdapterName *adapter_name = this->adapter_name_i (); + + this->ort_adapter_ = ort_ap_factory->create (); + + if (!this->ort_adapter_) + return 0; + + // @todo We have to look at this, we activate it but hold the POA lock, + // in case we are called by ORT_adapter, we shouldn't keep the lock + // here, but then the ort_adapter should be guarded against multiple + // activations. + this->ort_adapter_->activate (this->orb_core_.server_id (), + this->orb_core_.orbid (), + adapter_name, + this); + } + catch (const ::CORBA::Exception& ex) + { + ex._tao_print_exception ( + "(%P|%t) Cannot initialize the " + "object_reference_template_adapter\n"); + } + + return this->ort_adapter_; +} + +#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) + +PortableServer::AdapterActivator_ptr +TAO_Root_POA::the_activator (void) +{ + // Lock access for the duration of this transaction. + TAO_POA_GUARD_RETURN (PortableServer::AdapterActivator::_nil ()); + + return PortableServer::AdapterActivator::_duplicate (this->adapter_activator_.in ()); +} + +void +TAO_Root_POA::the_activator (PortableServer::AdapterActivator_ptr adapter_activator) +{ + // Lock access for the duration of this transaction. + TAO_POA_GUARD; + + this->adapter_activator_ = PortableServer::AdapterActivator::_duplicate (adapter_activator); +} + +#endif /* TAO_HAS_MINIMUM_POA == 0 && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)*/ + +#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) + +PortableServer::ServantManager_ptr +TAO_Root_POA::get_servant_manager (void) +{ + // Lock access for the duration of this transaction. + TAO_POA_GUARD_RETURN (PortableServer::ServantManager::_nil ()); + + return this->active_policy_strategies_.request_processing_strategy()-> + get_servant_manager (); +} + +void +TAO_Root_POA::set_servant_manager (PortableServer::ServantManager_ptr imgr) +{ + // Lock access for the duration of this transaction. + TAO_POA_GUARD; + + this->active_policy_strategies_.request_processing_strategy()-> + set_servant_manager (imgr); +} + +PortableServer::Servant +TAO_Root_POA::get_servant_i (void) +{ + return this->active_policy_strategies_.request_processing_strategy()-> + get_servant (); +} + +PortableServer::Servant +TAO_Root_POA::get_servant (void) +{ + // Lock access for the duration of this transaction. + TAO_POA_GUARD_RETURN (0); + + PortableServer::Servant servant = this->get_servant_i (); + + if (servant != 0) + { + // ATTENTION: Trick locking here, see class header for details + TAO::Portable_Server::Non_Servant_Upcall non_servant_upcall (*this); + ACE_UNUSED_ARG (non_servant_upcall); + + // The POA invokes _add_ref once on the Servant before returning + // it. If the application uses reference counting, the caller of + // get_servant is responsible for invoking _remove_ref once on + // the returned Servant when it is finished with it. A + // conforming caller need not invoke _remove_ref on the returned + // Servant if the type of the Servant uses the default reference + // counting inherited from ServantBase. + servant->_add_ref (); + + return servant; + } + else + { + // If no servant has been associated with the POA, the NoServant + // exception is raised. + throw PortableServer::POA::NoServant (); + } +} + +void +TAO_Root_POA::set_servant (PortableServer::Servant servant) +{ + // Lock access for the duration of this transaction. + TAO_POA_GUARD; + + this->active_policy_strategies_.request_processing_strategy()-> + set_servant (servant); +} + +#endif /* TAO_HAS_MINIMUM_POA == 0 && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) */ + +bool +TAO_Root_POA::is_servant_activation_allowed (PortableServer::Servant servant, + bool &wait_occurred_restart_call) +{ + return this->active_policy_strategies_.id_uniqueness_strategy ()-> + is_servant_activation_allowed (servant, wait_occurred_restart_call); +} + +bool +TAO_Root_POA::has_system_id (void) const +{ + return this->active_policy_strategies_.id_assignment_strategy ()-> + has_system_id (); +} + +int +TAO_Root_POA::rebind_using_user_id_and_system_id ( + PortableServer::Servant servant, + const PortableServer::ObjectId &user_id, + const PortableServer::ObjectId &system_id, + TAO::Portable_Server::Servant_Upcall &servant_upcall) +{ + return this->active_policy_strategies_.servant_retention_strategy ()-> + rebind_using_user_id_and_system_id (servant, + user_id, + system_id, + servant_upcall); +} + +CORBA::Boolean +TAO_Root_POA::servant_has_remaining_activations (PortableServer::Servant servant) +{ + return this->active_policy_strategies_.servant_retention_strategy ()-> + servant_has_remaining_activations (servant); +} + +bool +TAO_Root_POA::allow_implicit_activation (void) const +{ + return this->active_policy_strategies_.implicit_activation_strategy ()-> + allow_implicit_activation (); +} + +bool +TAO_Root_POA::allow_multiple_activations (void) const +{ + return this->active_policy_strategies_.id_uniqueness_strategy ()-> + allow_multiple_activations (); +} + +void +TAO_Root_POA::post_invoke_servant_cleanup( + const PortableServer::ObjectId &system_id, + const TAO::Portable_Server::Servant_Upcall &servant_upcall) +{ + this->active_policy_strategies_.request_processing_strategy ()-> + post_invoke_servant_cleanup (system_id, servant_upcall); +} + +CORBA::Short +TAO_Root_POA::server_priority (void) const +{ + return this->cached_policies_.server_priority (); +} + +int +TAO_Root_POA::is_servant_active ( + PortableServer::Servant servant, + bool &wait_occurred_restart_call) +{ + return this->active_policy_strategies_.servant_retention_strategy ()-> + is_servant_in_map (servant, wait_occurred_restart_call); +} + +TAO::Portable_Server::Cached_Policies& +TAO_Root_POA::cached_policies (void) +{ + return this->cached_policies_; +} + +TAO_Network_Priority_Hook* +TAO_Root_POA::network_priority_hook (void) +{ + return this->network_priority_hook_; +} + +TAO::Portable_Server::Cached_Policies::PriorityModel +TAO_Root_POA::priority_model (void) const +{ + return cached_policies_.priority_model (); +} + +#if (TAO_HAS_MINIMUM_POA == 0) +int +TAO_Root_POA::enter () +{ + return this->active_policy_strategies_.thread_strategy ()->enter(); +} +#endif /* TAO_HAS_MINIMUM_POA == 0 */ + +#if (TAO_HAS_MINIMUM_POA == 0) +int +TAO_Root_POA::exit () +{ + return this->active_policy_strategies_.thread_strategy ()->exit(); +} +#endif /* TAO_HAS_MINIMUM_POA == 0 */ + +bool +TAO_Root_POA::validate_lifespan ( + CORBA::Boolean is_persistent, + const TAO::Portable_Server::Temporary_Creation_Time& creation_time) const +{ + return this->active_policy_strategies_.lifespan_strategy()-> + validate (is_persistent, creation_time); +} + +CORBA::Boolean +TAO_Root_POA::root (void) const +{ + return true; +} + +TAO::ORT_Adapter * +TAO_Root_POA::ORT_adapter (void) +{ + if (this->ort_adapter_ != 0) + return this->ort_adapter_; + + // Lock access for the duration of this transaction. + TAO_POA_GUARD_RETURN (0); + + // DCL .. + if (this->ort_adapter_ != 0) + { + return this->ort_adapter_; + } + + return this->ORT_adapter_i (); +} + +CORBA::Policy * +TAO_Root_POA::server_protocol (void) +{ + return 0; +} + +void +TAO_Root_POA::Key_To_Object_Params::set (PortableServer::ObjectId_var &system_id, + const char *type_id, + TAO_ServantBase *servant, + CORBA::Boolean collocated, + CORBA::Short priority, + bool indirect) +{ + this->system_id_ = &system_id; + this->type_id_ = type_id; + this->servant_ = servant; + this->collocated_ = collocated; + this->priority_ = priority; + this->indirect_ = indirect; +} + +CORBA::ULong +TAO_Root_POA::waiting_servant_deactivation (void) const +{ + return this->active_policy_strategies_.servant_retention_strategy ()-> + waiting_servant_deactivation (); +} + +void +TAO_Root_POA::ort_adapter_factory_name (const char *name) +{ + TAO_POA_Static_Resources::instance ()->ort_adapter_factory_name_ = + name; +} + +CORBA::Policy_ptr +TAO_Root_POA::get_policy (CORBA::PolicyType policy) +{ + return this->policies_.get_policy (policy); +} + +void +TAO_Root_POA::check_state (void) +{ + this->active_policy_strategies_.lifespan_strategy ()->check_state (); +} + +const char * +TAO_Root_POA::ort_adapter_factory_name (void) +{ + return TAO_POA_Static_Resources::instance ()->ort_adapter_factory_name_.c_str(); +} + +void +TAO_Root_POA::imr_client_adapter_name (const char *name) +{ + TAO_POA_Static_Resources::instance ()->imr_client_adapter_name_ = name; +} + +const char * +TAO_Root_POA::imr_client_adapter_name (void) +{ + return TAO_POA_Static_Resources::instance ()->imr_client_adapter_name_.c_str(); +} + +PortableServer::POAManager_ptr +TAO_Root_POA::the_POAManager (void) +{ + return PortableServer::POAManager::_duplicate (&this->poa_manager_); +} + +#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) +PortableServer::POAManagerFactory_ptr +TAO_Root_POA::the_POAManagerFactory (void) +{ + return PortableServer::POAManagerFactory::_duplicate (&this->poa_manager_factory_); +} +#endif + +CORBA::ORB_ptr +TAO_Root_POA::_get_orb (void) +{ + return CORBA::ORB::_duplicate (this->orb_core_.orb ()); +} + +// Initialize instance_ to 0, since this is what we test for in the call +// to instance (). Note that this does not require a constructor call, so +// it is always initialized by the time that instance () can be called. +TAO_POA_Static_Resources* TAO_POA_Static_Resources::instance_ = 0; + +// Force an instance to be created at module initialization time, +// since we do not want to worry about double checked locking and +// the race condition to initialize the lock. +TAO_POA_Static_Resources* TAO_POA_Static_Resources::initialization_reference_ = + TAO_POA_Static_Resources::instance (); + +void +TAO_POA_Static_Resources::fini (void) +{ + delete TAO_POA_Static_Resources::instance_; + TAO_POA_Static_Resources::instance_ = 0; +} + +TAO_POA_Static_Resources* +TAO_POA_Static_Resources::instance (void) +{ + if (TAO_POA_Static_Resources::instance_ == 0) + { + // This new is never freed on purpose. The data specified by + // it needs to be around for the last shared library that references + // this class. This could occur in a destructor in a shared library + // that is unloaded after this one. One solution to avoid this + // harmless memory leak would be to use reference counting. + ACE_NEW_RETURN (TAO_POA_Static_Resources::instance_, + TAO_POA_Static_Resources (), + 0); + } + + return TAO_POA_Static_Resources::instance_; +} + +TAO_POA_Static_Resources::TAO_POA_Static_Resources (void) + : ort_adapter_factory_name_ ("ORT_Adapter_Factory"), + imr_client_adapter_name_ ("ImR_Client_Adapter") +{ +} + +void +TAO_Root_POA::poa_activated_hook () +{ +} + +void +TAO_Root_POA::poa_deactivated_hook () +{ +} + +void +TAO_Root_POA::servant_activated_hook (PortableServer::Servant, + const PortableServer::ObjectId&) +{ +} + +void +TAO_Root_POA::servant_deactivated_hook (PortableServer::Servant, + const PortableServer::ObjectId&) +{ +} + +TAO_END_VERSIONED_NAMESPACE_DECL |