diff options
Diffstat (limited to 'TAO/tao/poa.cpp')
-rw-r--r-- | TAO/tao/poa.cpp | 3481 |
1 files changed, 3250 insertions, 231 deletions
diff --git a/TAO/tao/poa.cpp b/TAO/tao/poa.cpp index 4e74e271f8f..1b7bc638f9f 100644 --- a/TAO/tao/poa.cpp +++ b/TAO/tao/poa.cpp @@ -1,361 +1,3380 @@ // @(#) $Id$ -// -// Copyright 1994-1995 by Sun Microsystems Inc. -// All Rights Reserved -// -// POA initialisation -- both anonymous and (for system bootstrapping) -// named POAs. -// -// XXX at this time, there's a strong linkage between this code and -// the modules knowing about IIOP. In the future, a looser coupling -// between OA initialiszation and protocol components is desired. +// CORBA #include "tao/corba.h" -// {A201E4C8-F258-11ce-9598-0000C07CA898} -DEFINE_GUID (IID_POA, -0xa201e4c8, 0xf258, 0x11ce, 0x95, 0x98, 0x0, 0x0, 0xc0, 0x7c, 0xa8, 0x98) ; +// POA +#include "tao/poa.h" -// CORBA_POA::init() is used in get_poa() and get_named_poa() in order -// to initialize the OA. It was originally part of POA, and may no -// longer be useful. +// Exception macros +#include "tao/poa_macros.h" -CORBA::POA_ptr -CORBA_POA::init (CORBA::ORB_ptr parent, - ACE_INET_Addr &, - CORBA::Environment &env) +// auto_ptr class +#include "ace/Auto_Ptr.h" + +// This is the maximum space require to convert the ulong into a string +const int TAO_POA::max_space_required_for_ulong = 24; + +TAO_Thread_Policy::TAO_Thread_Policy (PortableServer::ThreadPolicyValue value) + : value_ (value) +{ +} + +TAO_Thread_Policy::TAO_Thread_Policy (const TAO_Thread_Policy &rhs) + : value_ (rhs.value_) +{ +} + +PortableServer::ThreadPolicyValue +TAO_Thread_Policy::value (CORBA::Environment &env) { - env.clear (); - TAO_ORB_Core *p = TAO_ORB_Core_instance (); + ACE_UNUSED_ARG (env); + return this->value_; +} + +PortableServer::Policy_ptr +TAO_Thread_Policy::copy (CORBA::Environment &env) +{ + auto_ptr<TAO_Thread_Policy> new_policy (new TAO_Thread_Policy (*this)); - if (p->root_poa ()) + PortableServer::Policy_var result = new_policy->_this (env); + if (env.exception () != 0) + return PortableServer::Policy::_nil (); + else { - env.exception (new CORBA_INITIALIZE (CORBA::COMPLETED_NO)); - return 0; + // Make sure that the auto_ptr does not delete the + // implementation object + new_policy.release (); + return result._retn (); } +} - CORBA::POA_ptr rp; - ACE_NEW_RETURN (rp, CORBA_POA (parent, env), 0); - p->root_poa (rp); +void +TAO_Thread_Policy::destroy (CORBA::Environment &env) +{ + ACE_UNUSED_ARG (env); - return rp; + // Commit suicide: must have been dynamically allocated + delete this; } -CORBA_POA::CORBA_POA (CORBA::ORB_ptr owning_orb, - CORBA::Environment &) - : do_exit_ (CORBA::B_FALSE), - orb_ (owning_orb), - call_count_ (0), - skeleton_ (0) +TAO_Lifespan_Policy::TAO_Lifespan_Policy (PortableServer::LifespanPolicyValue value) + : value_ (value) { - TAO_ORB_Core* p = TAO_ORB_Core_instance (); - TAO_Server_Strategy_Factory *f = p->server_factory (); +} - this->objtable_ = f->create_object_table (); +TAO_Lifespan_Policy::TAO_Lifespan_Policy (const TAO_Lifespan_Policy &rhs) + : value_ (rhs.value_) +{ +} - // @@ What is this doing here? Why is it setting the root poa based - // on whether objtable_ is non-zero? (cjc) - if (this->objtable_ != 0) - p->root_poa (this); +PortableServer::LifespanPolicyValue +TAO_Lifespan_Policy::value (CORBA::Environment &env) +{ + ACE_UNUSED_ARG (env); + return this->value_; } -CORBA_POA::~CORBA_POA (void) +PortableServer::Policy_ptr +TAO_Lifespan_Policy::copy (CORBA::Environment &env) { + auto_ptr<TAO_Lifespan_Policy> new_policy (new TAO_Lifespan_Policy (*this)); + + PortableServer::Policy_var result = new_policy->_this (env); + if (env.exception () != 0) + return PortableServer::Policy::_nil (); + else + { + // Make sure that the auto_ptr does not delete the + // implementation object + new_policy.release (); + return result._retn (); + } } -// Create an objref +void +TAO_Lifespan_Policy::destroy (CORBA::Environment &env) +{ + ACE_UNUSED_ARG (env); -CORBA::Object_ptr -CORBA_POA::create (TAO_opaque &key, - CORBA::String type_id, - CORBA::Environment &env) + // Commit suicide: must have been dynamically allocated + delete this; +} + +TAO_Id_Uniqueness_Policy::TAO_Id_Uniqueness_Policy (PortableServer::IdUniquenessPolicyValue value) + : value_ (value) +{ +} + +TAO_Id_Uniqueness_Policy::TAO_Id_Uniqueness_Policy (const TAO_Id_Uniqueness_Policy &rhs) + : value_ (rhs.value_) +{ +} + +PortableServer::IdUniquenessPolicyValue +TAO_Id_Uniqueness_Policy::value (CORBA::Environment &env) +{ + ACE_UNUSED_ARG (env); + return this->value_; +} + +PortableServer::Policy_ptr +TAO_Id_Uniqueness_Policy::copy (CORBA::Environment &env) +{ + auto_ptr<TAO_Id_Uniqueness_Policy> new_policy (new TAO_Id_Uniqueness_Policy (*this)); + + PortableServer::Policy_var result = new_policy->_this (env); + if (env.exception () != 0) + return PortableServer::Policy::_nil (); + else + { + // Make sure that the auto_ptr does not delete the + // implementation object + new_policy.release (); + return result._retn (); + } +} + +void +TAO_Id_Uniqueness_Policy::destroy (CORBA::Environment &env) +{ + ACE_UNUSED_ARG (env); + + // Commit suicide: must have been dynamically allocated + delete this; +} + +TAO_Id_Assignment_Policy::TAO_Id_Assignment_Policy (PortableServer::IdAssignmentPolicyValue value) + : value_ (value) +{ +} + +TAO_Id_Assignment_Policy::TAO_Id_Assignment_Policy (const TAO_Id_Assignment_Policy &rhs) + : value_ (rhs.value_) +{ +} + +PortableServer::IdAssignmentPolicyValue +TAO_Id_Assignment_Policy::value (CORBA::Environment &env) +{ + ACE_UNUSED_ARG (env); + return this->value_; +} + +PortableServer::Policy_ptr +TAO_Id_Assignment_Policy::copy (CORBA::Environment &env) +{ + auto_ptr<TAO_Id_Assignment_Policy> new_policy (new TAO_Id_Assignment_Policy (*this)); + + PortableServer::Policy_var result = new_policy->_this (env); + if (env.exception () != 0) + return PortableServer::Policy::_nil (); + else + { + // Make sure that the auto_ptr does not delete the + // implementation object + new_policy.release (); + return result._retn (); + } +} + +void +TAO_Id_Assignment_Policy::destroy (CORBA::Environment &env) +{ + ACE_UNUSED_ARG (env); + + // Commit suicide: must have been dynamically allocated + delete this; +} + +TAO_Implicit_Activation_Policy::TAO_Implicit_Activation_Policy (PortableServer::ImplicitActivationPolicyValue value) + : value_ (value) +{ +} + +TAO_Implicit_Activation_Policy::TAO_Implicit_Activation_Policy (const TAO_Implicit_Activation_Policy &rhs) + : value_ (rhs.value_) +{ +} + +PortableServer::ImplicitActivationPolicyValue +TAO_Implicit_Activation_Policy::value (CORBA::Environment &env) +{ + ACE_UNUSED_ARG (env); + return this->value_; +} + +PortableServer::Policy_ptr +TAO_Implicit_Activation_Policy::copy (CORBA::Environment &env) +{ + auto_ptr<TAO_Implicit_Activation_Policy> new_policy (new TAO_Implicit_Activation_Policy (*this)); + + PortableServer::Policy_var result = new_policy->_this (env); + if (env.exception () != 0) + return PortableServer::Policy::_nil (); + else + { + // Make sure that the auto_ptr does not delete the + // implementation object + new_policy.release (); + return result._retn (); + } +} + +void +TAO_Implicit_Activation_Policy::destroy (CORBA::Environment &env) +{ + ACE_UNUSED_ARG (env); + + // Commit suicide: must have been dynamically allocated + delete this; +} + +TAO_Servant_Retention_Policy::TAO_Servant_Retention_Policy (PortableServer::ServantRetentionPolicyValue value) + : value_ (value) +{ +} + +TAO_Servant_Retention_Policy::TAO_Servant_Retention_Policy (const TAO_Servant_Retention_Policy &rhs) + : value_ (rhs.value_) +{ +} + +PortableServer::ServantRetentionPolicyValue +TAO_Servant_Retention_Policy::value (CORBA::Environment &env) +{ + ACE_UNUSED_ARG (env); + return this->value_; +} + +PortableServer::Policy_ptr +TAO_Servant_Retention_Policy::copy (CORBA::Environment &env) +{ + auto_ptr<TAO_Servant_Retention_Policy> new_policy (new TAO_Servant_Retention_Policy (*this)); + + PortableServer::Policy_var result = new_policy->_this (env); + if (env.exception () != 0) + return PortableServer::Policy::_nil (); + else + { + // Make sure that the auto_ptr does not delete the + // implementation object + new_policy.release (); + return result._retn (); + } +} + +void +TAO_Servant_Retention_Policy::destroy (CORBA::Environment &env) +{ + ACE_UNUSED_ARG (env); + + // Commit suicide: must have been dynamically allocated + delete this; +} + +TAO_Request_Processing_Policy::TAO_Request_Processing_Policy (PortableServer::RequestProcessingPolicyValue value) + : value_ (value) +{ +} + +TAO_Request_Processing_Policy::TAO_Request_Processing_Policy (const TAO_Request_Processing_Policy &rhs) + : value_ (rhs.value_) +{ +} + +PortableServer::RequestProcessingPolicyValue +TAO_Request_Processing_Policy::value (CORBA::Environment &env) +{ + ACE_UNUSED_ARG (env); + return this->value_; +} + +PortableServer::Policy_ptr +TAO_Request_Processing_Policy::copy (CORBA::Environment &env) +{ + auto_ptr<TAO_Request_Processing_Policy> new_policy (new TAO_Request_Processing_Policy (*this)); + + PortableServer::Policy_var result = new_policy->_this (env); + if (env.exception () != 0) + return PortableServer::Policy::_nil (); + else + { + // Make sure that the auto_ptr does not delete the + // implementation object + new_policy.release (); + return result._retn (); + } +} + +void +TAO_Request_Processing_Policy::destroy (CORBA::Environment &env) +{ + ACE_UNUSED_ARG (env); + + // Commit suicide: must have been dynamically allocated + delete this; +} + +TAO_POA_Policies::TAO_POA_Policies (void) + : thread_ (PortableServer::ORB_CTRL_MODEL), + lifespan_ (PortableServer::TRANSIENT), + id_uniqueness_ (PortableServer::UNIQUE_ID), + id_assignment_ (PortableServer::SYSTEM_ID), + implicit_activation_ (PortableServer::NO_IMPLICIT_ACTIVATION), + servant_retention_ (PortableServer::RETAIN), + request_processing_ (PortableServer::USE_ACTIVE_OBJECT_MAP_ONLY) +{ +} + +void +TAO_POA_Policies::parse_policies (const PortableServer::PolicyList &policies, + CORBA::Environment &env) +{ + for (CORBA::ULong i = 0; + i < policies.length () && env.exception () == 0; + i++) + { + this->parse_policy (policies[i], env); + } + + if (this->validity_check () == -1) + { + CORBA::Exception *exception = new PortableServer::POA::InvalidPolicy; + env.exception (exception); + return; + } +} + +int +TAO_POA_Policies::validity_check (void) +{ + // The NON_RETAIN policy requires either the USE_DEFAULT_SERVANT or + // USE_SERVANT_MANAGER policies. + if (this->servant_retention_ == PortableServer::NON_RETAIN) + if (this->request_processing_ != PortableServer::USE_SERVANT_MANAGER && + this->request_processing_ != PortableServer::USE_DEFAULT_SERVANT) + return -1; + + // USE_ACTIVE_OBJECT_MAP_ONLY requires the RETAIN policy. + if (this->request_processing_ == PortableServer::USE_ACTIVE_OBJECT_MAP_ONLY) + if (this->servant_retention_ != PortableServer::RETAIN) + return -1; + + // USE_DEFAULT_SERVANT requires the MULTIPLE_ID policy. + if (this->request_processing_ == PortableServer::USE_DEFAULT_SERVANT) + if (this->id_uniqueness_ != PortableServer::MULTIPLE_ID) + return -1; + + // IMPLICIT_ACTIVATION requires the SYSTEM_ID and RETAIN policies. + if (this->implicit_activation_ == PortableServer::IMPLICIT_ACTIVATION) + if (this->servant_retention_ != PortableServer::RETAIN || + this->id_assignment_ != PortableServer::SYSTEM_ID) + return -1; + + return 0; +} + +void +TAO_POA_Policies::parse_policy (const PortableServer::Policy_ptr policy, + CORBA::Environment &env) { - CORBA::String id; - IIOP_Object *data; + PortableServer::ThreadPolicy_var thread + = PortableServer::ThreadPolicy::_narrow (policy, env); + if (!CORBA::is_nil (thread.in ())) + { + this->thread_ = thread->value (env); + return; + } + else + { + env.clear (); + } - if (type_id) - id = CORBA::string_copy (type_id); + PortableServer::LifespanPolicy_var lifespan + = PortableServer::LifespanPolicy::_narrow (policy, env); + if (!CORBA::is_nil (lifespan.in ())) + { + this->lifespan_ = lifespan->value (env); + return; + } else - id = 0; + { + env.clear (); + } + PortableServer::IdUniquenessPolicy_var id_uniqueness + = PortableServer::IdUniquenessPolicy::_narrow (policy, env); + if (!CORBA::is_nil (id_uniqueness.in ())) + { + this->id_uniqueness_ = id_uniqueness->value (env); + return; + } + else + { + env.clear (); + } + PortableServer::IdAssignmentPolicy_var id_assignment + = PortableServer::IdAssignmentPolicy::_narrow (policy, env); + if (!CORBA::is_nil (id_assignment.in ())) + { + this->id_assignment_ = id_assignment->value (env); + return; + } + else + { + env.clear (); + } - data = new IIOP_Object (id, - IIOP::Profile (TAO_ORB_Core_instance ()->orb_params ()->addr (), - key)); - if (data != 0) - env.clear (); + PortableServer::ImplicitActivationPolicy_var implicit_activation + = PortableServer::ImplicitActivationPolicy::_narrow (policy, env); + if (!CORBA::is_nil (implicit_activation.in ())) + { + this->implicit_activation_ = implicit_activation->value (env); + return; + } else { - env.exception (new CORBA_NO_MEMORY (CORBA::COMPLETED_NO)); + env.clear (); + } + + PortableServer::ServantRetentionPolicy_var servant_retention + = PortableServer::ServantRetentionPolicy::_narrow (policy, env); + if (!CORBA::is_nil (servant_retention.in ())) + { + this->servant_retention_ = servant_retention->value (env); + return; + } + else + { + env.clear (); + } + + PortableServer::RequestProcessingPolicy_var request_processing + = PortableServer::RequestProcessingPolicy::_narrow (policy, env); + if (!CORBA::is_nil (request_processing.in ())) + { + this->request_processing_ = request_processing->value (env); + return; + } + else + { + env.clear (); + } + + CORBA::Exception *exception = new PortableServer::POA::InvalidPolicy; + env.exception (exception); + return; +} + +PortableServer::ThreadPolicyValue +TAO_POA_Policies::thread (void) const +{ + return this->thread_; +} + +void +TAO_POA_Policies::thread (PortableServer::ThreadPolicyValue value) +{ + this->thread_ = value; +} + +PortableServer::LifespanPolicyValue +TAO_POA_Policies::lifespan (void) const +{ + return this->lifespan_; +} + +void +TAO_POA_Policies::lifespan (PortableServer::LifespanPolicyValue value) +{ + this->lifespan_ = value; +} + +PortableServer::IdUniquenessPolicyValue +TAO_POA_Policies::id_uniqueness (void) const +{ + return this->id_uniqueness_; +} + +void +TAO_POA_Policies::id_uniqueness (PortableServer::IdUniquenessPolicyValue value) +{ + this->id_uniqueness_ = value; +} + +PortableServer::IdAssignmentPolicyValue +TAO_POA_Policies::id_assignment (void) const +{ + return this->id_assignment_; +} + +void +TAO_POA_Policies::id_assignment (PortableServer::IdAssignmentPolicyValue value) +{ + this->id_assignment_ = value; +} + +PortableServer::ImplicitActivationPolicyValue +TAO_POA_Policies::implicit_activation (void) const +{ + return this->implicit_activation_; +} + +void +TAO_POA_Policies::implicit_activation (PortableServer::ImplicitActivationPolicyValue value) +{ + this->implicit_activation_ = value; +} + +PortableServer::ServantRetentionPolicyValue +TAO_POA_Policies::servant_retention (void) const +{ + return this->servant_retention_; +} + +void +TAO_POA_Policies::servant_retention (PortableServer::ServantRetentionPolicyValue value) +{ + this->servant_retention_ = value; +} + +PortableServer::RequestProcessingPolicyValue +TAO_POA_Policies::request_processing (void) const +{ + return this->request_processing_; +} + +void +TAO_POA_Policies::request_processing (PortableServer::RequestProcessingPolicyValue value) +{ + this->request_processing_ = value; +} + +TAO_POA::TAO_POA (const TAO_POA::String &adapter_name, + TAO_POA_Manager &poa_manager, + const TAO_POA_Policies &policies, + TAO_POA *parent, + CORBA::Environment &env) + : name_ (adapter_name), + poa_manager_ (poa_manager), + policies_ (policies), + parent_ (parent), + active_object_map_ (new TAO_Object_Table), + delete_active_object_map_ (1), + adapter_activator_ (), + servant_activator_ (), + servant_locator_ (), + default_servant_ (0), + children_ (), + lock_ (), + closing_down_ (0), + counter_ (0), + creation_time_ (ACE_OS::gettimeofday ()) +{ + this->set_complete_name (); + + // Register self with manager + this->poa_manager_.register_poa (this, env); +} + +TAO_POA::TAO_POA (const TAO_POA::String &adapter_name, + TAO_POA_Manager &poa_manager, + const TAO_POA_Policies &policies, + TAO_POA *parent, + TAO_Object_Table &active_object_map, + CORBA::Environment &env) + : name_ (adapter_name), + poa_manager_ (poa_manager), + policies_ (policies), + parent_ (parent), + active_object_map_ (&active_object_map), + delete_active_object_map_ (0), + adapter_activator_ (), + servant_activator_ (), + servant_locator_ (), + default_servant_ (0), + children_ (), + lock_ (), + closing_down_ (0), + counter_ (0), + creation_time_ (ACE_OS::gettimeofday ()) +{ + this->set_complete_name (); + + // Register self with manager + this->poa_manager_.register_poa (this, env); +} + +TAO_POA * +TAO_POA::clone (const TAO_POA::String &adapter_name, + TAO_POA_Manager &poa_manager, + const TAO_POA_Policies &policies, + TAO_POA *parent, + CORBA::Environment &env) +{ + return new TAO_POA (adapter_name, + poa_manager, + policies, + parent, + env); +} + +TAO_POA * +TAO_POA::clone (const TAO_POA::String &adapter_name, + TAO_POA_Manager &poa_manager, + const TAO_POA_Policies &policies, + TAO_POA *parent, + TAO_Object_Table &active_object_map, + CORBA::Environment &env) +{ + return new TAO_POA (adapter_name, + poa_manager, + policies, + parent, + active_object_map, + env); +} + +TAO_POA::~TAO_POA (void) +{ + if (this->delete_active_object_map_) + delete active_object_map_; + + // Remove POA from the POAManager + // + // Note: Errors are ignored here since there is nothing we can do + // about them + // + CORBA::Environment env; + this->poa_manager_.remove_poa (this, env); +} + +ACE_Lock & +TAO_POA::lock (void) +{ + return this->lock_; +} + +PortableServer::POA_ptr +TAO_POA::create_POA (const char *adapter_name, + PortableServer::POAManager_ptr poa_manager, + const PortableServer::PolicyList &policies, + CORBA::Environment &env) +{ + // 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_POA_Policies tao_policies; + tao_policies.parse_policies (policies, env); + if (env.exception () != 0) + return PortableServer::POA::_nil (); + + // 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. + TAO_POA_Manager *poa_manager_impl = 0; + if (CORBA::is_nil (poa_manager)) + { + poa_manager_impl = this->poa_manager_.clone (); + } + else + { + PortableServer::Servant servant = poa_manager->_servant (); + if (servant == 0) + { + CORBA::Exception *exception = new CORBA::OBJ_ADAPTER (CORBA::COMPLETED_NO); + env.exception (exception); + return PortableServer::POA::_nil (); + } + + void *ptr = servant->_downcast (servant->_interface_repository_id ()); + POA_PortableServer::POAManager *mgr = (POA_PortableServer::POAManager *) ptr; + poa_manager_impl = ACE_dynamic_cast (TAO_POA_Manager *, mgr); + } + + TAO_POA *result = this->create_POA (adapter_name, + *poa_manager_impl, + tao_policies, + env); + if (env.exception () != 0) + return PortableServer::POA::_nil (); + + return result->_this (env); +} + +TAO_POA * +TAO_POA::create_POA (const TAO_POA::String &adapter_name, + TAO_POA_Manager &poa_manager, + const TAO_POA_Policies &policies, + CORBA::Environment &env) +{ + // Lock access to the POA for the duration of this transaction + TAO_POA_WRITE_GUARD_RETURN (ACE_Lock, monitor, this->lock (), 0, env); + + return this->create_POA_i (adapter_name, + poa_manager, + policies, + env); +} + +TAO_POA * +TAO_POA::create_POA_i (const TAO_POA::String &adapter_name, + TAO_POA_Manager &poa_manager, + const TAO_POA_Policies &policies, + CORBA::Environment &env) +{ + // If this is the leaf POA name + if (this->leaf_poa_name (adapter_name, env)) + { + // 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. + int result = this->children_.find (adapter_name); + + // Child was found + if (result != -1) + { + CORBA::Exception *exception = new PortableServer::POA::AdapterAlreadyExists; + env.exception (exception); + return 0; + } + + // + // Child was not found + // + + // 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. + auto_ptr<TAO_POA> new_poa (this->clone (adapter_name, + poa_manager, + policies, + this, + env)); + + if (env.exception () != 0) + return 0; + + // Add to children map + if (this->children_.bind (adapter_name, new_poa.get ()) != 0) + { + CORBA::Exception *exception = new CORBA::OBJ_ADAPTER (CORBA::COMPLETED_NO); + env.exception (exception); + return 0; + } + + // 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 auto_ptr delete the implementation + return new_poa.release (); + } + // Not the leaf POA name + else + { + // Find the topmost name + TAO_POA::String topmost_poa_name; + TAO_POA::String tail_poa_name; + this->parse_poa_name (adapter_name, + topmost_poa_name, + tail_poa_name, + env); + + if (env.exception () != 0) + return 0; + + // If we are the topmost poa, let's create the tail + if (topmost_poa_name == this->name_) + { + return this->create_POA_i (tail_poa_name, + poa_manager, + policies, + env); + } + + // + // We are not the topmost POA + // + + // Try to find the topmost child + TAO_POA *child_poa = 0; + int result = this->children_.find (topmost_poa_name, child_poa); + + // Child was not found or the topmost is us + if (result != 0) + { + child_poa = this->create_POA_i (topmost_poa_name, + poa_manager, + policies, + env); + if (env.exception () != 0) + return 0; + } + + // At this point, the intermediate child POA was either found or + // created + return child_poa->create_POA (tail_poa_name, + poa_manager, + policies, + env); + } +} + +PortableServer::POA_ptr +TAO_POA::find_POA (const char *adapter_name, + CORBA::Boolean activate_it, + CORBA::Environment &env) +{ + TAO_POA::String name (adapter_name); + + TAO_POA *result = this->find_POA (name, + activate_it, + env); + + if (env.exception () != 0) + return PortableServer::POA::_nil (); + + return result->_this (env); +} + +TAO_POA * +TAO_POA::find_POA (const TAO_POA::String &adapter_name, + CORBA::Boolean activate_it, + CORBA::Environment &env) +{ + // Check if we are the POA the user is looking for + if (adapter_name == this->name_) + return this; + + // Lock access to the POA for the duration of this transaction + TAO_POA_WRITE_GUARD_RETURN (ACE_Lock, monitor, this->lock (), 0, env); + + return this->find_POA_i_optimized (adapter_name, + activate_it, + env); + +} + +TAO_POA * +TAO_POA::find_POA_i (const TAO_POA::String &adapter_name, + CORBA::Boolean activate_it, + CORBA::Environment &env) +{ + // Check if we are the POA the user is looking for + if (adapter_name == this->name_) + return this; + + return this->find_POA_i_optimized (adapter_name, + activate_it, + env); +} + +TAO_POA * +TAO_POA::find_POA_i_optimized (const TAO_POA::String &adapter_name, + CORBA::Boolean activate_it, + CORBA::Environment &env) +{ + // If this is the leaf POA name + if (this->leaf_poa_name (adapter_name, env)) + { + // If the target POA is the parent of a child POA with the + // specified name (relative to the target POA), that child POA + // is returned. + TAO_POA *child_poa = 0; + int result = this->children_.find (adapter_name, child_poa); + + // Child was found + if (result != -1) + return child_poa; + + // + // Child was not found + // + + // If a child POA with the specified name does not exist and the + // value of the activate_it parameter is TRUE, the target POA's + // AdapterActivator, if one exists, is invoked, and, if it + // successfully activates the child POA, that child POA is + // returned. + if (activate_it && !CORBA::is_nil (this->adapter_activator_.in ())) + { + PortableServer::POA_var self = this->_this (env); + // Check for exceptions + if (env.exception () != 0) + return 0; + + CORBA::Boolean success = + this->adapter_activator_->unknown_adapter (self.in (), + adapter_name.c_str (), + env); + // Check for exceptions + if (env.exception () != 0) + return 0; + + // On success + if (success) + { + // Search the children table again + result = this->children_.find (adapter_name, child_poa); + + // Child was found + if (result != -1) + return child_poa; + } + } + + // Otherwise, the AdapterNonExistent exception is raised. + CORBA::Exception *exception = new PortableServer::POA::AdapterNonExistent; + env.exception (exception); return 0; } + // Not the leaf POA name + else + { + // Find the topmost name + // Find the topmost name + TAO_POA::String topmost_poa_name; + TAO_POA::String tail_poa_name; + this->parse_poa_name (adapter_name, + topmost_poa_name, + tail_poa_name, + env); + + if (env.exception () != 0) + return 0; + + // If we are the topmost poa, let's create the tail + if (topmost_poa_name == this->name_) + { + return this->find_POA_i (tail_poa_name, + activate_it, + env); + } + + // + // We are not the topmost POA + // - // Return the CORBA::Object_ptr interface to this objref. - CORBA::Object_ptr new_obj; + // Try to find the topmost child + TAO_POA *child_poa; + int result = this->children_.find (topmost_poa_name, child_poa); - if (data->QueryInterface (IID_CORBA_Object, - (void **) &new_obj) != TAO_NOERROR) - env.exception (new CORBA::INTERNAL (CORBA::COMPLETED_NO)); + // Child was not found + if (result != 0) + { + child_poa = this->find_POA_i_optimized (topmost_poa_name, + activate_it, + env); + if (env.exception () != 0) + return 0; + } - data->Release (); - return new_obj; + // At this point, the intermediate child POA was either found or + // created + return child_poa->find_POA (tail_poa_name, + activate_it, + env); + } } -// Return the key fed into an object at creation time. +void +TAO_POA::destroy (CORBA::Boolean etherealize_objects, + CORBA::Boolean wait_for_completion, + CORBA::Environment &env) +{ + // Lock access to the POA for the duration of this transaction + TAO_POA_WRITE_GUARD (ACE_Lock, monitor, this->lock (), env); -CORBA::OctetSeq * -CORBA_POA::get_key (CORBA::Object_ptr, + this->destroy_i (etherealize_objects, + wait_for_completion, + env); +} + +void +TAO_POA::destroy_i (CORBA::Boolean etherealize_objects, + CORBA::Boolean wait_for_completion, CORBA::Environment &env) { - // XXX implement me ! ... must have been created by this OA. - env.exception (new CORBA_IMP_LIMIT (CORBA::COMPLETED_NO)); - return 0; + this->closing_down_ = 1; + + // 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 + if (this->parent_ != 0) + this->parent_->delete_child (this->name_, env); + + if (env.exception () != 0) + return; + + // Remove all children POAs + for (CHILDREN::iterator iterator = this->children_.begin (); + iterator != this->children_.end () && env.exception () == 0; + iterator++) + { + TAO_POA *child_poa = (*iterator).int_id_; + child_poa->destroy (etherealize_objects, + wait_for_completion, + env); + } + + if (env.exception () != 0) + return; + + // 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 etherealize_objects parameter is TRUE, the POA has the + // RETAIN policy, and a servant manager is registered with the POA, + // the etherealize operation on the servant manager will be called + // for each active object in the Active Object Map. The apparent + // destruction of the POA occurs before any calls to etherealize are + // made. Thus, for example, an etherealize method that attempts to + // invoke operations on the POA will receive the OBJECT_NOT_EXIST + // exception. + + // Remove the registered objects + if (etherealize_objects) + { + if (this->policies ().servant_retention () == PortableServer::RETAIN && + this->policies ().request_processing () == PortableServer::USE_SERVANT_MANAGER && + !CORBA::is_nil (this->servant_activator_.in ())) + { + PortableServer::POA_var self = this->_this (env); + if (env.exception () != 0) + return; + + while (1) + { + TAO_Object_Table::iterator iterator = this->active_object_map ().begin (); + if (iterator == this->active_object_map ().end () || env.exception () != 0) + break; + + PortableServer::Servant servant = 0; + PortableServer::ObjectId id ((*iterator).ext_id_); + + int result = this->active_object_map ().unbind (id, servant); + if (result != 0) + { + CORBA::Exception *exception = new CORBA::OBJ_ADAPTER (CORBA::COMPLETED_NO); + env.exception (exception); + return; + } + + CORBA::Boolean remaining_activations = CORBA::B_FALSE; + + if (this->policies ().id_uniqueness () == PortableServer::MULTIPLE_ID && + this->active_object_map ().find (servant) != -1) + remaining_activations = CORBA::B_TRUE; + + this->servant_activator_->etherealize (id, + self.in (), + servant, + CORBA::B_TRUE, + remaining_activations, + env); + } + } + } + + // 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. + + ACE_UNUSED_ARG (wait_for_completion); + + // Commit suicide + delete this; } -#if 0 -// Used by method code to ask the OA to shut down. void -CORBA_POA::please_shutdown (CORBA::Environment &env) +TAO_POA::delete_child (const TAO_POA::String &child, + CORBA::Environment &env) { - ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX, poa_mon, lock_)); + // If we are not closing down, we must remove this child from our + // collection. + if (!this->closing_down_) + { + // Lock access to the POA for the duration of this transaction + TAO_POA_WRITE_GUARD (ACE_Lock, monitor, this->lock (), env); + + this->delete_child_i (child, + env); + } - env.clear (); - do_exit_ = CORBA::B_TRUE; + // If we are closing down, we are currently iterating over our + // children and there is not need to remove this child from our + // collection. } -// Used by non-method code to tell the OA to shut down. void -CORBA_POA::clean_shutdown (CORBA::Environment &env) +TAO_POA::delete_child_i (const TAO_POA::String &child, + CORBA::Environment &env) { - ACE_MT (ACE_GUARD (ACE_SYNCH_MUTEX, poa_mon, lock_)); + if (this->children_.unbind (child) != 0) + { + CORBA::Exception *exception = new CORBA::OBJ_ADAPTER (CORBA::COMPLETED_NO); + env.exception (exception); + return; + } +} - env.clear (); +TAO_POA_Policies & +TAO_POA::policies (void) +{ + return this->policies_; +} + +TAO_Object_Table & +TAO_POA::active_object_map (void) +{ + return *this->active_object_map_; +} - if (call_count_ != 0) +PortableServer::ServantManager_ptr +TAO_POA::get_servant_manager (CORBA::Environment &env) +{ + // Lock access to the POA for the duration of this transaction + TAO_POA_READ_GUARD_RETURN (ACE_Lock, monitor, this->lock (), PortableServer::ServantManager::_nil (), env); + + return this->get_servant_manager_i (env); +} + +PortableServer::ServantManager_ptr +TAO_POA::get_servant_manager_i (CORBA::Environment &env) +{ + // This operation requires the USE_SERVANT_MANAGER policy; if not + // present, the WrongPolicy exception is raised. + if (this->policies ().request_processing () != PortableServer::USE_SERVANT_MANAGER) + { + CORBA::Exception *exception = new PortableServer::POA::WrongPolicy; + env.exception (exception); + return PortableServer::ServantManager::_nil (); + } + + // This operation returns the servant manager associated with the + // POA. If no servant manager has been associated with the POA, it + // returns a null reference. + if (this->policies ().servant_retention () == PortableServer::RETAIN) + return PortableServer::ServantManager::_duplicate (this->servant_activator_.in ()); + else + return PortableServer::ServantManager::_duplicate (this->servant_locator_.in ()); +} + +void +TAO_POA::set_servant_manager (PortableServer::ServantManager_ptr imgr, + CORBA::Environment &env) +{ + // Lock access to the POA for the duration of this transaction + TAO_POA_WRITE_GUARD (ACE_Lock, monitor, this->lock (), env); + + this->set_servant_manager_i (imgr, + env); +} + +void +TAO_POA::set_servant_manager_i (PortableServer::ServantManager_ptr imgr, + CORBA::Environment &env) +{ + // This operation requires the USE_SERVANT_MANAGER policy; if not + // present, the WrongPolicy exception is raised. + if (this->policies ().request_processing () != PortableServer::USE_SERVANT_MANAGER) { - dmsg ("called clean_shutdown with requests outstanding"); - env.exception (new CORBA::BAD_INV_ORDER (CORBA::COMPLETED_NO)); + CORBA::Exception *exception = new PortableServer::POA::WrongPolicy; + env.exception (exception); return; } - // Here we need to tell all the endpoints to shut down... + // This operation sets the default servant manager associated with + // the POA. + if (this->policies ().servant_retention () == PortableServer::RETAIN) + { + this->servant_activator_ = PortableServer::ServantActivator::_narrow (imgr, env); + if (CORBA::is_nil (this->servant_activator_.in ())) + { + CORBA::Exception *exception = new PortableServer::POA::WrongPolicy; + env.exception (exception); + return; + } + } + else + { + this->servant_locator_ = PortableServer::ServantLocator::_narrow (imgr, env); + if (CORBA::is_nil (this->servant_locator_.in ())) + { + CORBA::Exception *exception = new PortableServer::POA::WrongPolicy; + env.exception (exception); + return; + } + } +} + +PortableServer::Servant +TAO_POA::get_servant (CORBA::Environment &env) +{ + // Lock access to the POA for the duration of this transaction + TAO_POA_READ_GUARD_RETURN (ACE_Lock, monitor, this->lock (), 0, env); + + return this->get_servant_i (env); +} + +PortableServer::Servant +TAO_POA::get_servant_i (CORBA::Environment &env) +{ + // This operation requires the USE_DEFAULT_SERVANT policy; if not + // present, the WrongPolicy exception is raised. + if (this->policies ().request_processing () != PortableServer::USE_DEFAULT_SERVANT) + { + CORBA::Exception *exception = new PortableServer::POA::WrongPolicy; + env.exception (exception); + return 0; + } + + // This operation returns the default servant associated with the + // POA. + if (this->default_servant_ != 0) + { + return this->default_servant_; + } + else + // If no servant has been associated with the POA, the NoServant + // exception is raised. + { + CORBA::Exception *exception = new PortableServer::POA::NoServant; + env.exception (exception); + return 0; + } } -#endif /* 0 */ -// For POA -- POA operations for which we provide the vtable entry void -CORBA_POA::register_dir (dsi_handler handler, - void *ctx, - CORBA::Environment &env) +TAO_POA::set_servant (PortableServer::Servant servant, + CORBA::Environment &env) { - if (handler == 0) + // Lock access to the POA for the duration of this transaction + TAO_POA_WRITE_GUARD (ACE_Lock, monitor, this->lock (), env); + + this->set_servant_i (servant, + env); +} + +void +TAO_POA::set_servant_i (PortableServer::Servant servant, + CORBA::Environment &env) +{ + // This operation requires the USE_DEFAULT_SERVANT policy; if not + // present, the WrongPolicy exception is raised. + if (this->policies ().request_processing () != PortableServer::USE_DEFAULT_SERVANT) { - env.exception (new CORBA::BAD_PARAM (CORBA::COMPLETED_NO)); + CORBA::Exception *exception = new PortableServer::POA::WrongPolicy; + env.exception (exception); return; } - skeleton_ = handler; - context_ = ctx; - - env.clear (); -} - -// A "Named POA" is used in bootstrapping some part of the ORB since -// it's name-to-address binding is managed by the OS. Examples of -// such bindings are /etc/services (for TCP) and /etc/rpc (for ONC -// RPC) . The name of a POA is only guaranteed to be unique within -// the domain of a single system, as a rule; two hosts would have -// distinct "king" POAs. -// -// For network endpoints, most such names are manually administered. -// Some other namespaces (AF_UNIX filesystem names for example) have a -// more formal underlying name service that can be dynamically updated -// while not compromising system security. -// -// The address family used by the POA is found from the ORB passed in. -// -// XXX the coupling could stand to be looser here, so this module did -// not know specifically about the Internet ORB !! - -CORBA::POA_ptr -CORBA_POA::get_named_poa (CORBA::ORB_ptr orb, - CORBA::String name, + // This operation registers the specified servant with the POA as + // the default servant. This servant will be used for all requests + // for which no servant is found in the Active Object Map. + this->default_servant_ = servant; +} + +PortableServer::ObjectId * +TAO_POA::activate_object (PortableServer::Servant servant, CORBA::Environment &env) { - env.clear (); + // Lock access to the POA for the duration of this transaction + TAO_POA_WRITE_GUARD_RETURN (ACE_Lock, monitor, this->lock (), 0, env); + + return this->activate_object_i (servant, + env); +} + +PortableServer::ObjectId * +TAO_POA::activate_object_i (PortableServer::Servant servant, + CORBA::Environment &env) +{ + // This operation requires the SYSTEM_ID and RETAIN policy; if not + // present, the WrongPolicy exception is raised. + if (!(this->policies ().id_assignment () == PortableServer::SYSTEM_ID && + this->policies ().servant_retention () == PortableServer::RETAIN)) + { + CORBA::Exception *exception = new PortableServer::POA::WrongPolicy; + env.exception (exception); + return 0; + } + + // If the POA has the UNIQUE_ID policy and the specified servant is + // already in the Active Object Map, the ServantAlreadyActive + // exception is raised. + if (this->policies ().id_uniqueness () == PortableServer::UNIQUE_ID && + this->active_object_map ().find (servant) != -1) + { + CORBA::Exception *exception = new PortableServer::POA::ServantAlreadyActive; + env.exception (exception); + return 0; + } - // If the ORB is an Internet ORB, we know this must be a TCP OA. - { - IIOP_ORB *internet; + // Otherwise, the activate_object operation generates an Object Id + // and enters the Object Id and the specified servant in the Active + // Object Map. The Object Id is returned. + PortableServer::ObjectId_var new_id = this->create_object_id (); - if (orb->QueryInterface (IID_IIOP_ORB, (void **) &internet) == TAO_NOERROR) - { - CORBA::POA_ptr tcp_oa; + if (this->active_object_map ().bind (new_id.in (), servant) == -1) + { + CORBA::Exception *exception = new CORBA::OBJ_ADAPTER (CORBA::COMPLETED_NO); + env.exception (exception); + return 0; + } - internet->Release (); + // Everything is finally ok + return new_id._retn (); +} - // POA initialization with name specified; it'll come from - // /etc/services if it's not a port number. +void +TAO_POA::activate_object_with_id (const PortableServer::ObjectId &id, + PortableServer::Servant servant, + CORBA::Environment &env) +{ + // Lock access to the POA for the duration of this transaction + TAO_POA_WRITE_GUARD (ACE_Lock, monitor, this->lock (), env); - ACE_INET_Addr poa_name (name, (ACE_UINT32) INADDR_ANY); + this->activate_object_with_id_i (id, + servant, + env); +} - tcp_oa = CORBA::POA::init (orb, poa_name, env); +void +TAO_POA::activate_object_with_id_i (const PortableServer::ObjectId &id, + PortableServer::Servant servant, + CORBA::Environment &env) +{ + // This operation requires the RETAIN policy; if not present, the + // WrongPolicy exception is raised. + if (this->policies ().servant_retention () != PortableServer::RETAIN) + { + CORBA::Exception *exception = new PortableServer::POA::WrongPolicy; + env.exception (exception); + return; + } - if (env.exception () != 0) - return 0; - else - return tcp_oa; // derives from POA - } - } + // 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 activate_object_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 activate_object_with_id 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->policies ().id_assignment () == PortableServer::SYSTEM_ID && + !this->is_poa_generated_id (id)) + { + CORBA::Exception *exception = new CORBA::BAD_PARAM (CORBA::COMPLETED_NO); + env.exception (exception); + return; + } - // We don't know how to deal with this kind of ORB. Report error. + // If the CORBA object denoted by the Object Id value is already + // active in this POA (there is a servant bound to it in the Active + // Object Map), the ObjectAlreadyActive exception is raised. + if (this->active_object_map ().find (id) != -1) + { + CORBA::Exception *exception = new PortableServer::POA::ObjectAlreadyActive; + env.exception (exception); + return; + } - env.exception (new CORBA::BAD_PARAM (CORBA::COMPLETED_NO) ); - return 0; + // If the POA has the UNIQUE_ID policy and the servant is already in + // the Active Object Map, the ServantAlreadyActive exception is + // raised. + if (this->policies ().id_uniqueness () == PortableServer::UNIQUE_ID && + this->active_object_map ().find (servant) != -1) + { + CORBA::Exception *exception = new PortableServer::POA::ServantAlreadyActive; + env.exception (exception); + return; + } + + // Otherwise, the activate_object_with_id operation enters an + // association between the specified Object Id and the specified + // servant in the Active Object Map. + if (this->active_object_map ().bind (id, servant) == -1) + { + CORBA::Exception *exception = new CORBA::OBJ_ADAPTER (CORBA::COMPLETED_NO); + env.exception (exception); + return; + } + + // Everything is finally ok } -// An "Anonymous" POA is used more routinely. The name used doesn't -// matter to anyone; it is only used to create object references with -// a short lifespan, namely that of the process acquiring this POA. +void +TAO_POA::deactivate_object (const PortableServer::ObjectId &oid, + CORBA::Environment &env) +{ + // Lock access to the POA for the duration of this transaction + TAO_POA_WRITE_GUARD (ACE_Lock, monitor, this->lock (), env); + + this->deactivate_object_i (oid, + env); +} -CORBA::POA_ptr -CORBA_POA::get_poa (CORBA::ORB_ptr orb, - CORBA::Environment &env) +void +TAO_POA::deactivate_object_i (const PortableServer::ObjectId &oid, + CORBA::Environment &env) { - env.clear (); + // This operation requires the RETAIN policy; if not present, the + // WrongPolicy exception is raised. + if (this->policies ().servant_retention () != PortableServer::RETAIN) + { + CORBA::Exception *exception = new PortableServer::POA::WrongPolicy; + env.exception (exception); + return; + } - // If the ORB is an Internet ORB, we know this must be a TCP OA. - { - IIOP_ORB *internet; + // This operation causes the association of the Object Id specified + // by the oid parameter and its servant to be removed from the + // Active Object Map. + PortableServer::Servant servant = 0; + int result = this->active_object_map ().unbind (oid, servant); - if (orb->QueryInterface (IID_IIOP_ORB, (void **) &internet) == TAO_NOERROR) - { - CORBA::POA_ptr tcp_oa; + // If there is no active object associated with the specified Object + // Id, the operation raises an ObjectNotActive exception. + if (result != 0) + { + CORBA::Exception *exception = new PortableServer::POA::ObjectNotActive; + env.exception (exception); + return; + } - internet->Release (); + // If a servant manager is associated with the POA, + // ServantLocator::etherealize will be invoked with the oid and the + // servant. (The deactivate_object operation does not wait for the + // etherealize operation to complete before deactivate_object + // returns.) + // + // Note: If the servant associated with the oid is serving multiple + // Object Ids, ServantLocator::etherealize may be invoked multiple + // times with the same servant when the other objects are + // deactivated. It is the responsibility of the object + // implementation to refrain from destroying the servant while it is + // active with any Id. + if (!CORBA::is_nil (this->servant_activator_.in ())) + { + PortableServer::POA_var self = this->_this (env); + if (env.exception () != 0) + return; + + CORBA::Boolean remaining_activations = CORBA::B_FALSE; + + if (this->policies ().id_uniqueness () == PortableServer::MULTIPLE_ID && + this->active_object_map ().find (servant) != -1) + remaining_activations = CORBA::B_TRUE; + + this->servant_activator_->etherealize (oid, + self.in (), + servant, + CORBA::B_FALSE, + remaining_activations, + env); + } +} - // POA initialization with null name means anonymous OA +CORBA::Object_ptr +TAO_POA::create_reference (const char *intf, + CORBA::Environment &env) +{ + // Lock access to the POA for the duration of this transaction + TAO_POA_WRITE_GUARD_RETURN (ACE_Lock, monitor, this->lock (), CORBA::Object::_nil (), env); - ACE_INET_Addr anonymous ((u_short) 0, (ACE_UINT32) INADDR_ANY); + return this->create_reference_i (intf, + env); +} - tcp_oa = CORBA::POA::init (orb, anonymous, env); +CORBA::Object_ptr +TAO_POA::create_reference_i (const char *intf, + CORBA::Environment &env) +{ + // This operation requires the SYSTEM_ID policy; if not present, the + // WrongPolicy exception is raised. + if (this->policies ().id_assignment () != PortableServer::SYSTEM_ID) + { + CORBA::Exception *exception = new PortableServer::POA::WrongPolicy; + env.exception (exception); + return CORBA::Object::_nil (); + } - if (env.exception () != 0) - return 0; - else - return tcp_oa; // derives from POA - } - } + // This operation creates an object reference that encapsulates a + // POA-generated Object Id value and the specified interface + // repository id. This operation does not cause an activation to + // take place. The resulting reference may be passed to clients, so + // that subsequent requests on those references will cause the + // appropriate servant manager to be invoked, if one is + // available. The generated Object Id value may be obtained by + // invoking POA::reference_to_id with the created reference. + PortableServer::ObjectId_var new_id = this->create_object_id (); + TAO::ObjectKey_var new_key = this->create_object_key (new_id.in ()); + + // Ask the ORB to create you a reference + return TAO_ORB_Core_instance ()->orb ()->key_to_object (new_key.in (), intf, env); +} - // We don't know how to deal with this kind of ORB. Report error. +CORBA::Object_ptr +TAO_POA::create_reference_with_id (const PortableServer::ObjectId &oid, + const char *intf, + CORBA::Environment &env) +{ + // 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->policies ().id_assignment () == PortableServer::SYSTEM_ID && + !this->is_poa_generated_id (oid)) + { + CORBA::Exception *exception = new CORBA::BAD_PARAM (CORBA::COMPLETED_NO); + env.exception (exception); + return CORBA::Object::_nil (); + } - env.exception (new CORBA::BAD_PARAM (CORBA::COMPLETED_NO) ); - return 0; + // This operation creates an object reference that encapsulates the + // specified Object Id and interface repository Id values. This + // operation does not cause an activation to take place. The + // resulting reference may be passed to clients, so that subsequent + // requests on those references will cause the object to be + // activated if necessary, or the default servant used, depending on + // the applicable policies. + TAO::ObjectKey_var new_key = this->create_object_key (oid); + + // Ask the ORB to create you a reference + return TAO_ORB_Core_instance ()->orb ()->key_to_object (new_key.in (), intf, env); } -void CORBA_POA::dispatch (TAO_opaque &key, - CORBA::ServerRequest &req, - void *context, +PortableServer::ObjectId * +TAO_POA::servant_to_id (PortableServer::Servant servant, + CORBA::Environment &env) +{ + // If we had upgradeable locks, this would initially be a read lock + // + // Lock access to the POA for the duration of this transaction + TAO_POA_WRITE_GUARD_RETURN (ACE_Lock, monitor, this->lock (), 0, env); + + return this->servant_to_id_i (servant, + env); +} + +PortableServer::ObjectId * +TAO_POA::servant_to_id_i (PortableServer::Servant servant, CORBA::Environment &env) { - ACE_UNUSED_ARG(context); + // This operation requires the RETAIN and either the UNIQUE_ID or + // IMPLICIT_ACTIVATION policies; if not present, the WrongPolicy + // exception is raised. + if (!(this->policies ().servant_retention () == PortableServer::RETAIN && + (this->policies ().id_uniqueness () == PortableServer::UNIQUE_ID || + this->policies ().implicit_activation () == PortableServer::IMPLICIT_ACTIVATION))) + { + CORBA::Exception *exception = new PortableServer::POA::WrongPolicy; + env.exception (exception); + return 0; + } + + // This operation has three possible behaviors. + + // If the POA has the UNIQUE_ID policy and the specified servant is + // active, the Object Id associated with that servant is returned. + PortableServer::ObjectId_var id; + if (this->policies ().id_uniqueness () == PortableServer::UNIQUE_ID && + this->active_object_map ().find (servant, id.out ()) != -1) + { + return id._retn (); + } + + // If the POA has the IMPLICIT_ACTIVATION policy and either the POA + // has the MULTIPLE_ID policy or the specified servant is not + // active, the servant is activated using a POA-generated Object Id + // and the Interface Id associated with the servant, and that Object + // Id is returned. + if (this->policies ().implicit_activation () == PortableServer::IMPLICIT_ACTIVATION) + { + if (this->policies ().id_uniqueness () == PortableServer::MULTIPLE_ID || + this->active_object_map ().find (servant) != 0) + { + PortableServer::ObjectId_var new_id = this->create_object_id (); + + if (this->active_object_map ().bind (new_id.in (), servant) == -1) + { + CORBA::Exception *exception = new CORBA::OBJ_ADAPTER (CORBA::COMPLETED_NO); + env.exception (exception); + return 0; + } + + // Everything is finally ok + return new_id._retn (); + } + } + + // Otherwise, the ServantNotActive exception is raised. + CORBA::Exception *exception = new PortableServer::POA::ServantNotActive; + env.exception (exception); + return 0; +} + +CORBA::Object_ptr +TAO_POA::servant_to_reference (PortableServer::Servant servant, + CORBA::Environment &env) +{ + // Note: The allocation of an Object Id value and installation in + // the Active Object Map caused by implicit activation may actually + // be deferred until an attempt is made to externalize the + // reference. The real requirement here is that a reference is + // produced that will behave appropriately (that is, yield a + // consistent Object Id value when asked politely). + PortableServer::ObjectId_var oid = this->servant_to_id (servant, + env); + + if (env.exception () != 0) + return CORBA::Object::_nil (); + else + return this->create_reference_with_id (oid.in (), + servant->_interface_repository_id (), + env); +} + +PortableServer::Servant +TAO_POA::reference_to_servant (CORBA::Object_ptr reference, + CORBA::Environment &env) +{ + // This operation requires the RETAIN policy or the + // USE_DEFAULT_SERVANT policy. If neither policy is present, the + // WrongPolicy exception is raised. + if (!(this->policies ().servant_retention () == PortableServer::RETAIN || + this->policies ().request_processing () == PortableServer::USE_DEFAULT_SERVANT)) + { + CORBA::Exception *exception = new PortableServer::POA::WrongPolicy; + env.exception (exception); + return 0; + } - TAO_Skeleton skel; // pointer to function pointer for the operation - CORBA::Object_ptr obj; // object that will be looked up based on the key - CORBA::String opname; + // If the POA has the RETAIN policy and the specified object is + // present in the Active Object Map, this operation returns the + // servant associated with that object in the Active Object Map. + if (this->policies ().servant_retention () == PortableServer::RETAIN) + { + TAO::ObjectKey_var key = reference->key (env); + + // If the object reference was not created by this POA, the + // WrongAdapter exception is raised. + PortableServer::ObjectId_var id; + TAO_POA::String poa_name; + CORBA::Boolean persistent = CORBA::B_FALSE; + ACE_Time_Value poa_creation_time; + + int result = this->parse_key (key.in (), + poa_name, + id.out (), + persistent, + poa_creation_time); + if (result != 0 || + poa_name != this->complete_name () || + persistent != this->persistent () || + !this->persistent () && poa_creation_time != this->creation_time_) + { + CORBA::Exception *exception = new PortableServer::POA::WrongAdapter; + env.exception (exception); + return 0; + } - // Get the skeleton + return this->id_to_servant (id.in (), env); + } - // Find the object based on the key - if (this->find (key, obj) != -1) + // Otherwise, if the POA has the USE_DEFAULT_SERVANT policy and a + // default servant has been registered with the POA, this operation + // returns the default servant. + if (this->policies ().request_processing () == PortableServer::USE_DEFAULT_SERVANT) { -#if 0 // XXXASG - testing a new way of handling requests to overcome the - // casting problem arising out of virtual inheritance - opname = req.op_name (); + // Lock access to the POA for the duration of this transaction + TAO_POA_READ_GUARD_RETURN (ACE_Lock, monitor, this->lock (), 0, env); - // Find the skeleton "glue" function based on the operation name - if (obj->find (opname, skel) != -1) - // Schedule the upcall. This is the degenerate case of scheduling... - // using a "do it now!" scheduler - skel (req, obj, env); + if (this->default_servant_ != 0) + { + return this->default_servant_; + } else + // Otherwise, the ObjectNotActive exception is raised. { - // Something really bad happened: the operation was not - // found in the object, fortunately there is a standard - // exception for that purpose. - env.exception (new CORBA_BAD_OPERATION (CORBA::COMPLETED_NO)); - ACE_ERROR ((LM_ERROR, - "Cannot find operation <%s> in object\n", - opname)); + CORBA::Exception *exception = new PortableServer::POA::ObjectNotActive; + env.exception (exception); + return 0; } -#else - ACE_UNUSED_ARG (opname); - ACE_UNUSED_ARG (skel); -#endif - obj->dispatch (req, context, env); + } + + // Not reached + return 0; +} + +PortableServer::ObjectId * +TAO_POA::reference_to_id (CORBA::Object_ptr reference, + CORBA::Environment &env) +{ + // The WrongPolicy exception is declared to allow future extensions. + + // This operation returns the Object Id value encapsulated by the + // specified reference. + + // 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. + TAO::ObjectKey_var key = reference->key (env); + PortableServer::ObjectId_var id; + TAO_POA::String poa_name; + CORBA::Boolean persistent = CORBA::B_FALSE; + ACE_Time_Value poa_creation_time; + + int result = this->parse_key (key.in (), + poa_name, + id.out (), + persistent, + poa_creation_time); + if (result != 0 || + poa_name != this->complete_name () || + persistent != this->persistent () || + !this->persistent () && poa_creation_time != this->creation_time_) + { + CORBA::Exception *exception = new PortableServer::POA::WrongAdapter; + env.exception (exception); + return 0; + } + + // The object denoted by the reference does not have to be active + // for this operation to succeed. + return id._retn (); +} + +PortableServer::Servant +TAO_POA::id_to_servant (const PortableServer::ObjectId &oid, + CORBA::Environment &env) +{ + // Lock access to the POA for the duration of this transaction + TAO_POA_READ_GUARD_RETURN (ACE_Lock, monitor, this->lock (), 0, env); + + return this->id_to_servant_i (oid, + env); +} + +PortableServer::Servant +TAO_POA::id_to_servant_i (const PortableServer::ObjectId &oid, + CORBA::Environment &env) +{ + // This operation requires the RETAIN policy; if not present, the + // WrongPolicy exception is raised. + if (this->policies ().servant_retention () != PortableServer::RETAIN) + { + CORBA::Exception *exception = new PortableServer::POA::WrongPolicy; + env.exception (exception); + return 0; + } + + // This operation returns the active servant associated with the + // specified Object Id value. If the Object Id value is not active + // in the POA, an ObjectNotActive exception is raised. + PortableServer::Servant servant = 0; + if (this->active_object_map ().find (oid, servant) != -1) + { + return servant; } else + // Otherwise, the ObjectNotActive exception is raised. { - env.exception (new CORBA::OBJECT_NOT_EXIST (CORBA::COMPLETED_NO)); - ACE_ERROR ((LM_ERROR, "Cannot find object\n")); + CORBA::Exception *exception = new PortableServer::POA::ObjectNotActive; + env.exception (exception); + return 0; + } +} + +CORBA::Object_ptr +TAO_POA::id_to_reference (const PortableServer::ObjectId &oid, + CORBA::Environment &env) +{ + PortableServer::Servant servant = this->id_to_servant (oid, + env); + if (env.exception () != 0) + return CORBA::Object::_nil (); + else + return this->servant_to_reference (servant, + env); +} + +PortableServer::POA_ptr +TAO_POA::the_parent (CORBA::Environment &env) +{ + if (this->parent_ != 0) + return this->parent_->_this (env); + else + return PortableServer::POA::_nil (); +} + +PortableServer::POAManager_ptr +TAO_POA::the_POAManager (CORBA::Environment &env) +{ + return this->poa_manager_._this (env); +} + +PortableServer::AdapterActivator_ptr +TAO_POA::the_activator (CORBA::Environment &env) +{ + ACE_UNUSED_ARG (env); + + return PortableServer::AdapterActivator::_duplicate (this->adapter_activator_.in ()); +} + +void +TAO_POA::the_activator (PortableServer::AdapterActivator_ptr adapter_activator, + CORBA::Environment &env) +{ + ACE_UNUSED_ARG (env); + + this->adapter_activator_ = PortableServer::AdapterActivator::_duplicate (adapter_activator); +} + +TAO_POA * +TAO_POA::locate_poa_i (const TAO::ObjectKey &key, + PortableServer::ObjectId_out id, + CORBA::Environment &env) +{ + TAO_POA::String poa_name; + CORBA::Boolean persistent = CORBA::B_FALSE; + ACE_Time_Value poa_creation_time; + + int result = this->parse_key (key, + poa_name, + id, + persistent, + poa_creation_time); + if (result != 0) + { + CORBA::Exception *exception = new CORBA::OBJ_ADAPTER (CORBA::COMPLETED_NO); + env.exception (exception); + return 0; + } + + TAO_POA *poa = this->find_POA_i (poa_name, + persistent, + env); + if (env.exception () != 0) + return 0; + + // Make sure it is not an "old" objectId + if (!poa->persistent () && + poa->creation_time () != poa_creation_time) + { + CORBA::Exception *exception = new CORBA::OBJECT_NOT_EXIST (CORBA::COMPLETED_NO); + env.exception (exception); + return 0; } - // @@ XXXASG - - // We need to pass this skel and associated information to the - // scheduler. How do we do it?? + return poa; } int -CORBA_POA::find (const TAO_opaque &key, - CORBA::Object_ptr &obj) +TAO_POA::locate_servant (const TAO::ObjectKey &key, + CORBA::Environment &env) { - return objtable_->find (key, obj); + // Lock access to the POAManager for the duration of this transaction + TAO_POA_READ_GUARD_RETURN (ACE_Lock, monitor, this->lock (), -1, env); + + return this->locate_servant_i (key, env); } int -CORBA_POA::bind (const TAO_opaque &key, - CORBA::Object_ptr obj) +TAO_POA::locate_servant_i (const TAO::ObjectKey &key, + CORBA::Environment &env) +{ + PortableServer::ObjectId_var id; + + TAO_POA *poa = this->locate_poa_i (key, + id.out (), + env); + if (env.exception () != 0) + return -1; + + // If the POA has the RETAIN policy, the POA looks in the Active + // Object Map to find if there is a servant associated with the + // Object Id value from the request. If such a servant exists, + // return 0. + if (poa->policies ().servant_retention () == PortableServer::RETAIN) + { + PortableServer::Servant servant = 0; + if (poa->active_object_map ().find (id.in (), servant) != -1) + // Success + return 0; + } + + // If the POA has the NON_RETAIN policy or has the RETAIN policy but + // didn't find a servant in the Active Object Map, the POA takes the + // following actions: + + // If the USE_ACTIVE_OBJECT_MAP_ONLY policy is in effect, the POA raises + // the OBJECT_NOT_EXIST system exception. + if (poa->policies ().request_processing () == PortableServer::USE_ACTIVE_OBJECT_MAP_ONLY) + return -1; + + // If the POA has the USE_DEFAULT_SERVANT policy, a default servant + // has been associated with the POA, return 0. If no servant has + // been associated with the POA, return -1. + if (poa->policies ().request_processing () == PortableServer::USE_DEFAULT_SERVANT) + { + if (poa->default_servant_ == 0) + return -1; + else + // Success + return 0; + } + + // If the POA has the USE_SERVANT_MANAGER policy, a servant manager + // has been associated with the POA, return 0. If no servant manager + // has been associated with the POA, return -1. + if (poa->policies ().request_processing () == PortableServer::USE_SERVANT_MANAGER) + { + if (CORBA::is_nil (poa->servant_activator_.in ()) && + CORBA::is_nil (poa->servant_locator_.in ())) + return -1; + else + // Success + return 0; + } + + // Failure + return -1; +} + +PortableServer::Servant +TAO_POA::locate_poa_and_servant_i (const TAO::ObjectKey &key, + const char *operation, + PortableServer::ObjectId_out id, + TAO_POA *&poa_impl, + CORBA::Environment &env) +{ + poa_impl = this->locate_poa_i (key, + id, + env); + if (env.exception () != 0) + return 0; + + // If the POA has the RETAIN policy, the POA looks in the Active + // Object Map to find if there is a servant associated with the + // Object Id value from the request. If such a servant exists, the + // POA invokes the appropriate method on the servant. + if (poa_impl->policies ().servant_retention () == PortableServer::RETAIN) + { + PortableServer::Servant servant = 0; + if (poa_impl->active_object_map ().find (*id.ptr (), servant) != -1) + // Success + return servant; + } + + // If the POA has the NON_RETAIN policy or has the RETAIN policy but + // didn't find a servant in the Active Object Map, the POA takes the + // following actions: + + // If the USE_ACTIVE_OBJECT_MAP_ONLY policy is in effect, the POA raises + // the OBJECT_NOT_EXIST system exception. + if (poa_impl->policies ().request_processing () == PortableServer::USE_ACTIVE_OBJECT_MAP_ONLY) + { + CORBA::Exception *exception = new CORBA::OBJECT_NOT_EXIST (CORBA::COMPLETED_NO); + env.exception (exception); + return 0; + } + + // If the POA has the USE_DEFAULT_SERVANT policy, a default servant + // has been associated with the POA so the POA will invoke the + // appropriate method on that servant. If no servant has been + // associated with the POA, the POA raises the OBJ_ADAPTER system + // exception. + if (poa_impl->policies ().request_processing () == PortableServer::USE_DEFAULT_SERVANT) + { + if (poa_impl->default_servant_ == 0) + { + CORBA::Exception *exception = new CORBA::OBJ_ADAPTER (CORBA::COMPLETED_NO); + env.exception (exception); + return 0; + } + else + { + // Success + return poa_impl->default_servant_; + } + } + + // If the POA has the USE_SERVANT_MANAGER policy, a servant manager + // has been associated with the POA so the POA will invoke incarnate + // or preinvoke on it to find a servant that may handle the + // request. (The choice of method depends on the NON_RETAIN or + // RETAIN policy of the POA.) If no servant manager has been + // associated with the POA, the POA raises the OBJ_ADAPTER system + // exception. + // + // If a servant manager is located and invoked, but the servant + // manager is not directly capable of incarnating the object, it + // (the servant manager) may deal with the circumstance in a variety + // of ways, all of which are the application's responsibility. Any + // system exception raised by the servant manager will be returned + // to the client in the reply. In addition to standard CORBA + // exceptions, a servant manager is capable of raising a + // ForwardRequest exception. This exception includes an object + // reference. + // + if (poa_impl->policies ().request_processing () == PortableServer::USE_SERVANT_MANAGER) + { + if (CORBA::is_nil (poa_impl->servant_activator_.in ()) && + CORBA::is_nil (poa_impl->servant_locator_.in ())) + { + CORBA::Exception *exception = new CORBA::OBJ_ADAPTER (CORBA::COMPLETED_NO); + env.exception (exception); + return 0; + } + + PortableServer::POA_var poa = poa_impl->_this (env); + if (env.exception () != 0) + return 0; + + if (poa_impl->policies ().servant_retention () == PortableServer::RETAIN) + { + // @@ + // Invocations of incarnate on the servant manager are serialized. + // Invocations of etherealize on the servant manager are serialized. + // Invocations of incarnate and etherealize on the servant manager are mutually exclusive. + PortableServer::Servant servant = poa_impl->servant_activator_->incarnate (*id.ptr (), + poa.in (), + env); + if (env.exception () != 0 || servant == 0) + return 0; + + // If the incarnate operation returns a servant that is + // already active for a different Object Id and if the POA + // also has the UNIQUE_ID policy, the incarnate has violated + // the POA policy and is considered to be in error. The POA + // will raise an OBJ_ADAPTER system exception for the + // request. + if (poa_impl->policies ().id_uniqueness () == PortableServer::UNIQUE_ID && + poa_impl->active_object_map ().find (servant) != -1) + { + CORBA::Exception *exception = new CORBA::OBJ_ADAPTER (CORBA::COMPLETED_NO); + env.exception (exception); + return 0; + } + + // The POA enters the returned Servant value into the Active + // Object Map so that subsequent requests with the same + // ObjectId value will be delivered directly to that servant + // without invoking the servant manager. + if (poa_impl->active_object_map ().bind (*id.ptr (), servant) == -1) + { + CORBA::Exception *exception = new CORBA::OBJ_ADAPTER (CORBA::COMPLETED_NO); + env.exception (exception); + return 0; + } + + // Success + return servant; + } + else + // + // Don't retain servant + // + { + // No serialization of invocations of preinvoke or + // postinvoke may be assumed; there may be multiple + // concurrent invocations of preinvoke for the same + // ObjectId. + // + // The same thread will be used to preinvoke the object, + // process the request, and postinvoke the object. + // + PortableServer::ServantLocator::Cookie cookie; + PortableServer::Servant servant = poa_impl->servant_locator_->preinvoke (*id.ptr (), + poa.in (), + operation, + cookie, + env); + if (env.exception () != 0 || servant == 0) + return 0; + + // Remember the cookie + TAO_ORB_Core *orb_core = TAO_ORB_Core_instance (); + TAO_POA_Current *poa_current = orb_core->poa_current (); + poa_current->locator_cookie (cookie); + + // Success + return servant; + } + } + + // Failure + CORBA::Exception *exception = new CORBA::OBJ_ADAPTER (CORBA::COMPLETED_NO); + env.exception (exception); + return 0; +} + +void +TAO_POA::dispatch_servant (const TAO::ObjectKey &key, + CORBA::ServerRequest &req, + void *context, + CORBA::Environment &env) { - return objtable_->bind (key, obj); + // Lock access to the POAManager for the duration of this transaction + TAO_POA_READ_GUARD (ACE_Lock, monitor, this->lock (), env); + + this->dispatch_servant_i (key, req, context, env); } -// IUnknown calls -ULONG -CORBA_POA::AddRef (void) +void +TAO_POA::dispatch_servant_i (const TAO::ObjectKey &key, + CORBA::ServerRequest &req, + void *context, + CORBA::Environment &env) { - ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, poa_mon, com_lock_, 0)); - return ++refcount_; + PortableServer::ObjectId_var id; + TAO_POA *poa = 0; + // const char *operation = req.operation (); + const char *operation = req.op_name (); + + PortableServer::Servant servant = this->locate_poa_and_servant_i (key, + operation, + id.out (), + poa, + env); + if (env.exception () != 0 || servant == 0) + return; + + // Setup for upcall + poa->pre_invoke (key, + id.in (), + servant, + env); + + servant->_dispatch (req, + context, + env); + + // Cleanup from upcall + poa->post_invoke (servant, + operation, + env); } -ULONG -CORBA_POA::Release (void) +void +TAO_POA::pre_invoke (const TAO::ObjectKey &key, + const PortableServer::ObjectId &id, + PortableServer::Servant servant, + CORBA::Environment &env) { - { - ACE_MT (ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, poa_mon, com_lock_, 0)); + ACE_UNUSED_ARG (env); - if (--refcount_ != 0) - return refcount_; - } + TAO_ORB_Core *orb_core = TAO_ORB_Core_instance (); + TAO_POA_Current *poa_current = orb_core->poa_current (); - delete this; + poa_current->POA_impl (this); + poa_current->object_key (key); + poa_current->object_id (id); + poa_current->servant (servant); +} + +void +TAO_POA::post_invoke (PortableServer::Servant servant, + const char *operation, + CORBA::Environment &env) +{ + TAO_ORB_Core *orb_core = TAO_ORB_Core_instance (); + TAO_POA_Current *poa_current = orb_core->poa_current (); + + PortableServer::ServantLocator::Cookie cookie = poa_current->locator_cookie (); + + PortableServer::POA_var poa = poa_current->get_POA (env); + + if (cookie != 0) + this->servant_locator_->postinvoke (poa_current->object_id (), + poa.in (), + operation, + cookie, + servant, + env); + // Reset current + poa_current->clear (); +} + +const ACE_Time_Value & +TAO_POA::creation_time (void) +{ + return this->creation_time_; +} + +int +TAO_POA::parse_key (const TAO::ObjectKey &key, + TAO_POA::String &poa_name, + PortableServer::ObjectId_out id, + CORBA::Boolean &persistent, + ACE_Time_Value &poa_creation_time) +{ + // Grab the id buffer + TAO_POA::String object_key (TAO_POA::ObjectKey_to_const_string (key)); + + // Try to find the first separator + int first_token_position = object_key.find (TAO_POA::name_separator (), + 0); + // If not found, the name is not correct + if (first_token_position == TAO_POA::String::npos) + return -1; + else + first_token_position += 0; + + // Try to find the second separator + int second_token_position = object_key.find (TAO_POA::name_separator (), + first_token_position + 1); + // If not found, the name is not correct + if (second_token_position == TAO_POA::String::npos) + return -1; + else + second_token_position += first_token_position + 1; + + // Try to find the third separator + int third_token_position = object_key.find (TAO_POA::name_separator (), + second_token_position + 1); + // If not found, the name is not correct + if (third_token_position == TAO_POA::String::npos) + return -1; + else + third_token_position += second_token_position + 1; + + // Try to find the last separator + int last_token_position = object_key.rfind (TAO_POA::name_separator ()); + + // If not found or the token are not distinct, the name is not correct + if (last_token_position == TAO_POA::String::npos || + third_token_position == last_token_position) + return -1; + + // Take the substring from 0 to first_token_position for the + // object_key_type. + int starting_at = 0; + int now_many = first_token_position - starting_at; + TAO_POA::String object_key_type = object_key.substr (starting_at, + now_many); + if (object_key_type == this->persistent_key_type ()) + persistent = 1; + else if (object_key_type == this->transient_key_type ()) + persistent = 0; + else + // Incorrect key + return -1; + + // Take the substring from (first_token_position + separator_length) + // to second_token_position for the seconds + starting_at = first_token_position + TAO_POA::name_separator_length (); + now_many = second_token_position - starting_at; + TAO_POA::String seconds = object_key.substr (starting_at, + now_many); + + // Take the substring from (second_token_position + separator_length) + // to third_token_position for the micro_seconds + starting_at = second_token_position + TAO_POA::name_separator_length (); + now_many = third_token_position - starting_at; + TAO_POA::String micro_seconds = object_key.substr (starting_at, + now_many); + + // Take the substring from (third_token_position + separator_length) + // to last_token_position for the POA name + starting_at = third_token_position + TAO_POA::name_separator_length (); + now_many = last_token_position - starting_at; + poa_name = object_key.substr (starting_at, + now_many); + + // Take the substring from (last_token_position + + // separator_length) to length for the objectId + starting_at = last_token_position + TAO_POA::name_separator_length (); + now_many = object_key.length () - starting_at; + TAO_POA::String objectId = object_key.substr (starting_at, + now_many); + + id = TAO_POA::string_to_ObjectId (objectId.c_str ()); + + poa_creation_time.sec (::atol (seconds.c_str ())); + poa_creation_time.usec (::atol (micro_seconds.c_str ())); + + // Success return 0; } -TAO_HRESULT -CORBA_POA::QueryInterface (REFIID riid, - void **ppv) +CORBA::Boolean +TAO_POA::persistent (void) +{ + return this->policies ().lifespan () == PortableServer::PERSISTENT; +} + +const TAO_POA::String & +TAO_POA::object_key_type (void) +{ + if (this->persistent ()) + return TAO_POA::persistent_key_type (); + else + return TAO_POA::transient_key_type (); +} + +const TAO_POA::String & +TAO_POA::persistent_key_type (void) +{ + static TAO_POA::String persistent = "Persistent"; + return persistent; +} + +const TAO_POA::String & +TAO_POA::transient_key_type (void) +{ + static TAO_POA::String transient = "Transient"; + return transient; +} + +PortableServer::ObjectId * +TAO_POA::create_object_id (void) { - *ppv = 0; + // Note: This method assumes two things: + // 1. Locks are held when this method is called + // 2. Size of octet == size of string element + + // Buffer for counter + char counter[TAO_POA::max_space_required_for_ulong]; + + // Convert counter into string + ACE_OS::sprintf (counter, + "%d", + this->counter_); + + // Calculate the required buffer size. + // Note: 1 is for the null terminator + TAO_POA::String id = + this->name_ + + TAO_POA::id_separator () + + counter; + + // Increment counter + this->counter_++; + + // Create the sequence + return TAO_POA::string_to_ObjectId (id.c_str ()); +} + +TAO::ObjectKey * +TAO_POA::create_object_key (const PortableServer::ObjectId &id) +{ + // Buffer for seconds + char seconds[TAO_POA::max_space_required_for_ulong]; + // Buffer for micro seconds + char micro_seconds[TAO_POA::max_space_required_for_ulong]; + + // Convert seconds into string + ACE_OS::sprintf (seconds, + "%d", + this->creation_time_.sec ()); + + // Convert micro seconds into string + ACE_OS::sprintf (micro_seconds, + "%d", + this->creation_time_.usec ()); + + // Calculate the required buffer size. + // Note: 1 is for the null terminator + int buffer_size = + this->object_key_type ().length () + + TAO_POA::name_separator_length () + + ACE_OS::strlen (seconds) + + TAO_POA::name_separator_length () + + ACE_OS::strlen (micro_seconds) + + TAO_POA::name_separator_length () + + this->complete_name_.length () + + TAO_POA::name_separator_length () + + id.length () + + 1; + + // Create the buffer for the key + CORBA::Octet *buffer = TAO::ObjectKey::allocbuf (buffer_size); + + // Grab the id buffer + const char *id_buffer = TAO_POA::ObjectId_to_const_string (id); + + // Make an object key + ACE_OS::sprintf ((CORBA::String) buffer, + "%s%c%s%c%s%c%s%c%s", + this->object_key_type ().c_str (), + TAO_POA::name_separator (), + seconds, + TAO_POA::name_separator (), + micro_seconds, + TAO_POA::name_separator (), + this->complete_name_.c_str (), + TAO_POA::name_separator (), + id_buffer); + + // Create the key, giving the ownership of the buffer to the + // sequence. + return new TAO::ObjectKey (buffer_size, + buffer_size, + buffer, + CORBA::B_TRUE); +} + +int +TAO_POA::is_poa_generated_id (const PortableServer::ObjectId &id) +{ + // Grab the buffer + const char *id_buffer = TAO_POA::ObjectId_to_const_string (id); + + // Check to see if the POA name is the first part of the id + if (ACE_OS::strncmp (id_buffer, + this->name_.c_str (), + this->name_.length ()) == 0) + return 1; + else + return 0; +} - if (IID_POA == riid - || IID_TAO_IUnknown == riid) - *ppv = this; +int +TAO_POA::is_poa_generated_key (const TAO::ObjectKey &key) +{ + // Grab the buffer + const char *id_buffer = TAO_POA::ObjectKey_to_const_string (key); + + // Check to see if the POA name is the first part of the id + if (ACE_OS::strncmp (id_buffer, + this->complete_name_.c_str (), + this->complete_name_.length ()) == 0) + return 1; + else + return 0; +} - if (*ppv == 0) - return ResultFromScode (TAO_E_NOINTERFACE); +int +TAO_POA::leaf_poa_name (const TAO_POA::String &adapter_name, + CORBA::Environment &env) +{ + // This method does not throw any exceptions + ACE_UNUSED_ARG (env); - (void) AddRef (); - return TAO_NOERROR; + // Try to find the name separator + if (adapter_name.find (TAO_POA::name_separator ()) == TAO_POA::String::npos) + // If not found, the name was a leaf + return 1; + else + // If found, the name was not a leaf + return 0; } + +void +TAO_POA::parse_poa_name (const TAO_POA::String &adapter_name, + TAO_POA::String &topmost_poa_name, + TAO_POA::String &tail_poa_name, + CORBA::Environment &env) +{ + // Try to find the name separator + int token_position = adapter_name.find (TAO_POA::name_separator ()); + + // If not found, the name was a leaf, throw exception + if (token_position == TAO_POA::String::npos) + { + CORBA::Exception *exception = new CORBA::OBJ_ADAPTER (CORBA::COMPLETED_NO); + env.exception (exception); + return; + } + else + { + // If found, take the substring from 0 to token_position + int starting_at = 0; + int now_many = token_position - starting_at; + topmost_poa_name = adapter_name.substr (starting_at, + now_many); + + // Take the substring from (token_position + separator_length) + // to length + starting_at = token_position + TAO_POA::name_separator_length (); + now_many = adapter_name.length () - starting_at; + tail_poa_name = adapter_name.substr (starting_at, + now_many); + } +} + +CORBA::String +TAO_POA::the_name (CORBA::Environment &env) +{ + ACE_UNUSED_ARG (env); + + return CORBA::string_dup (this->name_.c_str ()); +} + +TAO_POA::String +TAO_POA::complete_name (void) +{ + return this->complete_name_; +} + +void +TAO_POA::set_complete_name (void) +{ + if (this->parent_ != 0) + { + this->complete_name_ += this->parent_->complete_name (); + this->complete_name_ += TAO_POA::name_separator (); + } + this->complete_name_ += this->name_; +} + +char * +TAO_POA::ObjectId_to_string (const PortableServer::ObjectId &id) +{ + // This method assumes that the id was initially placed in the octet + // sequence as a char string + + // Grab the id buffer + CORBA::String id_buffer = (CORBA::String) &id[0]; + + // Create space and copy the contents + return CORBA::string_dup (id_buffer); +} + +const char * +TAO_POA::ObjectId_to_const_string (const PortableServer::ObjectId &id) +{ + // This method assumes that the id was initially placed in the octet + // sequence as a char string + + // Grab the id buffer + return (CORBA::String) &id[0]; +} + +const char * +TAO_POA::ObjectKey_to_const_string (const TAO::ObjectKey &key) +{ + // Grab the id buffer + return (CORBA::String) &key[0]; +} + +PortableServer::ObjectId * +TAO_POA::string_to_ObjectId (const char *id) +{ + // Size of Id + CORBA::ULong id_length = ACE_OS::strlen (id) + 1; + + // Create the buffer for the Id + CORBA::Octet *buffer = PortableServer::ObjectId::allocbuf (id_length); + + // Copy contents + ACE_OS::strcpy ((CORBA::String) buffer, id); + + // Create a new ID + return new PortableServer::ObjectId (id_length, + id_length, + buffer, + CORBA::B_TRUE); +} + +PortableServer::ObjectId * +TAO_POA::wstring_to_ObjectId (const wchar_t *id) +{ + // Size of Id + CORBA::ULong id_length = ACE_OS::strlen (id) + 1; + + // Create the buffer for the Id + CORBA::Octet *buffer = PortableServer::ObjectId::allocbuf (id_length * sizeof (CORBA::WChar)); + + // Copy contents + ACE_OS::strcpy ((CORBA::WString) buffer, id); + + // Create a new ID + return new PortableServer::ObjectId (id_length, + id_length, + buffer, + CORBA::B_TRUE); +} + +wchar_t * +TAO_POA::ObjectId_to_wstring (const PortableServer::ObjectId &id) +{ + // This method assumes that the id was initially placed in the octet + // sequence as a wchar string + + // Grab the id buffer + CORBA::WString id_buffer = (CORBA::WString) &id[0]; + + // Create space and copy the contents + return CORBA::wstring_dup (id_buffer); +} + +const wchar_t * +TAO_POA::ObjectId_to_const_wstring (const PortableServer::ObjectId &id) +{ + // This method assumes that the id was initially placed in the octet + // sequence as a wchar string + + // Grab the id buffer + return (CORBA::WString) &id[0]; +} + +char +TAO_POA::name_separator (void) +{ + return '/'; +} + +char +TAO_POA::id_separator (void) +{ + return ':'; +} + +CORBA::ULong +TAO_POA::name_separator_length (void) +{ + return sizeof (char); +} + +CORBA::ULong +TAO_POA::id_separator_length (void) +{ + return sizeof (char); +} + +PortableServer::ThreadPolicy_ptr +TAO_POA::create_thread_policy (PortableServer::ThreadPolicyValue value, + CORBA::Environment &env) +{ + auto_ptr<TAO_Thread_Policy> new_policy (new TAO_Thread_Policy (value)); + PortableServer::ThreadPolicy_var result = new_policy->_this (env); + if (env.exception () != 0) + return PortableServer::ThreadPolicy::_nil (); + else + { + // Make sure that the auto_ptr does not delete the + // implementation + new_policy.release (); + return result._retn (); + } +} + +PortableServer::LifespanPolicy_ptr +TAO_POA::create_lifespan_policy (PortableServer::LifespanPolicyValue value, + CORBA::Environment &env) +{ + auto_ptr<TAO_Lifespan_Policy> new_policy (new TAO_Lifespan_Policy (value)); + PortableServer::LifespanPolicy_var result = new_policy->_this (env); + if (env.exception () != 0) + return PortableServer::LifespanPolicy::_nil (); + else + { + // Make sure that the auto_ptr does not delete the + // implementation + new_policy.release (); + return result._retn (); + } +} + +PortableServer::IdUniquenessPolicy_ptr +TAO_POA::create_id_uniqueness_policy (PortableServer::IdUniquenessPolicyValue value, + CORBA::Environment &env) +{ + auto_ptr<TAO_Id_Uniqueness_Policy> new_policy (new TAO_Id_Uniqueness_Policy (value)); + PortableServer::IdUniquenessPolicy_var result = new_policy->_this (env); + if (env.exception () != 0) + return PortableServer::IdUniquenessPolicy::_nil (); + else + { + // Make sure that the auto_ptr does not delete the + // implementation + new_policy.release (); + return result._retn (); + } +} + +PortableServer::IdAssignmentPolicy_ptr +TAO_POA::create_id_assignment_policy (PortableServer::IdAssignmentPolicyValue value, + CORBA::Environment &env) +{ + auto_ptr<TAO_Id_Assignment_Policy> new_policy (new TAO_Id_Assignment_Policy (value)); + PortableServer::IdAssignmentPolicy_var result = new_policy->_this (env); + if (env.exception () != 0) + return PortableServer::IdAssignmentPolicy::_nil (); + else + { + // Make sure that the auto_ptr does not delete the + // implementation + new_policy.release (); + return result._retn (); + } +} + +PortableServer::ImplicitActivationPolicy_ptr +TAO_POA::create_implicit_activation_policy (PortableServer::ImplicitActivationPolicyValue value, + CORBA::Environment &env) +{ + auto_ptr<TAO_Implicit_Activation_Policy> new_policy (new TAO_Implicit_Activation_Policy (value)); + PortableServer::ImplicitActivationPolicy_var result = new_policy->_this (env); + if (env.exception () != 0) + return PortableServer::ImplicitActivationPolicy::_nil (); + else + { + // Make sure that the auto_ptr does not delete the + // implementation + new_policy.release (); + return result._retn (); + } +} + +PortableServer::ServantRetentionPolicy_ptr +TAO_POA::create_servant_retention_policy (PortableServer::ServantRetentionPolicyValue value, + CORBA::Environment &env) +{ + auto_ptr<TAO_Servant_Retention_Policy> new_policy (new TAO_Servant_Retention_Policy (value)); + PortableServer::ServantRetentionPolicy_var result = new_policy->_this (env); + if (env.exception () != 0) + return PortableServer::ServantRetentionPolicy::_nil (); + else + { + // Make sure that the auto_ptr does not delete the + // implementation + new_policy.release (); + return result._retn (); + } +} + +PortableServer::RequestProcessingPolicy_ptr +TAO_POA::create_request_processing_policy (PortableServer::RequestProcessingPolicyValue value, + CORBA::Environment &env) +{ + auto_ptr<TAO_Request_Processing_Policy> new_policy (new TAO_Request_Processing_Policy (value)); + PortableServer::RequestProcessingPolicy_var result = new_policy->_this (env); + if (env.exception () != 0) + return PortableServer::RequestProcessingPolicy::_nil (); + else + { + // Make sure that the auto_ptr does not delete the + // implementation + new_policy.release (); + return result._retn (); + } +} + +CORBA::Boolean +TAO_Adapter_Activator::unknown_adapter (PortableServer::POA_ptr parent, + const char *name, + CORBA::Environment &env) +{ + // Default policies + PortableServer::PolicyList default_policies; + + // This assumes that the lock on the parent is recursive + PortableServer::POA_var child = parent->create_POA (name, + PortableServer::POAManager::_nil (), + default_policies, + env); + + if (env.exception () != 0) + return CORBA::B_FALSE; + else + { + PortableServer::AdapterActivator_var activator = this->_this (env); + if (env.exception () != 0) + { + child->destroy (CORBA::B_FALSE, + CORBA::B_FALSE, + env); + return CORBA::B_FALSE; + } + + child->the_activator (activator.in (), env); + + if (env.exception () != 0) + { + child->destroy (CORBA::B_FALSE, + CORBA::B_FALSE, + env); + return CORBA::B_FALSE; + } + + // Finally everything is fine + return CORBA::B_TRUE; + } +} + +TAO_POA_Manager::TAO_POA_Manager (void) + : state_ (HOLDING), + closing_down_ (0), + lock_ (), + poa_collection_ () +{ +} + +TAO_POA_Manager::~TAO_POA_Manager (void) +{ +} + +void +TAO_POA_Manager::activate (CORBA::Environment &env) +{ + // Lock access to the POAManager for the duration of this transaction + TAO_POA_WRITE_GUARD (ACE_Lock, monitor, this->lock (), env); + + // This operation changes the state of the POA manager to active. If + // issued while the POA manager is in the inactive state, the + // AdapterInactive exception is raised. Entering the active state + // enables the associated POAs to process requests. + + if (this->state_ == INACTIVE) + { + CORBA::Exception *exception = new PortableServer::POAManager::AdapterInactive; + env.exception (exception); + return; + } + else + this->state_ = ACTIVE; +} + +void +TAO_POA_Manager::hold_requests (CORBA::Boolean wait_for_completion, + CORBA::Environment &env) +{ + // Lock access to the POAManager for the duration of this transaction + TAO_POA_WRITE_GUARD (ACE_Lock, monitor, this->lock (), env); + + // This operation changes the state of the POA manager to + // holding. If issued while the POA manager is in the inactive + // state, the AdapterInactive exception is raised. Entering the + // holding state causes the associated POAs to queue incoming + // requests. Any requests that have been queued but have not + // started executing will continue to be queued while in the holding + // state. + + if (this->state_ == INACTIVE) + { + CORBA::Exception *exception = new PortableServer::POAManager::AdapterInactive; + env.exception (exception); + return; + } + else + this->state_ = HOLDING; + + // If the wait_for_completion parameter is FALSE, this operation + // returns immediately after changing the state. If the parameter is + // TRUE, this operation does not return until either there are no + // actively executing requests in any of the POAs associated with + // this POA manager (that is, all requests that were started prior + // to the state change have completed) or the state of the POA + // manager is changed to a state other than holding. + + ACE_UNUSED_ARG (wait_for_completion); +} + +void +TAO_POA_Manager::discard_requests (CORBA::Boolean wait_for_completion, + CORBA::Environment &env) +{ + // Lock access to the POAManager for the duration of this transaction + TAO_POA_WRITE_GUARD (ACE_Lock, monitor, this->lock (), env); + + // This operation changes the state of the POA manager to + // discarding. If issued while the POA manager is in the inactive + // state, the AdapterInactive exception is raised. Entering the + // discarding state causes the associated POAs to discard incoming + // requests. In addition, any requests that have been queued but + // have not started executing are discarded. When a request is + // discarded, a TRANSIENT system exception is returned to the + // client. + + if (this->state_ == INACTIVE) + { + CORBA::Exception *exception = new PortableServer::POAManager::AdapterInactive; + env.exception (exception); + return; + } + else + this->state_ = DISCARDING; + + // If the wait_for_completion parameter is FALSE, this operation + // returns immediately after changing the state. If the parameter is + // TRUE, this operation does not return until either there are no + // actively executing requests in any of the POAs associated with + // this POA manager (that is, all requests that were started prior + // to the state change have completed) or the state of the POA + // manager is changed to a state other than discarding. + + ACE_UNUSED_ARG (wait_for_completion); +} + +void +TAO_POA_Manager::deactivate (CORBA::Boolean etherealize_objects, + CORBA::Boolean wait_for_completion, + CORBA::Environment &env) +{ + // Lock access to the POAManager for the duration of this transaction + TAO_POA_WRITE_GUARD (ACE_Lock, monitor, this->lock (), env); + + this->closing_down_ = 1; + + // This operation changes the state of the POA manager to + // inactive. If issued while the POA manager is in the inactive + // state, the AdapterInactive exception is raised. Entering the + // inactive state causes the associated POAs to reject requests that + // have not begun to be executed as well as any new requests. + + if (this->state_ == INACTIVE) + { + CORBA::Exception *exception = new PortableServer::POAManager::AdapterInactive; + env.exception (exception); + return; + } + else + this->state_ = INACTIVE; + + // After changing the state, if the etherealize_objects parameter is: + // + // a) TRUE - the POA manager will cause all associated POAs that + // have the RETAIN and USE_SERVANT_MANAGER policies to perform the + // etherealize operation on the associated servant manager for all + // active objects. + // + // b) FALSE - the etherealize operation is not called. The purpose + // is to provide developers with a means to shut down POAs in a + // crisis (for example, unrecoverable error) situation. + + for (POA_COLLECTION::iterator iterator = this->poa_collection_.begin (); + iterator != this->poa_collection_.end () && env.exception () == 0; + iterator++) + { + TAO_POA *poa = *iterator; + poa->destroy (etherealize_objects, + wait_for_completion, + env); + } + + // If the wait_for_completion parameter is FALSE, this operation + // will return immediately after changing the state. If the + // parameter is TRUE, this operation does not return until there are + // no actively executing requests in any of the POAs associated with + // this POA manager (that is, all requests that were started prior + // to the state change have completed) and, in the case of a TRUE + // etherealize_objects, all invocations of etherealize have + // completed for POAs having the RETAIN and USE_SERVANT_MANAGER + // policies. + + // If the ORB::shutdown operation is called, it makes a call on + // deactivate with a TRUE etherealize_objects parameter for each POA + // manager known in the process; the wait_for_completion parameter + // to deactivate will be the same as the similarly named parameter + // of ORB::shutdown. +} + +TAO_POA_Manager::Processing_State +TAO_POA_Manager::state (CORBA::Environment &env) +{ + // Lock access to the POAManager for the duration of this transaction + TAO_POA_READ_GUARD_RETURN (ACE_Lock, monitor, this->lock (), UNKNOWN, env); + + return this->state_; +} + +void +TAO_POA_Manager::remove_poa (TAO_POA *poa, + CORBA::Environment &env) +{ + // If we are not closing down, we must remove this poa from our + // collection. + if (!this->closing_down_) + { + // Lock access to the POAManager for the duration of this transaction + TAO_POA_WRITE_GUARD (ACE_Lock, monitor, this->lock (), env); + + this->remove_poa_i (poa, + env); + } + + // If we are closing down, we are currently iterating over our poa + // collection and there is not need to remove this poa from our + // collection. +} + +void +TAO_POA_Manager::remove_poa_i (TAO_POA *poa, + CORBA::Environment &env) +{ + int result = this->poa_collection_.remove (poa); + + if (result != 0) + { + CORBA::Exception *exception = new CORBA::OBJ_ADAPTER (CORBA::COMPLETED_NO); + env.exception (exception); + return; + } +} + +void +TAO_POA_Manager::register_poa (TAO_POA *poa, + CORBA::Environment &env) +{ + // Lock access to the POAManager for the duration of this transaction + TAO_POA_WRITE_GUARD (ACE_Lock, monitor, this->lock (), env); + + this->register_poa_i (poa, + env); +} + +void +TAO_POA_Manager::register_poa_i (TAO_POA *poa, + CORBA::Environment &env) +{ + int result = this->poa_collection_.insert (poa); + + if (result != 0) + { + CORBA::Exception *exception = new CORBA::OBJ_ADAPTER (CORBA::COMPLETED_NO); + env.exception (exception); + return; + } +} + +ACE_Lock & +TAO_POA_Manager::lock (void) +{ + return this->lock_; +} + +TAO_POA_Manager * +TAO_POA_Manager::clone (void) +{ + return new TAO_POA_Manager; +} + +TAO_Strategy_POA::TAO_Strategy_POA (const TAO_POA::String &adapter_name, + TAO_POA_Manager &poa_manager, + const TAO_POA_Policies &policies, + TAO_POA *parent, + CORBA::Environment &env) + : TAO_POA (adapter_name, + poa_manager, + policies, + parent, + env), + lock_ (0) +{ + this->lock_ = TAO_ORB_Core_instance ()->server_factory ()->create_poa_lock (); +} + +TAO_Strategy_POA::TAO_Strategy_POA (const TAO_POA::String &adapter_name, + TAO_POA_Manager &poa_manager, + const TAO_POA_Policies &policies, + TAO_POA *parent, + TAO_Object_Table &active_object_map, + CORBA::Environment &env) + : TAO_POA (adapter_name, + poa_manager, + policies, + parent, + active_object_map, + env), + lock_ (0) +{ + this->lock_ = TAO_ORB_Core_instance ()->server_factory ()->create_poa_lock (); +} + +TAO_Strategy_POA::~TAO_Strategy_POA (void) +{ + delete this->lock_; +} + +TAO_POA * +TAO_Strategy_POA::clone (const TAO_POA::String &adapter_name, + TAO_POA_Manager &poa_manager, + const TAO_POA_Policies &policies, + TAO_POA *parent, + CORBA::Environment &env) +{ + return new SELF (adapter_name, + poa_manager, + policies, + parent, + env); +} + +TAO_POA * +TAO_Strategy_POA::clone (const TAO_POA::String &adapter_name, + TAO_POA_Manager &poa_manager, + const TAO_POA_Policies &policies, + TAO_POA *parent, + TAO_Object_Table &active_object_map, + CORBA::Environment &env) +{ + return new SELF (adapter_name, + poa_manager, + policies, + parent, + active_object_map, + env); +} + +ACE_Lock & +TAO_Strategy_POA::lock (void) +{ + return *this->lock_; +} + +TAO_Strategy_POA_Manager::TAO_Strategy_POA_Manager (void) + : TAO_POA_Manager (), + lock_ (0) +{ + this->lock_ = TAO_ORB_Core_instance ()->server_factory ()->create_poa_mgr_lock (); +} + +TAO_Strategy_POA_Manager::~TAO_Strategy_POA_Manager (void) +{ + delete this->lock_; +} + +TAO_POA_Manager * +TAO_Strategy_POA_Manager::clone (void) +{ + return new SELF; +} + +ACE_Lock & +TAO_Strategy_POA_Manager::lock (void) +{ + return *this->lock_; +} + +TAO_POA_Current::TAO_POA_Current (void) + : poa_impl_ (0), + object_id_ (0), + servant_ (0), + object_key_ (0), + cookie_ (0) +{ +} + +TAO_POA_Current::~TAO_POA_Current (void) +{ +} + +PortableServer::POA_ptr +TAO_POA_Current::get_POA (CORBA::Environment &env) +{ + if (!this->context_is_valid ()) + { + CORBA::Exception *exception = new PortableServer::Current::NoContext; + env.exception (exception); + return PortableServer::POA::_nil (); + } + + PortableServer::POA_var result = this->poa_impl_->_this (env); + if (env.exception () != 0) + return PortableServer::POA::_nil (); + else + return result._retn (); +} + +PortableServer::ObjectId * +TAO_POA_Current::get_object_id (CORBA::Environment &env) +{ + if (!this->context_is_valid ()) + { + CORBA::Exception *exception = new PortableServer::Current::NoContext; + env.exception (exception); + return 0; + } + + // Create a new one and pass it back + return new PortableServer::ObjectId (*this->object_id_); +} + +void +TAO_POA_Current::clear (void) +{ + this->poa_impl_ = 0; + this->object_id_ = 0; + this->servant_ = 0; + this->object_key_ = 0; + this->cookie_ = 0; +} + +int +TAO_POA_Current::context_is_valid (void) +{ + return + this->poa_impl_ != 0 && + this->object_id_ != 0 && + this->servant_ != 0 && + this->object_key_ != 0; +} + +void +TAO_POA_Current::POA_impl (TAO_POA *impl) +{ + this->poa_impl_ = impl; +} + +TAO_POA * +TAO_POA_Current::POA_impl (void) const +{ + return this->poa_impl_; +} + +void +TAO_POA_Current::object_id (const PortableServer::ObjectId &id) +{ + this->object_id_ = &id; +} + +const PortableServer::ObjectId & +TAO_POA_Current::object_id (void) const +{ + return *this->object_id_; +} + +void +TAO_POA_Current::object_key (const TAO::ObjectKey &key) +{ + this->object_key_ = &key; +} + +const TAO::ObjectKey & +TAO_POA_Current::object_key (void) const +{ + return *this->object_key_; +} + +void +TAO_POA_Current::servant (PortableServer::Servant servant) +{ + this->servant_ = servant; +} + +PortableServer::Servant +TAO_POA_Current::servant (void) const +{ + return this->servant_; +} + +int +TAO_POA_Current::in_upcall (void) const +{ + return (this->servant_ != 0); +} + +PortableServer::ServantLocator::Cookie +TAO_POA_Current::locator_cookie (void) const +{ + return this->cookie_; +} + +void +TAO_POA_Current::locator_cookie (PortableServer::ServantLocator::Cookie cookie) +{ + this->cookie_ = cookie; +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_Auto_Basic_Ptr<TAO_Id_Assignment_Policy>; +template class ACE_Auto_Basic_Ptr<TAO_Id_Uniqueness_Policy>; +template class ACE_Auto_Basic_Ptr<TAO_Implicit_Activation_Policy>; +template class ACE_Auto_Basic_Ptr<TAO_Lifespan_Policy>; +template class ACE_Auto_Basic_Ptr<TAO_Object_Table_Iterator_Impl>; +template class ACE_Auto_Basic_Ptr<TAO_POA>; +template class ACE_Auto_Basic_Ptr<TAO_Request_Processing_Policy>; +template class ACE_Auto_Basic_Ptr<TAO_Servant_Retention_Policy>; +template class ACE_Auto_Basic_Ptr<TAO_Thread_Policy>; +template class ACE_Lock_Adapter<ACE_Null_Mutex>; +template class ACE_Lock_Adapter<ACE_Recursive_Thread_Mutex>; +template class ACE_Lock_Adapter<ACE_Thread_Mutex>; +template class ACE_Map_Entry<TAO_Unbounded_Sequence<unsigned char>, TAO_ServantBase *>; +template class ACE_Map_Iterator<ACE_CString, TAO_POA *, ACE_Null_Mutex>; +template class ACE_Map_Iterator_Base<ACE_CString, TAO_POA *, ACE_Null_Mutex>; +template class ACE_Map_Manager<ACE_CString, TAO_POA *, ACE_Null_Mutex>; +template class ACE_Read_Guard<ACE_Lock>; +template class ACE_Unbounded_Set<TAO_POA *>; +template class ACE_Unbounded_Set_Iterator<TAO_POA *>; +template class ACE_Write_Guard<ACE_Lock>; +template class TAO_Object_Manager<PortableServer::Policy>; +template class TAO_Unbounded_Object_Sequence<PortableServer::Policy>; +template class auto_ptr<TAO_Id_Assignment_Policy>; +template class auto_ptr<TAO_Id_Uniqueness_Policy>; +template class auto_ptr<TAO_Implicit_Activation_Policy>; +template class auto_ptr<TAO_Lifespan_Policy>; +template class auto_ptr<TAO_Object_Table_Iterator_Impl>; +template class auto_ptr<TAO_POA>; +template class auto_ptr<TAO_Request_Processing_Policy>; +template class auto_ptr<TAO_Servant_Retention_Policy>; +template class auto_ptr<TAO_Thread_Policy>; +template class ACE_Map_Entry<ACE_CString, TAO_POA *>; +template class ACE_Map_Reverse_Iterator<ACE_CString, TAO_POA *, ACE_Null_Mutex>; +template class ACE_Node<TAO_POA *>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate ACE_Auto_Basic_Ptr<TAO_Id_Assignment_Policy> +#pragma instantiate ACE_Auto_Basic_Ptr<TAO_Id_Uniqueness_Policy> +#pragma instantiate ACE_Auto_Basic_Ptr<TAO_Implicit_Activation_Policy> +#pragma instantiate ACE_Auto_Basic_Ptr<TAO_Lifespan_Policy> +#pragma instantiate ACE_Auto_Basic_Ptr<TAO_Object_Table_Iterator_Impl> +#pragma instantiate ACE_Auto_Basic_Ptr<TAO_POA> +#pragma instantiate ACE_Auto_Basic_Ptr<TAO_Request_Processing_Policy> +#pragma instantiate ACE_Auto_Basic_Ptr<TAO_Servant_Retention_Policy> +#pragma instantiate ACE_Auto_Basic_Ptr<TAO_Thread_Policy> +#pragma instantiate ACE_Lock_Adapter<ACE_Null_Mutex> +#pragma instantiate ACE_Lock_Adapter<ACE_Recursive_Thread_Mutex> +#pragma instantiate ACE_Lock_Adapter<ACE_Thread_Mutex> +#pragma instantiate ACE_Map_Entry<TAO_Unbounded_Sequence<unsigned char>, TAO_ServantBase *> +#pragma instantiate ACE_Map_Iterator<ACE_CString, TAO_POA *, ACE_Null_Mutex> +#pragma instantiate ACE_Map_Iterator_Base<ACE_CString, TAO_POA *, ACE_Null_Mutex> +#pragma instantiate ACE_Map_Manager<ACE_CString, TAO_POA *, ACE_Null_Mutex> +#pragma instantiate ACE_Read_Guard<ACE_Lock> +#pragma instantiate ACE_Unbounded_Set<TAO_POA *> +#pragma instantiate ACE_Unbounded_Set_Iterator<TAO_POA *> +#pragma instantiate ACE_Write_Guard<ACE_Lock> +#pragma instantiate TAO_Object_Manager<PortableServer::Policy> +#pragma instantiate TAO_Unbounded_Object_Sequence<PortableServer::Policy> +#pragma instantiate auto_ptr<TAO_Id_Assignment_Policy> +#pragma instantiate auto_ptr<TAO_Id_Uniqueness_Policy> +#pragma instantiate auto_ptr<TAO_Implicit_Activation_Policy> +#pragma instantiate auto_ptr<TAO_Lifespan_Policy> +#pragma instantiate auto_ptr<TAO_Object_Table_Iterator_Impl> +#pragma instantiate auto_ptr<TAO_POA> +#pragma instantiate auto_ptr<TAO_Request_Processing_Policy> +#pragma instantiate auto_ptr<TAO_Servant_Retention_Policy> +#pragma instantiate auto_ptr<TAO_Thread_Policy> +#pragma instantiate ACE_Map_Entry<ACE_CString, TAO_POA *> +#pragma instantiate ACE_Map_Reverse_Iterator<ACE_CString, TAO_POA *, ACE_Null_Mutex> +#pragma instantiate ACE_Node<TAO_POA *> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ |