poa.cpp
来自「这是广泛使用的通信开源项目,对于大容量,高并发的通讯要求完全能够胜任,他广泛可用」· C++ 代码 · 共 1,826 行 · 第 1/5 页
CPP
1,826 行
{
this->servant_locator_ = PortableServer::ServantLocator::_narrow (imgr
ACE_ENV_ARG_PARAMETER);
ACE_CHECK;
if (CORBA::is_nil (this->servant_locator_.in ()))
{
ACE_THROW (PortableServer::POA::WrongPolicy ());
}
}
}
PortableServer::Servant
TAO_POA::get_servant_i (ACE_ENV_SINGLE_ARG_DECL)
ACE_THROW_SPEC ((CORBA::SystemException,
PortableServer::POA::NoServant,
PortableServer::POA::WrongPolicy))
{
// This operation requires the USE_DEFAULT_SERVANT policy; if not
// present, the WrongPolicy exception is raised.
if (this->cached_policies_.request_processing () != PortableServer::USE_DEFAULT_SERVANT)
{
ACE_THROW_RETURN (PortableServer::POA::WrongPolicy (),
0);
}
// This operation returns the default servant associated with the
// POA.
PortableServer::Servant result = this->default_servant_.in ();
if (result != 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);
// The POA invokes _add_ref once on the Servant before returning
// it. If the application uses reference counting, the caller of
// get_servant is responsible for invoking _remove_ref once on
// the returned Servant when it is finished with it. A
// conforming caller need not invoke _remove_ref on the returned
// Servant if the type of the Servant uses the default reference
// counting inherited from ServantBase.
result->_add_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_CHECK_RETURN (0);
return result;
}
else
// If no servant has been associated with the POA, the NoServant
// exception is raised.
{
ACE_THROW_RETURN (PortableServer::POA::NoServant (),
0);
}
}
void
TAO_POA::set_servant_i (PortableServer::Servant servant
ACE_ENV_ARG_DECL)
ACE_THROW_SPEC ((CORBA::SystemException,
PortableServer::POA::WrongPolicy))
{
// This operation requires the USE_DEFAULT_SERVANT policy; if not
// present, the WrongPolicy exception is raised.
if (this->cached_policies_.request_processing () != PortableServer::USE_DEFAULT_SERVANT)
{
ACE_THROW (PortableServer::POA::WrongPolicy ());
}
// 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;
// The implementation of set_servant 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.
if (servant != 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);
servant->_add_ref (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_CHECK;
}
}
#endif /* TAO_HAS_MINIMUM_POA == 0 */
int
TAO_POA::is_servant_in_map (PortableServer::Servant servant,
int &wait_occurred_restart_call)
{
int deactivated = 0;
int servant_in_map =
this->active_object_map ().is_servant_in_map (servant,
deactivated);
if (!servant_in_map)
{
return 0;
}
else
{
if (deactivated)
{
if (TAO_debug_level > 0)
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%t) TAO_POA::is_servant_in_map: waiting for servant to deactivate\n")));
// We are going to wait on this condition variable; the POA
// state may change by the time we get the lock again.
// Therefore, indicate to the caller that all conditions
// need to be checked again.
wait_occurred_restart_call = 1;
++this->waiting_servant_deactivation_;
if (this->object_adapter ().enable_locking_)
this->servant_deactivation_condition_.wait ();
--this->waiting_servant_deactivation_;
return 0;
}
else
{
return 1;
}
}
}
int
TAO_POA::is_user_id_in_map (const PortableServer::ObjectId &id,
CORBA::Short priority,
int &priorities_match,
int &wait_occurred_restart_call)
{
int deactivated = 0;
int user_id_in_map =
this->active_object_map ().is_user_id_in_map (id,
priority,
priorities_match,
deactivated);
if (!user_id_in_map)
{
return 0;
}
else
{
if (deactivated)
{
if (TAO_debug_level > 0)
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%t) TAO_POA::is_user_id_in_map: waiting for servant to deactivate\n")));
// We are going to wait on this condition variable; the POA
// state may change by the time we get the lock again.
// Therefore, indicate to the caller that all conditions
// need to be checked again.
wait_occurred_restart_call = 1;
++this->waiting_servant_deactivation_;
if (this->object_adapter ().enable_locking_)
this->servant_deactivation_condition_.wait ();
--this->waiting_servant_deactivation_;
return 0;
}
else
{
return 1;
}
}
}
PortableServer::ObjectId *
TAO_POA::activate_object_i (PortableServer::Servant servant,
CORBA::Short priority,
int &wait_occurred_restart_call
ACE_ENV_ARG_DECL)
ACE_THROW_SPEC ((CORBA::SystemException,
PortableServer::POA::ServantAlreadyActive,
PortableServer::POA::WrongPolicy))
{
// This operation requires the SYSTEM_ID and RETAIN policy; if not
// present, the WrongPolicy exception is raised.
if (!(this->cached_policies_.id_assignment () == PortableServer::SYSTEM_ID &&
this->cached_policies_.servant_retention () == PortableServer::RETAIN))
{
ACE_THROW_RETURN (PortableServer::POA::WrongPolicy (),
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->cached_policies_.id_uniqueness () == PortableServer::UNIQUE_ID)
{
int result =
this->is_servant_in_map (servant,
wait_occurred_restart_call);
if (result)
{
ACE_THROW_RETURN (PortableServer::POA::ServantAlreadyActive (),
0);
}
else if (wait_occurred_restart_call)
{
// We ended up waiting on a condition variable, the POA
// state may have changed while we are waiting. Therefore,
// we need to restart this call.
return 0;
}
}
// 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 user_id;
if (this->active_object_map ().
bind_using_system_id_returning_user_id (servant,
priority,
user_id.out ()) != 0)
{
ACE_THROW_RETURN (CORBA::OBJ_ADAPTER (),
0);
}
//
// 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 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_RETURN (0);
return user_id._retn ();
}
void
TAO_POA::activate_object_with_id_i (const PortableServer::ObjectId &id,
PortableServer::Servant servant,
CORBA::Short priority,
int &wait_occurred_restart_call
ACE_ENV_ARG_DECL)
ACE_THROW_SPEC ((CORBA::SystemException,
PortableServer::POA::ServantAlreadyActive,
PortableServer::POA::ObjectAlreadyActive,
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 ());
}
// 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->cached_policies_.id_assignment () == PortableServer::SYSTEM_ID &&
!this->is_poa_generated_id (id))
{
ACE_THROW (CORBA::BAD_PARAM ());
}
// 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.
int priorities_match = 1;
int result =
this->is_user_id_in_map (id,
priority,
priorities_match,
wait_occurred_restart_call);
if (result)
{
ACE_THROW (PortableServer::POA::ObjectAlreadyActive ());
}
else if (wait_occurred_restart_call)
{
// We ended up waiting on a condition variable, the POA state
// may have changed while we are waiting. Therefore, we need to
// restart this call.
return;
}
// If the activate_object_with_id_and_priority operation is invoked
// with a different priority to an earlier invocation of one of the
// create reference with priority operations, for the same object,
// then the ORB shall raise a BAD_INV_ORDER system exception (with a
// Standard Minor Exception Code of 1). If the priority value is the
// same then the ORB shall return SUCCESS.
if (!priorities_match)
{
ACE_THROW (CORBA::BAD_INV_ORDER (CORBA::OMGVMCID | 1,
CORBA::COMPLETED_NO));
}
// 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->cached_policies_.id_uniqueness () == PortableServer::UNIQUE_ID)
{
result =
this->is_servant_in_map (servant,
wait_occurred_restart_call);
if (result)
{
ACE_THROW (PortableServer::POA::ServantAlreadyActive ());
}
else if (wait_occurred_restart_call)
{
// We ended up waiting on a condition variable, the POA
// state may have changed while we are waiting. Therefore,
// we need to restart this call.
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.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?