diff options
Diffstat (limited to 'TAO/orbsvcs/orbsvcs/Event/EC_ProxyConsumer.cpp')
-rw-r--r-- | TAO/orbsvcs/orbsvcs/Event/EC_ProxyConsumer.cpp | 310 |
1 files changed, 310 insertions, 0 deletions
diff --git a/TAO/orbsvcs/orbsvcs/Event/EC_ProxyConsumer.cpp b/TAO/orbsvcs/orbsvcs/Event/EC_ProxyConsumer.cpp new file mode 100644 index 00000000000..f16960141c1 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Event/EC_ProxyConsumer.cpp @@ -0,0 +1,310 @@ +// $Id$ + +#include "orbsvcs/Event/EC_ProxyConsumer.h" +#include "orbsvcs/Event/EC_Event_Channel_Base.h" +#include "orbsvcs/Event/EC_Supplier_Filter.h" +#include "orbsvcs/Event/EC_Supplier_Filter_Builder.h" + +#include "ace/Reverse_Lock_T.h" + +#if ! defined (__ACE_INLINE__) +#include "orbsvcs/Event/EC_ProxyConsumer.i" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID (Event, + EC_ProxyConsumer, + "$Id$") + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +typedef ACE_Reverse_Lock<ACE_Lock> TAO_EC_Unlock; + +TAO_EC_ProxyPushConsumer:: + TAO_EC_ProxyPushConsumer (TAO_EC_Event_Channel_Base* ec) + : event_channel_ (ec), + refcount_ (1), + connected_ (0), + filter_ (0) +{ + this->lock_ = + this->event_channel_->create_consumer_lock (); + + this->default_POA_ = + this->event_channel_->consumer_poa (); + + this->qos_.is_gateway = 0; +} + +TAO_EC_ProxyPushConsumer::~TAO_EC_ProxyPushConsumer (void) +{ + this->event_channel_->destroy_consumer_lock (this->lock_); + this->cleanup_i (); +} + + +CORBA::Boolean +TAO_EC_ProxyPushConsumer::supplier_non_existent ( + CORBA::Boolean_out disconnected + ACE_ENV_ARG_DECL) +{ + CORBA::Object_var supplier; + { + ACE_GUARD_THROW_EX ( + ACE_Lock, ace_mon, *this->lock_, + CORBA::INTERNAL ()); + ACE_CHECK_RETURN (0); + + disconnected = 0; + if (this->is_connected_i () == 0) + { + disconnected = 1; + return 0; + } + if (CORBA::is_nil (this->supplier_.in ())) + { + return 0; + } + supplier = CORBA::Object::_duplicate (this->supplier_.in ()); + } + +#if (TAO_HAS_MINIMUM_CORBA == 0) + return supplier->_non_existent (ACE_ENV_SINGLE_ARG_PARAMETER); +#else + return 0; +#endif /* TAO_HAS_MINIMUM_CORBA */ +} + +void +TAO_EC_ProxyPushConsumer::connected (TAO_EC_ProxyPushSupplier* supplier + ACE_ENV_ARG_DECL) +{ + TAO_EC_ProxyPushConsumer_Guard ace_mon (this->lock_, + this->refcount_, + this->event_channel_, + this); + if (!ace_mon.locked ()) + return; + + ace_mon.filter->connected (supplier ACE_ENV_ARG_PARAMETER); +} + +void +TAO_EC_ProxyPushConsumer::reconnected (TAO_EC_ProxyPushSupplier* supplier + ACE_ENV_ARG_DECL) +{ + TAO_EC_ProxyPushConsumer_Guard ace_mon (this->lock_, + this->refcount_, + this->event_channel_, + this); + if (!ace_mon.locked ()) + return; + + ace_mon.filter->reconnected (supplier ACE_ENV_ARG_PARAMETER); +} + +void +TAO_EC_ProxyPushConsumer::disconnected (TAO_EC_ProxyPushSupplier* supplier + ACE_ENV_ARG_DECL) +{ + TAO_EC_ProxyPushConsumer_Guard ace_mon (this->lock_, + this->refcount_, + this->event_channel_, + this); + if (!ace_mon.locked ()) + return; + + ace_mon.filter->disconnected (supplier ACE_ENV_ARG_PARAMETER); +} + +void +TAO_EC_ProxyPushConsumer::connected (TAO_EC_ProxyPushConsumer* + ACE_ENV_ARG_DECL_NOT_USED) +{ +} + +void +TAO_EC_ProxyPushConsumer::reconnected (TAO_EC_ProxyPushConsumer* + ACE_ENV_ARG_DECL_NOT_USED) +{ +} + +void +TAO_EC_ProxyPushConsumer::disconnected (TAO_EC_ProxyPushConsumer* + ACE_ENV_ARG_DECL_NOT_USED) +{ +} + +void +TAO_EC_ProxyPushConsumer::shutdown_hook (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) +{ +} + +void +TAO_EC_ProxyPushConsumer::shutdown (ACE_ENV_SINGLE_ARG_DECL) +{ + RtecEventComm::PushSupplier_var supplier; + + { + ACE_GUARD_THROW_EX ( + ACE_Lock, ace_mon, *this->lock_, + RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR ()); + ACE_CHECK; + + supplier = this->supplier_._retn (); + this->connected_ = 0; + + this->shutdown_hook (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + if (this->filter_ != 0) + { + this->filter_->shutdown (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + this->cleanup_i (); + } + } + + this->deactivate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + if (CORBA::is_nil (supplier.in ())) + return; + + ACE_TRY + { + supplier->disconnect_push_supplier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + // Ignore exceptions, we must isolate other clients from + // failures on this one. + } + ACE_ENDTRY; +} + +void +TAO_EC_ProxyPushConsumer::cleanup_i (void) +{ + this->supplier_ = + RtecEventComm::PushSupplier::_nil (); + this->connected_ = 0; + + if (this->filter_ != 0) + { + this->filter_->unbind (this); + this->filter_->_decr_refcnt (); + this->filter_ = 0; + } +} + +void +TAO_EC_ProxyPushConsumer::deactivate (ACE_ENV_SINGLE_ARG_DECL) +{ + 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_ProxyPushConsumer::_incr_refcnt (void) +{ + ACE_GUARD_RETURN (ACE_Lock, ace_mon, *this->lock_, 0); + return this->refcount_++; +} + +void +TAO_EC_ProxyPushConsumer::refcount_zero_hook (void) +{ + // Use the event channel + this->event_channel_->destroy_proxy (this); +} + +CORBA::ULong +TAO_EC_ProxyPushConsumer::_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; +} + + +// **************************************************************** + +TAO_EC_ProxyPushConsumer_Guard:: + TAO_EC_ProxyPushConsumer_Guard (ACE_Lock *lock, + CORBA::ULong &refcount, + TAO_EC_Event_Channel_Base *ec, + TAO_EC_ProxyPushConsumer *proxy) + : lock_ (lock), + refcount_ (refcount), + event_channel_ (ec), + proxy_ (proxy), + locked_ (0) +{ + ACE_Guard<ACE_Lock> ace_mon (*this->lock_); + // If the guard fails there is not much we can do, raising an + // exception is wrong, the client has *no* way to handle that kind + // of error. Even worse, there is no exception to raise in that + // case. + // @@ Returning something won't work either, the error should be + // logged though! + + if (proxy->is_connected_i () == 0) + return; + + this->filter = this->proxy_->filter_i (); + this->filter->_incr_refcnt (); + + this->locked_ = 1; + this->refcount_++; +} + +TAO_EC_ProxyPushConsumer_Guard:: + ~TAO_EC_ProxyPushConsumer_Guard (void) +{ + // This access is safe because guard objects are created on the + // stack, only one thread has access to them + if (!this->locked_) + return; + + { + ACE_Guard<ACE_Lock> ace_mon (*this->lock_); + // If the guard fails there is not much we can do, raising an + // exception is wrong, the client has *no* way to handle that kind + // of error. Even worse, there is no exception to raise in that + // case. + // @@ Returning something won't work either, the error should be + // logged though! + + this->filter->_decr_refcnt (); + + this->refcount_--; + if (this->refcount_ != 0) + return; + } + + this->proxy_->refcount_zero_hook (); +} + +TAO_END_VERSIONED_NAMESPACE_DECL |