summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/orbsvcs/Event/EC_ProxyConsumer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/orbsvcs/orbsvcs/Event/EC_ProxyConsumer.cpp')
-rw-r--r--TAO/orbsvcs/orbsvcs/Event/EC_ProxyConsumer.cpp310
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