summaryrefslogtreecommitdiff
path: root/TAO/tao/PortableServer/Object_Adapter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/tao/PortableServer/Object_Adapter.cpp')
-rw-r--r--TAO/tao/PortableServer/Object_Adapter.cpp1338
1 files changed, 1338 insertions, 0 deletions
diff --git a/TAO/tao/PortableServer/Object_Adapter.cpp b/TAO/tao/PortableServer/Object_Adapter.cpp
new file mode 100644
index 00000000000..eba1da2172c
--- /dev/null
+++ b/TAO/tao/PortableServer/Object_Adapter.cpp
@@ -0,0 +1,1338 @@
+// $Id$
+
+// -- PortableServer Include --
+#include "tao/PortableServer/Object_Adapter.h"
+#include "tao/PortableServer/Non_Servant_Upcall.h"
+#include "tao/PortableServer/Servant_Upcall.h"
+#include "tao/PortableServer/Root_POA.h"
+#include "tao/PortableServer/Regular_POA.h"
+#include "tao/PortableServer/Creation_Time.h"
+#include "tao/PortableServer/POA_Guard.h"
+#include "tao/PortableServer/Default_Servant_Dispatcher.h"
+#include "tao/PortableServer/Collocated_Object_Proxy_Broker.h"
+#include "tao/PortableServer/POAManager.h"
+#include "tao/PortableServer/POAManagerFactory.h"
+#include "tao/PortableServer/Servant_Base.h"
+
+// -- ACE Include --
+#include "ace/Auto_Ptr.h"
+#include "ace/Log_Msg.h"
+#include "ace/OS_NS_string.h"
+
+// -- TAO Include --
+#include "tao/PortableInterceptorC.h"
+#include "tao/ORB.h"
+#include "tao/ORB_Core.h"
+#include "tao/TSS_Resources.h"
+#include "tao/TAO_Server_Request.h"
+#include "tao/Stub.h"
+#include "tao/Profile.h"
+#include "tao/MProfile.h"
+#include "tao/debug.h"
+#include "tao/PortableInterceptor.h"
+#include "tao/ORBInitializer_Registry.h"
+#include "tao/Thread_Lane_Resources_Manager.h"
+#include "tao/Thread_Lane_Resources.h"
+#include "tao/Protocols_Hooks.h"
+#include "tao/ServerRequestInterceptor_Adapter.h"
+
+#if !defined (__ACE_INLINE__)
+# include "tao/PortableServer/Object_Adapter.inl"
+#endif /* __ACE_INLINE__ */
+
+#include "tao/PortableServer/ThreadPolicy.h"
+#include "tao/PortableServer/LifespanPolicy.h"
+#include "tao/PortableServer/IdAssignmentPolicy.h"
+#include "tao/PortableServer/IdUniquenessPolicy.h"
+#include "tao/PortableServer/ImplicitActivationPolicy.h"
+#include "tao/PortableServer/RequestProcessingPolicy.h"
+#include "tao/PortableServer/ServantRetentionPolicy.h"
+
+ACE_RCSID (PortableServer,
+ Object_Adapter,
+ "$Id$")
+
+#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
+namespace PortableServer
+{
+ class POAManagerFactory;
+ typedef POAManagerFactory *POAManagerFactory_ptr;
+}
+#endif
+
+// Timeprobes class
+#include "tao/Timeprobe.h"
+
+#if defined (ACE_ENABLE_TIMEPROBES)
+
+static const char *TAO_Object_Adapter_Timeprobe_Description[] =
+{
+ "Object_Adapter::dispatch_servant - start",
+ "Object_Adapter::dispatch_servant - end",
+
+ "POA::parse_key - start",
+ "POA::parse_key - end",
+
+ "Object_Adapter::find_poa - start",
+ "Object_Adapter::find_poa - end",
+
+ "POA::locate_servant - start",
+ "POA::locate_servant - end",
+
+ "Servant::_dispatch - start",
+ "Servant::_dispatch - end",
+};
+
+enum
+{
+ // Timeprobe description table start key
+ TAO_OBJECT_ADAPTER_DISPATCH_SERVANT_START = 200,
+ TAO_OBJECT_ADAPTER_DISPATCH_SERVANT_END,
+
+ TAO_POA_PARSE_KEY_START,
+ TAO_POA_PARSE_KEY_END,
+
+ TAO_OBJECT_ADAPTER_FIND_POA_START,
+ TAO_OBJECT_ADAPTER_FIND_POA_END,
+
+ TAO_POA_LOCATE_SERVANT_START,
+ TAO_POA_LOCATE_SERVANT_END,
+
+ TAO_SERVANT_DISPATCH_START,
+ TAO_SERVANT_DISPATCH_END
+};
+
+// Setup Timeprobes
+ACE_TIMEPROBE_EVENT_DESCRIPTIONS (TAO_Object_Adapter_Timeprobe_Description,
+ TAO_OBJECT_ADAPTER_DISPATCH_SERVANT_START);
+
+#endif /* ACE_ENABLE_TIMEPROBES */
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+/* static */
+CORBA::ULong TAO_Object_Adapter::transient_poa_name_size_ = 0;
+
+void
+TAO_Object_Adapter::set_transient_poa_name_size (const TAO_Server_Strategy_Factory::Active_Object_Map_Creation_Parameters &creation_parameters)
+{
+ if (TAO_Object_Adapter::transient_poa_name_size_ == 0)
+ {
+ switch (creation_parameters.poa_lookup_strategy_for_transient_id_policy_)
+ {
+#if (TAO_HAS_MINIMUM_POA_MAPS == 0)
+ case TAO_LINEAR:
+ TAO_Object_Adapter::transient_poa_name_size_ =
+ sizeof (CORBA::ULong);
+ break;
+ case TAO_DYNAMIC_HASH:
+ TAO_Object_Adapter::transient_poa_name_size_ =
+ sizeof (CORBA::ULong);
+ break;
+#endif /* TAO_HAS_MINIMUM_POA_MAPS == 0 */
+ case TAO_ACTIVE_DEMUX:
+ default:
+ TAO_Object_Adapter::transient_poa_name_size_ =
+ static_cast <CORBA::ULong>(
+ ACE_Active_Map_Manager_Key::size ());
+ break;
+ }
+ }
+}
+
+TAO_Object_Adapter::TAO_Object_Adapter (const TAO_Server_Strategy_Factory::Active_Object_Map_Creation_Parameters &creation_parameters,
+ TAO_ORB_Core &orb_core)
+ : hint_strategy_ (0),
+ servant_dispatcher_ (0),
+ persistent_poa_name_map_ (0),
+ transient_poa_map_ (0),
+ orb_core_ (orb_core),
+ enable_locking_ (orb_core_.server_factory ()->enable_poa_locking ()),
+ thread_lock_ (),
+ lock_ (TAO_Object_Adapter::create_lock (enable_locking_,
+ thread_lock_)),
+ reverse_lock_ (*lock_),
+ non_servant_upcall_condition_ (thread_lock_),
+ non_servant_upcall_in_progress_ (0),
+ non_servant_upcall_nesting_level_ (0),
+ non_servant_upcall_thread_ (ACE_OS::NULL_thread),
+ root_ (0),
+#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
+ poa_manager_factory_ (0),
+#endif
+ default_validator_ (orb_core),
+ default_poa_policies_ ()
+{
+ TAO_Object_Adapter::set_transient_poa_name_size (creation_parameters);
+
+ Hint_Strategy *hint_strategy = 0;
+ if (creation_parameters.use_active_hint_in_poa_names_)
+ ACE_NEW (hint_strategy,
+ Active_Hint_Strategy (creation_parameters.poa_map_size_));
+ else
+ ACE_NEW (hint_strategy,
+ No_Hint_Strategy);
+
+ // Give ownership to the auto pointer.
+ auto_ptr<Hint_Strategy> new_hint_strategy (hint_strategy);
+
+ new_hint_strategy->object_adapter (this);
+
+ persistent_poa_name_map *ppnm = 0;
+ switch (creation_parameters.poa_lookup_strategy_for_persistent_id_policy_)
+ {
+ case TAO_LINEAR:
+#if (TAO_HAS_MINIMUM_POA_MAPS == 0)
+ ACE_NEW (ppnm,
+ persistent_poa_name_linear_map (creation_parameters.poa_map_size_));
+
+ break;
+#else
+ ACE_ERROR ((LM_ERROR,
+ "linear option for -ORBPersistentidPolicyDemuxStrategy "
+ "not supported with minimum POA maps. "
+ "Ingoring option to use default... \n"));
+ /* FALL THROUGH */
+#endif /* TAO_HAS_MINIMUM_POA_MAPS == 0 */
+ case TAO_DYNAMIC_HASH:
+ default:
+ ACE_NEW (ppnm,
+ persistent_poa_name_hash_map (creation_parameters.poa_map_size_));
+ break;
+ }
+ // Give ownership to the auto pointer.
+ auto_ptr<persistent_poa_name_map> new_persistent_poa_name_map (ppnm);
+
+ transient_poa_map *tpm = 0;
+ switch (creation_parameters.poa_lookup_strategy_for_transient_id_policy_)
+ {
+#if (TAO_HAS_MINIMUM_POA_MAPS == 0)
+ case TAO_LINEAR:
+ ACE_NEW (tpm,
+ transient_poa_linear_map (creation_parameters.poa_map_size_));
+ break;
+ case TAO_DYNAMIC_HASH:
+ ACE_NEW (tpm,
+ transient_poa_hash_map (creation_parameters.poa_map_size_));
+ break;
+#else
+ case TAO_LINEAR:
+ case TAO_DYNAMIC_HASH:
+ ACE_ERROR ((LM_ERROR,
+ "linear and dynamic options for -ORBTransientidPolicyDemuxStrategy "
+ "are not supported with minimum POA maps. "
+ "Ingoring option to use default... \n"));
+ /* FALL THROUGH */
+#endif /* TAO_HAS_MINIMUM_POA_MAPS == 0 */
+ case TAO_ACTIVE_DEMUX:
+ default:
+ ACE_NEW (tpm,
+ transient_poa_active_map (creation_parameters.poa_map_size_));
+ break;
+ }
+ // Give ownership to the auto pointer.
+ auto_ptr<transient_poa_map> new_transient_poa_map (tpm);
+
+ this->hint_strategy_ =
+ new_hint_strategy.release ();
+ this->persistent_poa_name_map_ =
+ new_persistent_poa_name_map.release ();
+ this->transient_poa_map_ =
+ new_transient_poa_map.release ();
+}
+
+void
+TAO_Object_Adapter::init_default_policies (TAO_POA_Policy_Set &policies
+ ACE_ENV_ARG_DECL)
+{
+ // Initialize the default policies.
+#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
+
+ TAO::Portable_Server::ThreadPolicy thread_policy (PortableServer::ORB_CTRL_MODEL);
+ policies.merge_policy (&thread_policy ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+#endif /* TAO_HAS_MINIMUM_POA == 0 */
+
+#if !defined (CORBA_E_MICRO)
+ // Lifespan policy.
+ TAO::Portable_Server::LifespanPolicy lifespan_policy (PortableServer::TRANSIENT);
+ policies.merge_policy (&lifespan_policy ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+#endif
+
+#if !defined (CORBA_E_MICRO)
+ // ID uniqueness policy.
+ TAO::Portable_Server::IdUniquenessPolicy id_uniqueness_policy (PortableServer::UNIQUE_ID);
+ policies.merge_policy (&id_uniqueness_policy ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+#endif
+
+#if !defined (CORBA_E_MICRO)
+ // ID assignment policy.
+ TAO::Portable_Server::IdAssignmentPolicy id_assignment_policy (PortableServer::SYSTEM_ID);
+ policies.merge_policy (&id_assignment_policy ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+#endif
+
+#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
+ // Implicit activation policy.
+ TAO::Portable_Server::ImplicitActivationPolicy implicit_activation_policy
+ (PortableServer::NO_IMPLICIT_ACTIVATION);
+ policies.merge_policy (&implicit_activation_policy ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // Servant retention policy.
+ TAO::Portable_Server::ServantRetentionPolicy servant_retention_policy
+ (PortableServer::RETAIN);
+ policies.merge_policy (&servant_retention_policy ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // Request processing policy.
+ TAO::Portable_Server::RequestProcessingPolicy request_processing_policy
+ (PortableServer::USE_ACTIVE_OBJECT_MAP_ONLY);
+ policies.merge_policy (&request_processing_policy ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+#endif /* TAO_HAS_MINIMUM_POA == 0 */
+#if defined (CORBA_E_MICRO)
+ ACE_UNUSED_ARG (policies);
+#endif
+}
+
+TAO_Object_Adapter::~TAO_Object_Adapter (void)
+{
+ delete this->hint_strategy_;
+ delete this->persistent_poa_name_map_;
+ delete this->transient_poa_map_;
+ delete this->lock_;
+
+ delete this->servant_dispatcher_;
+
+ // This cleanup may have already occurred in the close() method. If
+ // that is the case then this won't cause any harm since root_ and
+ // poa_manager_factory_ would have been set to zero. But, if close
+ // wasn't called, then these would be leaked. It may be better if
+ // these pointers had a corresponding _var version so that this cleanup
+ // could be automatic.
+ ::CORBA::release (this->root_);
+#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
+ release_poa_manager_factory (this->poa_manager_factory_);
+#endif
+}
+
+/* static */
+ACE_Lock *
+TAO_Object_Adapter::create_lock (int enable_locking,
+ TAO_SYNCH_MUTEX &thread_lock)
+{
+#if defined (ACE_HAS_THREADS)
+ if (enable_locking)
+ {
+ ACE_Lock *the_lock = 0;
+ ACE_NEW_RETURN (the_lock,
+ ACE_Lock_Adapter<TAO_SYNCH_MUTEX> (thread_lock),
+ 0);
+ return the_lock;
+ }
+#else
+ ACE_UNUSED_ARG (enable_locking);
+ ACE_UNUSED_ARG (thread_lock);
+#endif /* ACE_HAS_THREADS */
+
+ ACE_Lock *the_lock = 0;
+ ACE_NEW_RETURN (the_lock,
+ ACE_Lock_Adapter<ACE_SYNCH_NULL_MUTEX> (),
+ 0);
+ return the_lock;
+}
+
+int
+TAO_Object_Adapter::dispatch_servant (const TAO::ObjectKey &key,
+ TAO_ServerRequest &req,
+ CORBA::Object_out forward_to
+ ACE_ENV_ARG_DECL)
+{
+ ACE_FUNCTION_TIMEPROBE (TAO_OBJECT_ADAPTER_DISPATCH_SERVANT_START);
+
+ // This object is magical, i.e., it has a non-trivial constructor
+ // and destructor.
+ TAO::Portable_Server::Servant_Upcall servant_upcall (&this->orb_core_);
+
+ // Set up state in the POA et al (including the POA Current), so
+ // that we know that this servant is currently in an upcall.
+ const char *operation = req.operation ();
+ int result =
+ servant_upcall.prepare_for_upcall (key,
+ operation,
+ forward_to
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (result);
+
+ if (result != TAO_Adapter::DS_OK)
+ return result;
+
+ // Preprocess request.
+ if (req.collocated ())
+ {
+ servant_upcall.pre_invoke_collocated_request (
+ ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (result);
+ }
+ else
+ {
+ servant_upcall.pre_invoke_remote_request (req
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (result);
+ }
+
+ // Servant dispatch.
+ {
+ ACE_FUNCTION_TIMEPROBE (TAO_SERVANT_DISPATCH_START);
+
+ do_dispatch (req, servant_upcall ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (result);
+ }
+
+#if TAO_HAS_INTERCEPTORS == 1
+ // ServerInterceptor might have raised ForwardRequest. In case of
+ // remote calls invocations the LocationForwardReply would have been
+ // sent in earlier stage, but in colocal scenario no message is sent
+ // and the LocationForward object must be passed over here to
+ // calling operation's mem-space.
+ if (req.collocated() && req.reply_status () == PortableInterceptor::LOCATION_FORWARD)
+ {
+ forward_to = CORBA::Object::_duplicate (req.forward_location ());
+ result = TAO_Adapter::DS_FORWARD;
+ }
+#endif
+
+ return result;
+}
+
+void
+TAO_Object_Adapter::locate_poa (const TAO::ObjectKey &key,
+ PortableServer::ObjectId &system_id,
+ TAO_Root_POA *&poa
+ ACE_ENV_ARG_DECL)
+{
+ TAO_Object_Adapter::poa_name poa_system_name;
+ CORBA::Boolean is_root = false;
+ CORBA::Boolean is_persistent = false;
+ CORBA::Boolean is_system_id = false;
+ TAO::Portable_Server::Temporary_Creation_Time poa_creation_time;
+
+ int result = 0;
+
+ {
+ ACE_FUNCTION_TIMEPROBE (TAO_POA_PARSE_KEY_START);
+
+ result = TAO_Root_POA::parse_key (key,
+ poa_system_name,
+ system_id,
+ is_root,
+ is_persistent,
+ is_system_id,
+ poa_creation_time);
+ }
+
+ if (result != 0)
+ ACE_THROW (CORBA::OBJ_ADAPTER ());
+
+ {
+ ACE_FUNCTION_TIMEPROBE (TAO_OBJECT_ADAPTER_FIND_POA_START);
+
+ result = this->find_poa (poa_system_name,
+ is_persistent,
+ is_root,
+ poa_creation_time,
+ poa
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ if (result != 0)
+ ACE_THROW (CORBA::OBJECT_NOT_EXIST (CORBA::OMGVMCID | 2,
+ CORBA::COMPLETED_NO));
+}
+
+int
+TAO_Object_Adapter::activate_poa (const poa_name &folded_name,
+ TAO_Root_POA *&poa
+ ACE_ENV_ARG_DECL)
+{
+ int result = -1;
+
+#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_MICRO)
+
+ iteratable_poa_name ipn (folded_name);
+ iteratable_poa_name::iterator iterator = ipn.begin ();
+ iteratable_poa_name::iterator end = ipn.end ();
+
+ TAO_Root_POA *parent = this->root_;
+ if (parent == 0 || parent->name () != *iterator)
+ ACE_THROW_RETURN (CORBA::OBJ_ADAPTER (),
+ -1);
+ else
+ ++iterator;
+
+ for (;
+ iterator != end;
+ ++iterator)
+ {
+ TAO_Root_POA *current = 0;
+
+ ACE_TRY
+ {
+ current = parent->find_POA_i (*iterator,
+ 1
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCH (PortableServer::POA::AdapterNonExistent, ex)
+ {
+ return -1;
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (-1);
+
+ parent = current;
+ }
+
+ poa = parent;
+ result = 0;
+#else
+ ACE_UNUSED_ARG (folded_name);
+ ACE_UNUSED_ARG (poa);
+ ACE_ENV_ARG_NOT_USED; // FUZZ: ignore check_for_ace_check
+#endif /* TAO_HAS_MINIMUM_POA == 0 */
+
+ return result;
+}
+
+int
+TAO_Object_Adapter::find_transient_poa (const poa_name &system_name,
+ CORBA::Boolean root,
+ const TAO::Portable_Server::Temporary_Creation_Time &poa_creation_time,
+ TAO_Root_POA *&poa
+ ACE_ENV_ARG_DECL_NOT_USED)
+{
+ int result = 0;
+
+ if (root)
+ {
+ poa = this->root_;
+ }
+ else
+ {
+ result = this->transient_poa_map_->find (system_name,
+ poa);
+ }
+
+ if (poa == 0
+ || (result == 0 && !poa->validate_lifespan (false, poa_creation_time)))
+ result = -1;
+
+ return result;
+}
+
+int
+TAO_Object_Adapter::bind_poa (const poa_name &folded_name,
+ TAO_Root_POA *poa,
+ poa_name_out system_name)
+{
+ if (poa->persistent ())
+ return this->bind_persistent_poa (folded_name,
+ poa,
+ system_name);
+ else
+ return this->bind_transient_poa (poa,
+ system_name);
+}
+
+int
+TAO_Object_Adapter::unbind_poa (TAO_Root_POA *poa,
+ const poa_name &folded_name,
+ const poa_name &system_name)
+{
+ if (poa->persistent ())
+ return this->unbind_persistent_poa (folded_name,
+ system_name);
+ else
+ return this->unbind_transient_poa (system_name);
+}
+
+int
+TAO_Object_Adapter::locate_servant_i (const TAO::ObjectKey &key
+ ACE_ENV_ARG_DECL)
+{
+ ACE_FUNCTION_TIMEPROBE (TAO_POA_LOCATE_SERVANT_START);
+
+ PortableServer::ObjectId id;
+ TAO_Root_POA *poa = 0;
+
+ this->locate_poa (key,
+ id,
+ poa
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ PortableServer::Servant servant = 0;
+ TAO_SERVANT_LOCATION servant_location =
+ poa->locate_servant_i (id,
+ servant
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+
+ switch (servant_location)
+ {
+ case TAO_SERVANT_FOUND:
+ // Optimistic attitude
+ case TAO_DEFAULT_SERVANT:
+ case TAO_SERVANT_MANAGER:
+ return 0;
+
+ case TAO_SERVANT_NOT_FOUND:
+ return -1;
+ }
+
+ return -1;
+}
+
+TAO_SERVANT_LOCATION
+TAO_Object_Adapter::find_servant_i (const TAO::ObjectKey &key,
+ PortableServer::Servant &servant
+ ACE_ENV_ARG_DECL)
+{
+ PortableServer::ObjectId id;
+ TAO_Root_POA *poa = 0;
+
+ this->locate_poa (key,
+ id,
+ poa
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO_SERVANT_NOT_FOUND);
+
+ TAO_SERVANT_LOCATION servant_location = poa->locate_servant_i (id,
+ servant
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (TAO_SERVANT_NOT_FOUND);
+
+ return servant_location;
+}
+
+void
+TAO_Object_Adapter::open (ACE_ENV_SINGLE_ARG_DECL)
+{
+ // Add in the default POA policies to the default list.
+ this->init_default_policies (this->default_poa_policies ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // If a POA extension hasn't changed the servant dispatcher, initialize the
+ // default one.
+ if (this->servant_dispatcher_ == 0)
+ {
+ ACE_NEW (this->servant_dispatcher_,
+ TAO_Default_Servant_Dispatcher);
+ }
+
+#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
+ ACE_NEW_THROW_EX (this->poa_manager_factory_,
+ TAO_POAManager_Factory (*this),
+ CORBA::NO_MEMORY ());
+
+ ::CORBA::PolicyList policy;
+ PortableServer::POAManager_var poa_manager
+ = poa_manager_factory_->create_POAManager (TAO_DEFAULT_ROOTPOAMANAGER_NAME,
+ policy
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+#else
+ PortableServer::POAManager_ptr poa_manager_ptr;
+ ::CORBA::PolicyList policy_list;
+ ACE_NEW_THROW_EX (poa_manager_ptr,
+ TAO_POA_Manager (*this, TAO_DEFAULT_ROOTPOAMANAGER_NAME),
+ CORBA::NO_MEMORY
+ (CORBA::SystemException::_tao_minor_code (0, ENOMEM),
+ CORBA::COMPLETED_NO));
+ ACE_CHECK;
+
+ PortableServer::POAManager_var poa_manager = poa_manager_ptr;
+ // Keep reference of POAManager in TAO_Object_Adapter so the POAManager
+ // object is destructed after RootPOA is destructed.
+ the_poa_manager_ = poa_manager;
+
+#endif
+
+ // This makes sure that the default resources are open when the Root
+ // POA is created.
+ this->orb_core_.thread_lane_resources_manager ().open_default_resources (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+
+ TAO_POA_Policy_Set policies (this->default_poa_policies ());
+
+#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
+ // Specify the implicit activation policy since it should
+ // be different from the default. Note that merge_policy
+ // takes a const reference and makes its own copy of the
+ // policy. (Otherwise, we'd have to allocate the policy
+ // on the heap.)
+ // Implicit activation policy.
+ TAO::Portable_Server::ImplicitActivationPolicy implicit_activation_policy
+ (PortableServer::IMPLICIT_ACTIVATION);
+ policies.merge_policy (&implicit_activation_policy ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+#endif /* TAO_HAS_MINIMUM_POA == 0 */
+
+ // Merge policies from the ORB level.
+ this->validator ().merge_policies (policies.policies ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // 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.
+ policies.validate_policies (this->validator (),
+ this->orb_core_
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // Construct a new POA
+ TAO_Root_POA::String root_poa_name (TAO_DEFAULT_ROOTPOA_NAME);
+ this->root_ =
+ this->servant_dispatcher_->create_Root_POA (root_poa_name,
+ poa_manager.in (),
+ policies,
+ this->lock (),
+ this->thread_lock (),
+ this->orb_core_,
+ this
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // The Object_Adapter will keep a reference to the Root POA so that
+ // on its destruction, it can check whether the Root POA has been
+ // destroyed yet or not.
+ this->root_->_add_ref ();
+
+ // Lock access for the duration of this transaction.
+ TAO::Portable_Server::POA_Guard poa_guard (*this->root_ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // Iterate over the registered IOR interceptors so that they may be
+ // given the opportunity to add tagged components to the profiles
+ // for this servant.
+ this->root_->establish_components (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+void
+TAO_Object_Adapter::close (int wait_for_completion
+ ACE_ENV_ARG_DECL)
+{
+ this->check_close (wait_for_completion ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // Shutting down the ORB causes all object adapters to be destroyed,
+ // since they cannot exist in the absence of an ORB. Shut down is
+ // complete when all ORB processing (including request processing
+ // and object deactivation or other operations associated with
+ // object adapters) has completed and the object adapters have been
+ // destroyed. In the case of the POA, this means that all object
+ // etherealizations have finished and root POA has been destroyed
+ // (implying that all descendent POAs have also been destroyed).
+ TAO_Root_POA *root = 0;
+#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
+ TAO_POAManager_Factory* factory = 0;
+#endif
+ {
+ ACE_GUARD (ACE_Lock, ace_mon, this->lock ());
+ if (this->root_ == 0)
+ return;
+ root = this->root_;
+ this->root_ = 0;
+
+#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
+ if (this->poa_manager_factory_ == 0)
+ return;
+ factory = this->poa_manager_factory_;
+ this->poa_manager_factory_ = 0;
+#endif
+ }
+ CORBA::Boolean etherealize_objects = 1;
+ root->destroy (etherealize_objects,
+ wait_for_completion
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ ::CORBA::release (root);
+#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
+ release_poa_manager_factory (factory);
+#endif
+}
+
+void
+TAO_Object_Adapter::check_close (int wait_for_completion
+ ACE_ENV_ARG_DECL)
+{
+ TAO_Root_POA::check_for_valid_wait_for_completions (this->orb_core (),
+ wait_for_completion
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+int
+TAO_Object_Adapter::priority (void) const
+{
+ return 0;
+}
+
+int
+TAO_Object_Adapter::dispatch (TAO::ObjectKey &key,
+ TAO_ServerRequest &request,
+ CORBA::Object_out forward_to
+ ACE_ENV_ARG_DECL)
+{
+ if (key.length() < TAO_Root_POA::TAO_OBJECTKEY_PREFIX_SIZE
+ || ACE_OS::memcmp (key.get_buffer (),
+ &TAO_Root_POA::objectkey_prefix[0],
+ TAO_Root_POA::TAO_OBJECTKEY_PREFIX_SIZE) != 0)
+ {
+ return TAO_Adapter::DS_MISMATCHED_KEY;
+ }
+
+ int result = 0;
+
+#if TAO_HAS_INTERCEPTORS == 1
+ TAO::ServerRequestInterceptor_Adapter *sri_adapter =
+ orb_core_.serverrequestinterceptor_adapter ();
+
+ ACE_TRY
+ {
+ if (sri_adapter != 0)
+ {
+#if TAO_HAS_EXTENDED_FT_INTERCEPTORS == 1
+ CORBA::OctetSeq_var ocs;
+ sri_adapter->tao_ft_interception_point (request,
+ 0, // args
+ 0, // nargs
+ 0, // servant_upcall
+ 0, // exceptions
+ 0, // nexceptions
+ ocs.out ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ /// If we have a cached result, just go ahead and send the reply
+ /// and let us return
+ if (ocs.ptr () != 0)
+ {
+ // request.result_seq (
+ request.send_cached_reply (ocs.inout ());
+
+ return TAO_Adapter::DS_OK;
+ }
+
+ // If a PortableInterceptor::ForwardRequest exception was
+ // thrown, then set the forward_to object reference and return
+ // with the appropriate return status.
+ forward_to.ptr () = request.forward_location ();
+ if (!CORBA::is_nil (request.forward_location ()))
+ {
+ return TAO_Adapter::DS_FORWARD;
+ }
+#endif /*TAO_HAS_EXTENDED_FT_INTERCEPTORS*/
+
+ // The receive_request_service_contexts() interception point
+ // must be invoked before the operation is dispatched to the
+ // servant.
+ sri_adapter->receive_request_service_contexts (request,
+ 0, // args
+ 0, // nargs
+ 0, // servant_upcall
+ 0, // exceptions
+ 0 // nexceptions
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // If a PortableInterceptor::ForwardRequest exception was
+ // thrown, then set the forward_to object reference and return
+ // with the appropriate return status.
+ forward_to.ptr () = request.forward_location ();
+ if (!CORBA::is_nil (request.forward_location ()))
+ {
+ return TAO_Adapter::DS_FORWARD;
+ }
+ }
+#endif /* TAO_HAS_INTERCEPTORS == 1 */
+
+ result = this->dispatch_servant (key,
+ request,
+ forward_to
+ ACE_ENV_ARG_PARAMETER);
+
+#if TAO_HAS_INTERCEPTORS == 1
+ ACE_TRY_CHECK;
+
+ if (result == TAO_Adapter::DS_FORWARD)
+ {
+ request.forward_location (forward_to.ptr ());
+ if (sri_adapter != 0)
+ {
+ sri_adapter->send_other (request,
+ 0, // args
+ 0, // nargs
+ 0, // servant_upcall
+ 0, // exceptions
+ 0 // nexceptions
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ }
+ }
+ ACE_CATCHANY
+ {
+ // Just assume the current exception is a system exception, the
+ // status can only change when the interceptor changes this
+ // and this is only done when the sri_adapter is available. If we
+ // don't have an sri_adapter we just rethrow the exception
+ PortableInterceptor::ReplyStatus status =
+ PortableInterceptor::SYSTEM_EXCEPTION;
+
+ if (sri_adapter != 0)
+ {
+ request.caught_exception (&ACE_ANY_EXCEPTION);
+
+ sri_adapter->send_exception (request,
+ 0, // args
+ 0, // nargs
+ 0, // servant_upcall
+ 0, // exceptions
+ 0 // nexceptions
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ status =
+ request.reply_status ();
+ }
+
+ // Only re-throw the exception if it hasn't been transformed by
+ // the send_exception() interception point (e.g. to a
+ // LOCATION_FORWARD).
+ if (status == PortableInterceptor::SYSTEM_EXCEPTION
+ || status == PortableInterceptor::USER_EXCEPTION)
+ {
+ ACE_RE_THROW;
+ }
+ }
+ ACE_ENDTRY;
+ ACE_CHECK_RETURN (result);
+#endif /* TAO_HAS_INTERCEPTORS == 1 */
+
+ return result;
+}
+
+const char *
+TAO_Object_Adapter::name (void) const
+{
+ return TAO_OBJID_ROOTPOA;
+}
+
+CORBA::Object_ptr
+TAO_Object_Adapter::root (void)
+{
+ return CORBA::Object::_duplicate (this->root_);
+}
+
+CORBA::Object_ptr
+TAO_Object_Adapter::create_collocated_object (TAO_Stub *stub,
+ const TAO_MProfile &mp)
+{
+ TAO_ServantBase *sb = this->get_collocated_servant (mp);
+
+ // Set the servant ORB. Do not duplicate the ORB here since
+ // TAO_Stub::servant_orb() duplicates it.
+ stub->servant_orb (this->orb_core_.orb ());
+
+ // It is ok to create a collocated object even when <sb> is
+ // zero. This constructor will set the stub collocated indicator and
+ // the strategized proxy broker if required.
+ CORBA::Object_ptr x;
+ ACE_NEW_RETURN (x,
+ CORBA::Object (stub,
+ 1,
+ sb),
+ CORBA::Object::_nil ());
+
+ // Success.
+ return x;
+}
+
+CORBA::Long
+TAO_Object_Adapter::initialize_collocated_object (TAO_Stub *stub)
+{
+ // If we have been forwarded: use the forwarded profiles
+ const TAO_MProfile &mp = stub->forward_profiles () ? *(stub->forward_profiles ())
+ : stub->base_profiles ();
+
+ TAO_ServantBase *sb = this->get_collocated_servant (mp);
+
+ // Set the servant ORB. Do not duplicate the ORB here since
+ // TAO_Stub::servant_orb() duplicates it.
+ stub->servant_orb (this->orb_core_.orb ());
+
+ // It is ok to set the object as a collocated object even when
+ // <sb> is zero.
+ stub->collocated_servant (sb);
+
+ // Mark the stub as collocated. This will set the strategized object
+ // proxy broker if required.
+ stub->is_collocated (true);
+
+ // Return 0 (success) iff we found a servant.
+ return ! sb;
+}
+
+#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
+void
+TAO_Object_Adapter::release_poa_manager_factory (
+ TAO_POAManager_Factory *factory)
+{
+ if (factory != 0)
+ {
+ factory->remove_all_poamanagers ();
+ ::CORBA::release (factory);
+ }
+}
+#endif
+
+TAO_ServantBase *
+TAO_Object_Adapter::get_collocated_servant (const TAO_MProfile &mp)
+{
+ for (TAO_PHandle j = 0;
+ j != mp.profile_count ();
+ ++j)
+ {
+ const TAO_Profile *profile = mp.get_profile (j);
+ TAO::ObjectKey_var objkey = profile->_key ();
+
+ if (objkey->length() < TAO_Root_POA::TAO_OBJECTKEY_PREFIX_SIZE
+ || ACE_OS::memcmp (objkey->get_buffer (),
+ &TAO_Root_POA::objectkey_prefix[0],
+ TAO_Root_POA::TAO_OBJECTKEY_PREFIX_SIZE) != 0)
+ continue;
+
+ TAO_ServantBase *servant = 0;
+
+ ACE_DECLARE_NEW_CORBA_ENV;
+ ACE_TRY
+ {
+ this->find_servant (objkey.in (),
+ servant
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ }
+ ACE_ENDTRY;
+
+ return servant;
+ }
+
+ return 0;
+}
+
+// ****************************************************************
+
+TAO_Object_Adapter::Hint_Strategy::~Hint_Strategy (void)
+{
+}
+
+void
+TAO_Object_Adapter::Hint_Strategy::object_adapter (TAO_Object_Adapter *oa)
+{
+ this->object_adapter_ = oa;
+}
+
+TAO_Object_Adapter::Active_Hint_Strategy::Active_Hint_Strategy (CORBA::ULong map_size)
+ : persistent_poa_system_map_ (map_size)
+{
+}
+
+TAO_Object_Adapter::Active_Hint_Strategy::~Active_Hint_Strategy (void)
+{
+}
+
+int
+TAO_Object_Adapter::Active_Hint_Strategy::find_persistent_poa (
+ const poa_name &system_name,
+ TAO_Root_POA *&poa
+ ACE_ENV_ARG_DECL)
+{
+ poa_name folded_name;
+ int result = this->persistent_poa_system_map_.recover_key (system_name,
+ folded_name);
+
+ if (result == 0)
+ {
+ result = this->persistent_poa_system_map_.find (system_name,
+ poa);
+ if (result != 0
+ || folded_name != poa->folded_name ())
+ {
+ result =
+ this->object_adapter_->persistent_poa_name_map_->find (folded_name,
+ poa);
+ if (result != 0)
+ {
+ result =
+ this->object_adapter_->activate_poa (folded_name,
+ poa
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ }
+ }
+ }
+
+ return result;
+}
+
+int
+TAO_Object_Adapter::Active_Hint_Strategy::bind_persistent_poa (
+ const poa_name &folded_name,
+ TAO_Root_POA *poa,
+ poa_name_out system_name)
+{
+ poa_name name = folded_name;
+ int result = this->persistent_poa_system_map_.bind_modify_key (poa,
+ name);
+
+ if (result == 0)
+ {
+ result =
+ this->object_adapter_->persistent_poa_name_map_->bind (folded_name,
+ poa);
+
+ if (result != 0)
+ this->persistent_poa_system_map_.unbind (name);
+ else
+ ACE_NEW_RETURN (system_name,
+ poa_name (name),
+ -1);
+ }
+
+ return result;
+}
+
+int
+TAO_Object_Adapter::Active_Hint_Strategy::unbind_persistent_poa (
+ const poa_name &folded_name,
+ const poa_name &system_name)
+{
+ int result = this->persistent_poa_system_map_.unbind (system_name);
+
+ if (result == 0)
+ result =
+ this->object_adapter_->persistent_poa_name_map_->unbind (folded_name);
+
+ return result;
+}
+
+TAO_Object_Adapter::No_Hint_Strategy::~No_Hint_Strategy (void)
+{
+}
+
+int
+TAO_Object_Adapter::No_Hint_Strategy::find_persistent_poa (
+ const poa_name &system_name,
+ TAO_Root_POA *&poa
+ ACE_ENV_ARG_DECL)
+{
+ int result =
+ this->object_adapter_->persistent_poa_name_map_->find (system_name,
+ poa);
+ if (result != 0)
+ {
+ result =
+ this->object_adapter_->activate_poa (system_name,
+ poa
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (-1);
+ }
+
+ return result;
+}
+
+int
+TAO_Object_Adapter::No_Hint_Strategy::bind_persistent_poa (
+ const poa_name &folded_name,
+ TAO_Root_POA *poa,
+ poa_name_out system_name)
+{
+ int result =
+ this->object_adapter_->persistent_poa_name_map_->bind (folded_name,
+ poa);
+ if (result == 0)
+ ACE_NEW_RETURN (system_name,
+ poa_name (folded_name),
+ -1);
+ return result;
+}
+
+int
+TAO_Object_Adapter::No_Hint_Strategy::unbind_persistent_poa (
+ const poa_name & folded_name,
+ const poa_name & /* system_name */)
+{
+ return this->object_adapter_->persistent_poa_name_map_->unbind (folded_name);
+}
+
+TAO_Object_Adapter::poa_name_iterator::poa_name_iterator (
+ int begin,
+ CORBA::ULong size,
+ const CORBA::Octet *folded_buffer)
+ : size_ (size),
+ folded_buffer_ (folded_buffer),
+ last_separator_ ((CORBA::ULong) ~0)
+{
+ if (begin)
+ {
+ this->position_ = (CORBA::ULong) ~0;
+ this->operator++ ();
+ }
+ else
+ this->position_ = this->size_;
+}
+
+bool
+TAO_Object_Adapter::poa_name_iterator::operator== (const poa_name_iterator &rhs) const
+{
+ return this->position_ == rhs.position_;
+}
+
+bool
+TAO_Object_Adapter::poa_name_iterator::operator!= (const poa_name_iterator &rhs) const
+{
+ return !this->operator== (rhs);
+}
+
+ACE_CString
+TAO_Object_Adapter::poa_name_iterator::operator* () const
+{
+ CORBA::ULong start_at =
+ this->last_separator_ +
+ TAO_Root_POA::name_separator_length ();
+
+ CORBA::ULong how_many =
+ this->position_
+ - this->last_separator_
+ - TAO_Root_POA::name_separator_length ();
+
+ return ACE_CString (reinterpret_cast <const char *>
+ (&this->folded_buffer_[start_at]),
+ how_many);
+}
+
+TAO_Object_Adapter::poa_name_iterator &
+TAO_Object_Adapter::poa_name_iterator::operator++ (void)
+{
+ for (this->last_separator_ = this->position_;
+ ;
+ )
+ {
+ ++this->position_;
+ if (this->position_ < this->size_)
+ {
+ if (this->folded_buffer_[this->position_] == TAO_Root_POA::name_separator ())
+ break;
+ }
+ else
+ break;
+ }
+
+ return *this;
+}
+
+TAO_Object_Adapter::iteratable_poa_name::iteratable_poa_name (
+ const poa_name &folded_name)
+ : folded_name_ (folded_name)
+{
+}
+
+TAO_Object_Adapter::iteratable_poa_name::iterator
+TAO_Object_Adapter::iteratable_poa_name::begin (void) const
+{
+ return iterator (1,
+ this->folded_name_.length (),
+ this->folded_name_.get_buffer ());
+}
+
+TAO_Object_Adapter::iteratable_poa_name::iterator
+TAO_Object_Adapter::iteratable_poa_name::end (void) const
+{
+ return iterator (0,
+ this->folded_name_.length (),
+ this->folded_name_.get_buffer ());
+}
+
+void
+TAO_Object_Adapter::wait_for_non_servant_upcalls_to_complete (ACE_ENV_SINGLE_ARG_DECL)
+{
+ // Check if a non-servant upcall is in progress. If a non-servant
+ // upcall is in progress, wait for it to complete. Unless of
+ // course, the thread making the non-servant upcall is this thread.
+ while (this->enable_locking_ &&
+ this->non_servant_upcall_in_progress_ &&
+ ! ACE_OS::thr_equal (this->non_servant_upcall_thread_,
+ ACE_OS::thr_self ()))
+ {
+ // If so wait...
+ int result =
+ this->non_servant_upcall_condition_.wait ();
+ if (result == -1)
+ ACE_THROW (CORBA::OBJ_ADAPTER ());
+ }
+}
+
+void
+TAO_Object_Adapter::wait_for_non_servant_upcalls_to_complete_no_throw (void)
+{
+ // Non-exception throwing version.
+ ACE_TRY_NEW_ENV
+ {
+ this->wait_for_non_servant_upcalls_to_complete (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ ACE_CATCHANY
+ {
+ ACE_ERROR ((LM_ERROR,
+ "TAO_Object_Adapter::wait_for_non_servant_upcalls_to_complete "
+ "threw exception it should not have!\n"));
+ }
+ ACE_ENDTRY;
+}
+
+void
+TAO_Object_Adapter::servant_dispatcher (TAO_Servant_Dispatcher *dispatcher)
+{
+ if (this->servant_dispatcher_)
+ delete this->servant_dispatcher_;
+
+ this->servant_dispatcher_ = dispatcher;
+}
+
+void
+TAO_Object_Adapter::do_dispatch (TAO_ServerRequest& req,
+ TAO::Portable_Server::Servant_Upcall& upcall
+ ACE_ENV_ARG_DECL)
+{
+ upcall.servant ()->_dispatch(req,
+ &upcall
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL