📄 ec_proxysupplier.cpp
字号:
// EC_ProxySupplier.cpp,v 1.62 2003/08/18 06:42:14 ossama Exp
#include "EC_ProxySupplier.h"
#include "EC_Dispatching.h"
#include "EC_Filter_Builder.h"
#include "EC_QOS_Info.h"
#include "EC_Event_Channel_Base.h"
#include "EC_Scheduling_Strategy.h"
#include "EC_ConsumerControl.h"
#include "EC_SupplierAdmin.h"
#include "orbsvcs/ESF/ESF_RefCount_Guard.h"
#include "orbsvcs/ESF/ESF_Proxy_RefCount_Guard.h"
#include "ace/Reverse_Lock_T.h"
#if ! defined (__ACE_INLINE__)
#include "EC_ProxySupplier.i"
#endif /* __ACE_INLINE__ */
ACE_RCSID (Event,
EC_ProxySupplier,
"EC_ProxySupplier.cpp,v 1.62 2003/08/18 06:42:14 ossama Exp")
typedef ACE_Reverse_Lock<ACE_Lock> TAO_EC_Unlock;
TAO_EC_ProxyPushSupplier::TAO_EC_ProxyPushSupplier (TAO_EC_Event_Channel_Base* ec, int validate_connection)
: event_channel_ (ec),
refcount_ (1),
suspended_ (0),
child_ (0),
consumer_validate_connection_(validate_connection)
{
this->lock_ =
this->event_channel_->create_supplier_lock ();
this->default_POA_ =
this->event_channel_->supplier_poa ();
}
TAO_EC_ProxyPushSupplier::~TAO_EC_ProxyPushSupplier (void)
{
this->event_channel_->destroy_supplier_lock (this->lock_);
this->cleanup_i ();
}
void
TAO_EC_ProxyPushSupplier::connected (TAO_EC_ProxyPushConsumer* consumer
ACE_ENV_ARG_DECL)
{
TAO_EC_Scheduling_Strategy *s =
this->event_channel_->scheduling_strategy ();
s->add_proxy_supplier_dependencies (this,
consumer
ACE_ENV_ARG_PARAMETER);
}
void
TAO_EC_ProxyPushSupplier::reconnected (TAO_EC_ProxyPushConsumer* consumer
ACE_ENV_ARG_DECL)
{
TAO_EC_Scheduling_Strategy *s =
this->event_channel_->scheduling_strategy ();
s->add_proxy_supplier_dependencies (this,
consumer
ACE_ENV_ARG_PARAMETER);
}
void
TAO_EC_ProxyPushSupplier::disconnected (TAO_EC_ProxyPushConsumer*
ACE_ENV_ARG_DECL_NOT_USED)
{
}
void
TAO_EC_ProxyPushSupplier::connected (TAO_EC_ProxyPushSupplier*
ACE_ENV_ARG_DECL_NOT_USED)
{
}
void
TAO_EC_ProxyPushSupplier::reconnected (TAO_EC_ProxyPushSupplier*
ACE_ENV_ARG_DECL_NOT_USED)
{
}
void
TAO_EC_ProxyPushSupplier::disconnected (TAO_EC_ProxyPushSupplier*
ACE_ENV_ARG_DECL_NOT_USED)
{
}
void
TAO_EC_ProxyPushSupplier::shutdown (ACE_ENV_SINGLE_ARG_DECL)
{
// Save the consumer we where connected to, we need to send a
// disconnect message to it.
RtecEventComm::PushConsumer_var consumer;
{
ACE_GUARD_THROW_EX (
ACE_Lock, ace_mon, *this->lock_,
RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR ());
ACE_CHECK;
int connected = this->is_connected_i ();
consumer = this->consumer_._retn ();
if (connected)
this->cleanup_i ();
}
this->deactivate (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_CHECK;
if (CORBA::is_nil (consumer.in ()))
return;
ACE_TRY
{
consumer->disconnect_push_consumer (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_TRY_CHECK;
}
ACE_CATCHANY
{
// Ignore exceptions, we must isolate other clients from
// problems on this one.
}
ACE_ENDTRY;
}
void
TAO_EC_ProxyPushSupplier::cleanup_i (void)
{
this->consumer_ =
RtecEventComm::PushConsumer::_nil ();
// @@ Why don't we have a destroy() method in the
// filter_builder?
delete this->child_;
this->child_ = 0;
}
void
TAO_EC_ProxyPushSupplier::deactivate (ACE_ENV_SINGLE_ARG_DECL) ACE_THROW_SPEC (())
{
ACE_TRY
{
PortableServer::ObjectId id =
this->object_id (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_TRY_CHECK;
this->default_POA_->deactivate_object (id ACE_ENV_ARG_PARAMETER);
ACE_TRY_CHECK;
}
ACE_CATCHANY
{
// Exceptions here should not be propagated. They usually
// indicate that an object is beign disconnected twice, or some
// race condition, but not a fault that the user needs to know
// about.
}
ACE_ENDTRY;
}
CORBA::ULong
TAO_EC_ProxyPushSupplier::_incr_refcnt (void)
{
ACE_GUARD_RETURN (ACE_Lock, ace_mon, *this->lock_, 0);
return this->refcount_++;
}
void
TAO_EC_ProxyPushSupplier::refcount_zero_hook (void)
{
// Use the event channel
this->event_channel_->destroy_proxy (this);
}
CORBA::ULong
TAO_EC_ProxyPushSupplier::_decr_refcnt (void)
{
{
ACE_GUARD_RETURN (ACE_Lock, ace_mon, *this->lock_, 0);
this->refcount_--;
if (this->refcount_ != 0)
return this->refcount_;
}
this->refcount_zero_hook ();
return 0;
}
typedef TAO_ESF_Proxy_RefCount_Guard<TAO_EC_Event_Channel_Base,TAO_EC_ProxyPushSupplier> Destroy_Guard;
int
TAO_EC_ProxyPushSupplier::filter (const RtecEventComm::EventSet& event,
TAO_EC_QOS_Info& qos_info
ACE_ENV_ARG_DECL)
{
Destroy_Guard auto_destroy (this->refcount_,
this->event_channel_,
this);
int result = 0;
{
ACE_GUARD_THROW_EX (
ACE_Lock, ace_mon, *this->lock_,
RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR ());
ACE_CHECK_RETURN (0);
if (this->is_connected_i () == 0)
return 0;
result =
this->child_->filter (event, qos_info ACE_ENV_ARG_PARAMETER);
ACE_CHECK_RETURN (0);
}
return result;
}
int
TAO_EC_ProxyPushSupplier::filter_nocopy (RtecEventComm::EventSet& event,
TAO_EC_QOS_Info& qos_info
ACE_ENV_ARG_DECL)
{
Destroy_Guard auto_destroy (this->refcount_,
this->event_channel_,
this);
int result = 0;
{
ACE_GUARD_THROW_EX (
ACE_Lock, ace_mon, *this->lock_,
RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR ());
ACE_CHECK_RETURN (0);
if (this->is_connected_i () == 0)
return 0;
result =
this->child_->filter_nocopy (event, qos_info ACE_ENV_ARG_PARAMETER);
ACE_CHECK_RETURN (0);
}
return result;
}
void
TAO_EC_ProxyPushSupplier::push (const RtecEventComm::EventSet& event,
TAO_EC_QOS_Info& qos_info
ACE_ENV_ARG_DECL)
{
// The mutex is already held by the caller (usually the filter()
// method)
if (this->is_connected_i () == 0)
return; // TAO_THROW (RtecEventComm::Disconnected ());????
if (this->suspended_ != 0)
return;
TAO_ESF_RefCount_Guard<CORBA::ULong> ace_mon (this->refcount_);
// The guard will decrement the reference count, notice that the
// reference count can become 0, but this is not the right spot to
// check for that and destroy the object.
// If we did so then we would destroy the object, and consequently
// the mutex, but the mutex is used later when the stack unwinds and
// the filter() method tries to destroy the mutex (that originally
// acquired the mutex in the first place).
// So the correct thing to do is to just decrement the reference
// count and let the filter() method do the destruction.
RtecEventComm::PushConsumer_var consumer =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -