poa.cpp
来自「这是广泛使用的通信开源项目,对于大容量,高并发的通讯要求完全能够胜任,他广泛可用」· C++ 代码 · 共 1,826 行 · 第 1/5 页
CPP
1,826 行
if (this->active_object_map ().bind_using_user_id (servant,
id,
priority) != 0)
{
ACE_THROW (CORBA::OBJ_ADAPTER ());
}
//
// Everything is finally ok
//
// A recursive thread lock without using a recursive thread lock.
// Non_Servant_Upcall has a magic constructor and destructor. We
// unlock the Object_Adapter lock for the duration of the servant
// activator upcalls; reacquiring once the upcalls complete. Even
// though we are releasing the lock, other threads will not be able
// to make progress since
// <Object_Adapter::non_servant_upcall_in_progress_> has been set.
TAO_Object_Adapter::Non_Servant_Upcall non_servant_upcall (*this);
ACE_UNUSED_ARG (non_servant_upcall);
// The implementation of activate_object_with_id will invoke
// _add_ref at least once on the Servant argument before
// returning. When the POA no longer needs the Servant, it will
// invoke _remove_ref on it the same number of times.
servant->_add_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_CHECK;
}
void
TAO_POA::deactivate_all_objects_i (CORBA::Boolean etherealize_objects,
CORBA::Boolean wait_for_completion
ACE_ENV_ARG_DECL)
ACE_THROW_SPEC ((CORBA::SystemException,
PortableServer::POA::WrongPolicy))
{
this->deactivate_all_objects_i (etherealize_objects
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
this->wait_for_completions (wait_for_completion
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
}
void
TAO_POA::wait_for_completions (CORBA::Boolean wait_for_completion
ACE_ENV_ARG_DECL)
{
while (this->object_adapter ().enable_locking_ &&
wait_for_completion &&
this->outstanding_requests_ > 0)
{
this->wait_for_completion_pending_ = 1;
int result = this->outstanding_requests_condition_.wait ();
if (result == -1)
{
ACE_THROW (CORBA::OBJ_ADAPTER ());
}
}
}
/* static */
void
TAO_POA::check_for_valid_wait_for_completions (const TAO_ORB_Core &orb_core,
CORBA::Boolean wait_for_completion
ACE_ENV_ARG_DECL)
{
if (wait_for_completion)
{
TAO_POA_Current_Impl *poa_current_impl =
ACE_static_cast (TAO_POA_Current_Impl *,
TAO_TSS_RESOURCES::instance ()->poa_current_impl_);
while (1)
{
// If wait_for_completion is TRUE and the current thread is
// in an invocation context dispatched from some POA
// belonging to the same ORB as this POA, the BAD_INV_ORDER
// system exception with standard minor code 3 is raised and
// POA destruction does not occur.
if (poa_current_impl != 0)
{
if (&orb_core == &poa_current_impl->orb_core ())
{
// CORBA 2.3 specifies which minor code corresponds
// to this particular problem.
ACE_THROW (CORBA::BAD_INV_ORDER (CORBA::OMGVMCID | 3,
CORBA::COMPLETED_NO));
}
}
else
break;
poa_current_impl =
poa_current_impl->previous_current_impl_;
}
}
}
void
TAO_POA::deactivate_all_objects_i (CORBA::Boolean etherealize_objects
ACE_ENV_ARG_DECL)
ACE_THROW_SPEC ((CORBA::SystemException,
PortableServer::POA::WrongPolicy))
{
this->etherealize_objects_ = etherealize_objects;
// This operation is a no-op for the non-RETAIN policy.
if (this->cached_policies_.servant_retention () != PortableServer::RETAIN)
{
return;
}
// 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.
// We must copy the map entries into a separate place since we
// cannot remove entries while iterating through the map.
ACE_Array_Base<TAO_Active_Object_Map::Map_Entry *> map_entries
(this->active_object_map ().current_size ());
size_t counter = 0;
TAO_Active_Object_Map::user_id_map::iterator end
= this->active_object_map ().user_id_map_->end ();
for (TAO_Active_Object_Map::user_id_map::iterator iter
= this->active_object_map ().user_id_map_->begin ();
iter != end;
++iter)
{
TAO_Active_Object_Map::user_id_map::value_type map_pair = *iter;
TAO_Active_Object_Map::Map_Entry *active_object_map_entry = map_pair.second ();
if (!active_object_map_entry->deactivated_)
{
map_entries[counter] = active_object_map_entry;
++counter;
}
}
for (size_t i = 0;
i < counter;
++i)
{
this->deactivate_map_entry (map_entries[i]
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
}
}
void
TAO_POA::deactivate_object_i (const PortableServer::ObjectId &id
ACE_ENV_ARG_DECL)
ACE_THROW_SPEC ((CORBA::SystemException,
PortableServer::POA::ObjectNotActive,
PortableServer::POA::WrongPolicy))
{
// This operation requires the RETAIN policy; if not present, the
// WrongPolicy exception is raised.
if (this->cached_policies_.servant_retention () != PortableServer::RETAIN)
{
ACE_THROW (PortableServer::POA::WrongPolicy ());
}
TAO_Active_Object_Map::Map_Entry *active_object_map_entry = 0;
int result = this->active_object_map ().
find_servant_and_system_id_using_user_id (id,
active_object_map_entry);
// If there is no active object associated with the specified Object
// Id, the operation raises an ObjectNotActive exception.
if (result != 0)
{
ACE_THROW (PortableServer::POA::ObjectNotActive ());
}
this->deactivate_map_entry (active_object_map_entry
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
}
void
TAO_POA::deactivate_map_entry (TAO_Active_Object_Map::Map_Entry *active_object_map_entry
ACE_ENV_ARG_DECL)
{
// Decrement the reference count.
CORBA::UShort new_count = --active_object_map_entry->reference_count_;
if (new_count == 0)
{
this->cleanup_servant (active_object_map_entry
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
}
else
{
// It should be noted that there may be a period of time between
// an object's deactivation and the etherealization (during
// which outstanding requests are being processed) in which
// arriving requests on that object should not be passed to its
// servant. During this period, requests targeted for such an
// object act as if the POA were in holding state until
// etherealize completes. If etherealize is called as a
// consequence of a deactivate call with a etherealize_objects
// parameter of TRUE, incoming requests are rejected.
// Else mark entry as closed...
active_object_map_entry->deactivated_ = 1;
}
}
void
TAO_POA::cleanup_servant (TAO_Active_Object_Map::Map_Entry *active_object_map_entry
ACE_ENV_ARG_DECL)
{
// 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 the POA has no ServantActivator associated with it, the POA
// implementation calls _remove_ref when all operation invocations
// have completed. If there is a ServantActivator, the Servant is
// consumed by the call to ServantActivator::etherealize instead.
// First check for a non-zero servant.
if (active_object_map_entry->servant_)
{
#if (TAO_HAS_MINIMUM_POA == 0)
if (this->etherealize_objects_ &&
this->cached_policies_.request_processing () == PortableServer::USE_SERVANT_MANAGER &&
!CORBA::is_nil (this->servant_activator_.in ()))
{
CORBA::Boolean remaining_activations =
this->active_object_map ().
remaining_activations (active_object_map_entry->servant_);
// A recursive thread lock without using a recursive thread
// lock. Non_Servant_Upcall has a magic constructor and
// destructor. We unlock the Object_Adapter lock for the
// duration of the servant activator upcalls; reacquiring
// once the upcalls complete. Even though we are releasing
// the lock, other threads will not be able to make progress
// since <Object_Adapter::non_servant_upcall_in_progress_>
// has been set.
TAO_Object_Adapter::Non_Servant_Upcall non_servant_upcall (*this);
ACE_UNUSED_ARG (non_servant_upcall);
// If the cleanup_in_progress parameter is TRUE, the reason
// for the etherealize operation is that either the
// deactivate or destroy operation was called with an
// etherealize_objects parameter of TRUE. If the parameter
// is FALSE, the etherealize operation is called for other
// reasons.
this->servant_activator_->etherealize (active_object_map_entry->user_id_,
this,
active_object_map_entry->servant_,
this->cleanup_in_progress_,
remaining_activations
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
}
else
#endif /* TAO_HAS_MINIMUM_POA == 0 */
{
// A recursive thread lock without using a recursive thread
// lock. Non_Servant_Upcall has a magic constructor and
// destructor. We unlock the Object_Adapter lock for the
// duration of the servant activator upcalls; reacquiring
// once the upcalls complete. Even though we are releasing
// the lock, other threads will not be able to make progress
// since <Object_Adapter::non_servant_upcall_in_progress_>
// has been set.
TAO_Object_Adapter::Non_Servant_Upcall non_servant_upcall (*this);
ACE_UNUSED_ARG (non_servant_upcall);
active_object_map_entry->servant_->_remove_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_CHECK;
}
}
// 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.
int result = this->active_object_map ().
unbind_using_user_id (active_object_map_entry->user_id_);
if (result != 0)
{
ACE_THROW (CORBA::OBJ_ADAPTER ());
}
}
void
TAO_POA::check_poa_manager_state (ACE_ENV_SINGLE_ARG_DECL)
{
PortableServer::POAManager::State state = this->poa_manager_.get_state_i ();
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:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?