summaryrefslogtreecommitdiff
path: root/TAO/tao/PortableServer/POAManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/tao/PortableServer/POAManager.cpp')
-rw-r--r--TAO/tao/PortableServer/POAManager.cpp425
1 files changed, 425 insertions, 0 deletions
diff --git a/TAO/tao/PortableServer/POAManager.cpp b/TAO/tao/PortableServer/POAManager.cpp
new file mode 100644
index 00000000000..344495551a1
--- /dev/null
+++ b/TAO/tao/PortableServer/POAManager.cpp
@@ -0,0 +1,425 @@
+// $Id$
+
+#include "tao/PortableServer/POAManager.h"
+#include "tao/PortableServer/POAManagerFactory.h"
+#include "tao/PortableServer/Root_POA.h"
+#include "tao/PortableServer/poa_macros.h"
+#include "tao/Server_Strategy_Factory.h"
+#include "tao/ORB_Core.h"
+#include "tao/IORInterceptor_Adapter.h"
+
+#if !defined (__ACE_INLINE__)
+# include "tao/PortableServer/POAManager.inl"
+#endif /* ! __ACE_INLINE__ */
+
+ACE_RCSID (PortableServer,
+ POAManager,
+ "$Id$")
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+TAO_POA_Manager::TAO_POA_Manager (
+ TAO_Object_Adapter &object_adapter,
+#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
+ const char * id,
+ const ::CORBA::PolicyList &policies,
+ PortableServer::POAManagerFactory_ptr poa_manager_factory)
+#else
+ const char * id)
+#endif
+ : state_ (PortableServer::POAManager::HOLDING),
+ lock_ (object_adapter.lock ()),
+ poa_collection_ (),
+ object_adapter_ (object_adapter),
+#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
+ id_ (id == 0 ? this->generate_manager_id () : CORBA::string_dup (id)),
+ poa_manager_factory_ (* dynamic_cast <TAO_POAManager_Factory*> (poa_manager_factory)),
+ policies_ (policies)
+{
+ poa_manager_factory_._add_ref ();
+}
+#else
+ id_ (id == 0 ? this->generate_manager_id () : CORBA::string_dup (id))
+{
+}
+#endif
+
+
+TAO_POA_Manager::~TAO_POA_Manager (void)
+{
+#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
+ poa_manager_factory_._remove_ref ();
+#endif
+}
+
+char *
+TAO_POA_Manager::get_id (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ return CORBA::string_dup (this->id_.in ());
+}
+
+void
+TAO_POA_Manager::activate_i (ACE_ENV_SINGLE_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ PortableServer::POAManager::AdapterInactive))
+{
+ // 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_ == PortableServer::POAManager::INACTIVE)
+ {
+ ACE_THROW (PortableServer::POAManager::AdapterInactive ());
+ }
+ else
+ {
+ this->state_ = PortableServer::POAManager::ACTIVE;
+ // Find the poas that applied the custom servant dispatching
+ // strategy to launch the dispatching threads.
+
+ for (POA_COLLECTION::iterator iterator = this->poa_collection_.begin ();
+ iterator != this->poa_collection_.end ();
+ ++iterator)
+ {
+ (*iterator)->poa_activated_hook ();
+ }
+ }
+
+ this->adapter_manager_state_changed (this->state_
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+void
+TAO_POA_Manager::deactivate_i (CORBA::Boolean etherealize_objects,
+ CORBA::Boolean wait_for_completion
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ PortableServer::POAManager::AdapterInactive))
+{
+ // Is the <wait_for_completion> semantics for this thread correct?
+ TAO_Root_POA::check_for_valid_wait_for_completions (this->object_adapter_.orb_core (),
+ wait_for_completion
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // 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_ == PortableServer::POAManager::INACTIVE)
+ {
+ ACE_THROW (PortableServer::POAManager::AdapterInactive ());
+ }
+ else
+ {
+ this->state_ = PortableServer::POAManager::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.
+
+ // If the wait_for_completion parameter is FALSE, this operation
+ // will return immediately after changing the state. If the
+ // parameter is TRUE and the current thread is not in an invocation
+ // context dispatched by some POA belonging to the same ORB as this
+ // POA, 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 parameter is TRUE and the current thread is in
+ // an invocation context dispatched by some POA belonging to the
+ // same ORB as this POA the BAD_INV_ORDER exception is raised and
+ // the state is not changed.
+
+ for (POA_COLLECTION::iterator iterator = this->poa_collection_.begin ();
+ iterator != this->poa_collection_.end ();
+ ++iterator)
+ {
+ TAO_Root_POA *poa = *iterator;
+ // Notify the poas that applied the custom servant dispatching
+ // strategy to stop the dispatching threads.
+ poa->poa_deactivated_hook ();
+
+ poa->deactivate_all_objects_i (etherealize_objects,
+ wait_for_completion
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+
+ // 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.
+
+ this->adapter_manager_state_changed (this->state_
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+void
+TAO_POA_Manager::adapter_manager_state_changed (PortableServer::POAManager::State state
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException))
+{
+ PortableInterceptor::AdapterState adapter_state =
+ static_cast<PortableInterceptor::AdapterState> (state);
+
+ TAO_IORInterceptor_Adapter *ior_adapter =
+ this->object_adapter_.orb_core ().ior_interceptor_adapter ();
+
+ if (ior_adapter)
+ {
+ ior_adapter->adapter_manager_state_changed (this->id_.in (),
+ adapter_state
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+}
+
+#if (TAO_HAS_MINIMUM_POA == 0)
+
+void
+TAO_POA_Manager::hold_requests_i (CORBA::Boolean wait_for_completion
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ PortableServer::POAManager::AdapterInactive))
+{
+ // Is the <wait_for_completion> semantics for this thread correct?
+ TAO_Root_POA::check_for_valid_wait_for_completions (this->object_adapter_.orb_core (),
+ wait_for_completion
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // 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_ == PortableServer::POAManager::INACTIVE)
+ {
+ ACE_THROW (PortableServer::POAManager::AdapterInactive ());
+ }
+ else
+ {
+ this->state_ = PortableServer::POAManager::HOLDING;
+ }
+
+ // If the wait_for_completion parameter is FALSE, this operation
+ // returns immediately after changing the state. If the parameter is
+ // TRUE and the current thread is not in an invocation context
+ // dispatched by some POA belonging to the same ORB as this POA,
+ // 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. If the parameter is TRUE
+ // and the current thread is in an invocation context dispatched by
+ // some POA belonging to the same ORB as this POA the BAD_INV_ORDER
+ // exception is raised and the state is not changed.
+
+ if (wait_for_completion)
+ {
+ for (POA_COLLECTION::iterator iterator = this->poa_collection_.begin ();
+ iterator != this->poa_collection_.end ();
+ ++iterator)
+ {
+ TAO_Root_POA *poa = *iterator;
+ poa->wait_for_completions (wait_for_completion
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ }
+
+ this->adapter_manager_state_changed (this->state_
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+}
+
+void
+TAO_POA_Manager::discard_requests_i (CORBA::Boolean wait_for_completion
+ ACE_ENV_ARG_DECL)
+ ACE_THROW_SPEC ((CORBA::SystemException,
+ PortableServer::POAManager::AdapterInactive))
+{
+ // Is the <wait_for_completion> semantics for this thread correct?
+ TAO_Root_POA::check_for_valid_wait_for_completions (this->object_adapter_.orb_core (),
+ wait_for_completion
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+
+ // 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_ == PortableServer::POAManager::INACTIVE)
+ {
+ ACE_THROW (PortableServer::POAManager::AdapterInactive ());
+ }
+ else
+ {
+ this->state_ = PortableServer::POAManager::DISCARDING;
+ }
+
+ // If the wait_for_completion parameter is FALSE, this operation
+ // returns immediately after changing the state. If the
+ // parameter is TRUE and the current thread is not in an
+ // invocation context dispatched by some POA belonging to the
+ // same ORB as this POA, 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. If the parameter is TRUE and the current
+ // thread is in an invocation context dispatched by some POA
+ // belonging to the same ORB as this POA the BAD_INV_ORDER
+ // exception is raised and the state is not changed.
+
+ if (wait_for_completion)
+ {
+ for (POA_COLLECTION::iterator iterator = this->poa_collection_.begin ();
+ iterator != this->poa_collection_.end ();
+ ++iterator)
+ {
+ TAO_Root_POA *poa = *iterator;
+ poa->wait_for_completions (wait_for_completion
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK;
+ }
+ }
+
+ this->adapter_manager_state_changed (this->state_
+ ACE_ENV_ARG_PARAMETER);
+}
+
+#endif /* TAO_HAS_MINIMUM_POA == 0 */
+
+int
+TAO_POA_Manager::remove_poa (TAO_Root_POA *poa)
+{
+ int const result = this->poa_collection_.remove (poa);
+
+ // The #if really only needs to go around the
+ // "this->poa_manager_factory_.remove_poamanager (this);" line, but it's
+ // moved out as an optimization for now. If additional non-CORBA/e and
+ // non-minimum POA code needs to go in that clause the #if would have to
+ // move back in.
+
+#if (TAO_HAS_MINIMUM_POA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO)
+ if (result == 0)
+ {
+ if (this->poa_collection_.is_empty ())
+ {
+ this->poa_manager_factory_.remove_poamanager (this);
+ }
+ }
+#endif
+ return result;
+}
+
+int
+TAO_POA_Manager::register_poa (TAO_Root_POA *poa)
+{
+ return this->poa_collection_.insert (poa);
+}
+
+void
+TAO_POA_Manager::check_state (ACE_ENV_SINGLE_ARG_DECL)
+{
+ if (state_ == PortableServer::POAManager::ACTIVE)
+ {
+ // When a POA manager is in the active state, the associated
+ // POAs will receive and start processing requests (assuming
+ // that appropriate thread resources are available).
+ return;
+ }
+
+ if (state_ == PortableServer::POAManager::DISCARDING)
+ {
+ // When a POA manager is in the discarding state, the associated
+ // POAs will discard all incoming requests (whose processing has
+ // not yet begun). When a request is discarded, the TRANSIENT
+ // system exception, with standard minor code 1, must be
+ // returned to the client-side to indicate that the request
+ // should be re-issued. (Of course, an ORB may always reject a
+ // request for other reasons and raise some other system
+ // exception.)
+ ACE_THROW (
+ CORBA::TRANSIENT (
+ CORBA::SystemException::_tao_minor_code (
+ TAO_POA_DISCARDING,
+ 1),
+ CORBA::COMPLETED_NO));
+ }
+
+ if (state_ == PortableServer::POAManager::HOLDING)
+ {
+ // When a POA manager is in the holding state, the associated
+ // POAs will queue incoming requests. The number of requests
+ // that can be queued is an implementation limit. If this limit
+ // is reached, the POAs may discard requests and return the
+ // TRANSIENT system exception, with standard minor code 1, to
+ // the client to indicate that the client should reissue the
+ // request. (Of course, an ORB may always reject a request for
+ // other reasons and raise some other system exception.)
+
+ // Since there is no queuing in TAO, we immediately raise a
+ // TRANSIENT exception.
+ ACE_THROW (CORBA::TRANSIENT (
+ CORBA::SystemException::_tao_minor_code (
+ TAO_POA_HOLDING,
+ 1),
+ CORBA::COMPLETED_NO));
+ }
+
+ if (state_ == PortableServer::POAManager::INACTIVE)
+ {
+ // The inactive state is entered when the associated POAs are to
+ // be shut down. Unlike the discarding state, the inactive state
+ // is not a temporary state. When a POA manager is in the
+ // inactive state, the associated POAs will reject new
+ // requests. The rejection mechanism used is specific to the
+ // vendor. The GIOP location forwarding mechanism and
+ // CloseConnection message are examples of mechanisms that could
+ // be used to indicate the rejection. If the client is
+ // co-resident in the same process, the ORB could raise the
+ // OBJ_ADAPTER system exception, with standard minor code 1, to
+ // indicate that the object implementation is unavailable.
+ ACE_THROW (CORBA::OBJ_ADAPTER (
+ CORBA::SystemException::_tao_minor_code (
+ TAO_POA_INACTIVE,
+ 1),
+ CORBA::COMPLETED_NO));
+ }
+}
+
+CORBA::ORB_ptr
+TAO_POA_Manager::_get_orb (ACE_ENV_SINGLE_ARG_DECL_NOT_USED)
+{
+ return CORBA::ORB::_duplicate (this->object_adapter_.orb_core ().orb ());
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL