EC_ProxyConsumer.cpp

Go to the documentation of this file.
00001 // $Id: EC_ProxyConsumer.cpp 76626 2007-01-26 13:50:03Z elliott_c $
00002 
00003 #include "orbsvcs/Event/EC_ProxyConsumer.h"
00004 #include "orbsvcs/Event/EC_Event_Channel_Base.h"
00005 #include "orbsvcs/Event/EC_Supplier_Filter.h"
00006 #include "orbsvcs/Event/EC_Supplier_Filter_Builder.h"
00007 
00008 #include "ace/Reverse_Lock_T.h"
00009 
00010 #if ! defined (__ACE_INLINE__)
00011 #include "orbsvcs/Event/EC_ProxyConsumer.inl"
00012 #endif /* __ACE_INLINE__ */
00013 
00014 ACE_RCSID (Event,
00015            EC_ProxyConsumer,
00016            "$Id: EC_ProxyConsumer.cpp 76626 2007-01-26 13:50:03Z elliott_c $")
00017 
00018 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00019 
00020 typedef ACE_Reverse_Lock<ACE_Lock> TAO_EC_Unlock;
00021 
00022 TAO_EC_ProxyPushConsumer::
00023     TAO_EC_ProxyPushConsumer (TAO_EC_Event_Channel_Base* ec)
00024   : event_channel_ (ec),
00025     refcount_ (1),
00026     connected_ (0),
00027     filter_ (0)
00028 {
00029   this->lock_ =
00030     this->event_channel_->create_consumer_lock ();
00031 
00032   this->default_POA_ =
00033     this->event_channel_->consumer_poa ();
00034 
00035   this->qos_.is_gateway = 0;
00036 }
00037 
00038 TAO_EC_ProxyPushConsumer::~TAO_EC_ProxyPushConsumer (void)
00039 {
00040   this->event_channel_->destroy_consumer_lock (this->lock_);
00041   this->cleanup_i ();
00042 }
00043 
00044 
00045 CORBA::Boolean
00046 TAO_EC_ProxyPushConsumer::supplier_non_existent (
00047       CORBA::Boolean_out disconnected)
00048 {
00049   CORBA::Object_var supplier;
00050   {
00051     ACE_GUARD_THROW_EX (
00052         ACE_Lock, ace_mon, *this->lock_,
00053         CORBA::INTERNAL ());
00054 
00055     disconnected = 0;
00056     if (this->is_connected_i () == 0)
00057       {
00058         disconnected = 1;
00059         return 0;
00060       }
00061     if (CORBA::is_nil (this->supplier_.in ()))
00062       {
00063         return 0;
00064       }
00065     supplier = CORBA::Object::_duplicate (this->supplier_.in ());
00066   }
00067 
00068 #if (TAO_HAS_MINIMUM_CORBA == 0)
00069   return supplier->_non_existent ();
00070 #else
00071   return 0;
00072 #endif /* TAO_HAS_MINIMUM_CORBA */
00073 }
00074 
00075 void
00076 TAO_EC_ProxyPushConsumer::connected (TAO_EC_ProxyPushSupplier* supplier)
00077 {
00078   TAO_EC_ProxyPushConsumer_Guard ace_mon (this->lock_,
00079                                           this->refcount_,
00080                                           this->event_channel_,
00081                                           this);
00082   if (!ace_mon.locked ())
00083     return;
00084 
00085   ace_mon.filter->connected (supplier);
00086 }
00087 
00088 void
00089 TAO_EC_ProxyPushConsumer::reconnected (TAO_EC_ProxyPushSupplier* supplier)
00090 {
00091   TAO_EC_ProxyPushConsumer_Guard ace_mon (this->lock_,
00092                                           this->refcount_,
00093                                           this->event_channel_,
00094                                           this);
00095   if (!ace_mon.locked ())
00096     return;
00097 
00098   ace_mon.filter->reconnected (supplier);
00099 }
00100 
00101 void
00102 TAO_EC_ProxyPushConsumer::disconnected (TAO_EC_ProxyPushSupplier* supplier)
00103 {
00104   TAO_EC_ProxyPushConsumer_Guard ace_mon (this->lock_,
00105                                           this->refcount_,
00106                                           this->event_channel_,
00107                                           this);
00108   if (!ace_mon.locked ())
00109     return;
00110 
00111   ace_mon.filter->disconnected (supplier);
00112 }
00113 
00114 void
00115 TAO_EC_ProxyPushConsumer::connected (TAO_EC_ProxyPushConsumer*)
00116 {
00117 }
00118 
00119 void
00120 TAO_EC_ProxyPushConsumer::reconnected (TAO_EC_ProxyPushConsumer*)
00121 {
00122 }
00123 
00124 void
00125 TAO_EC_ProxyPushConsumer::disconnected (TAO_EC_ProxyPushConsumer*)
00126 {
00127 }
00128 
00129 void
00130 TAO_EC_ProxyPushConsumer::shutdown_hook (void)
00131 {
00132 }
00133 
00134 void
00135 TAO_EC_ProxyPushConsumer::shutdown (void)
00136 {
00137   RtecEventComm::PushSupplier_var supplier;
00138 
00139   {
00140     ACE_GUARD_THROW_EX (
00141         ACE_Lock, ace_mon, *this->lock_,
00142         RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR ());
00143 
00144     supplier = this->supplier_._retn ();
00145     this->connected_ = 0;
00146 
00147     this->shutdown_hook ();
00148 
00149     if (this->filter_ != 0)
00150       {
00151         this->filter_->shutdown ();
00152 
00153         this->cleanup_i ();
00154       }
00155   }
00156 
00157   this->deactivate ();
00158 
00159   if (CORBA::is_nil (supplier.in ()))
00160     return;
00161 
00162   try
00163     {
00164       supplier->disconnect_push_supplier ();
00165     }
00166   catch (const CORBA::Exception&)
00167     {
00168       // Ignore exceptions, we must isolate other clients from
00169       // failures on this one.
00170     }
00171 }
00172 
00173 void
00174 TAO_EC_ProxyPushConsumer::cleanup_i (void)
00175 {
00176   this->supplier_ =
00177     RtecEventComm::PushSupplier::_nil ();
00178   this->connected_ = 0;
00179 
00180   if (this->filter_ != 0)
00181     {
00182       this->filter_->unbind (this);
00183       this->filter_->_decr_refcnt ();
00184       this->filter_ = 0;
00185     }
00186 }
00187 
00188 void
00189 TAO_EC_ProxyPushConsumer::deactivate (void)
00190 {
00191   try
00192     {
00193       PortableServer::ObjectId id =
00194           this->object_id ();
00195       this->default_POA_->deactivate_object (id);
00196     }
00197   catch (const CORBA::Exception&)
00198     {
00199       // Exceptions here should not be propagated.  They usually
00200       // indicate that an object is beign disconnected twice, or some
00201       // race condition, but not a fault that the user needs to know
00202       // about.
00203     }
00204 }
00205 
00206 CORBA::ULong
00207 TAO_EC_ProxyPushConsumer::_incr_refcnt (void)
00208 {
00209   ACE_GUARD_RETURN (ACE_Lock, ace_mon, *this->lock_, 0);
00210   return this->refcount_++;
00211 }
00212 
00213 void
00214 TAO_EC_ProxyPushConsumer::refcount_zero_hook (void)
00215 {
00216   // Use the event channel
00217   this->event_channel_->destroy_proxy (this);
00218 }
00219 
00220 CORBA::ULong
00221 TAO_EC_ProxyPushConsumer::_decr_refcnt (void)
00222 {
00223   {
00224     ACE_GUARD_RETURN (ACE_Lock, ace_mon, *this->lock_, 0);
00225     this->refcount_--;
00226     if (this->refcount_ != 0)
00227       return this->refcount_;
00228   }
00229 
00230   this->refcount_zero_hook ();
00231   return 0;
00232 }
00233 
00234 
00235 // ****************************************************************
00236 
00237 TAO_EC_ProxyPushConsumer_Guard::
00238     TAO_EC_ProxyPushConsumer_Guard (ACE_Lock *lock,
00239                                     CORBA::ULong &refcount,
00240                                     TAO_EC_Event_Channel_Base *ec,
00241                                     TAO_EC_ProxyPushConsumer *proxy)
00242  :   lock_ (lock),
00243      refcount_ (refcount),
00244      event_channel_ (ec),
00245      proxy_ (proxy),
00246      locked_ (0)
00247 {
00248   ACE_Guard<ACE_Lock> ace_mon (*this->lock_);
00249   // If the guard fails there is not much we can do, raising an
00250   // exception is wrong, the client has *no* way to handle that kind
00251   // of error.  Even worse, there is no exception to raise in that
00252   // case.
00253   // @@ Returning something won't work either, the error should be
00254   // logged though!
00255 
00256   if (proxy->is_connected_i () == 0)
00257     return;
00258 
00259   this->filter = this->proxy_->filter_i ();
00260   this->filter->_incr_refcnt ();
00261 
00262   this->locked_ = 1;
00263   this->refcount_++;
00264 }
00265 
00266 TAO_EC_ProxyPushConsumer_Guard::
00267     ~TAO_EC_ProxyPushConsumer_Guard (void)
00268 {
00269   // This access is safe because guard objects are created on the
00270   // stack, only one thread has access to them
00271   if (!this->locked_)
00272     return;
00273 
00274   {
00275     ACE_Guard<ACE_Lock> ace_mon (*this->lock_);
00276     // If the guard fails there is not much we can do, raising an
00277     // exception is wrong, the client has *no* way to handle that kind
00278     // of error.  Even worse, there is no exception to raise in that
00279     // case.
00280     // @@ Returning something won't work either, the error should be
00281     // logged though!
00282 
00283     this->filter->_decr_refcnt ();
00284 
00285     this->refcount_--;
00286     if (this->refcount_ != 0)
00287       return;
00288   }
00289 
00290   this->proxy_->refcount_zero_hook ();
00291 }
00292 
00293 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:44:05 2010 for TAO_RTEvent by  doxygen 1.4.7