diff options
Diffstat (limited to 'TAO/orbsvcs/orbsvcs/Event/EC_ProxySupplier.cpp')
-rw-r--r-- | TAO/orbsvcs/orbsvcs/Event/EC_ProxySupplier.cpp | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/TAO/orbsvcs/orbsvcs/Event/EC_ProxySupplier.cpp b/TAO/orbsvcs/orbsvcs/Event/EC_ProxySupplier.cpp index d1384c41d72..9af16c805f7 100644 --- a/TAO/orbsvcs/orbsvcs/Event/EC_ProxySupplier.cpp +++ b/TAO/orbsvcs/orbsvcs/Event/EC_ProxySupplier.cpp @@ -96,7 +96,50 @@ TAO_EC_ProxyPushSupplier::connect_push_consumer ( ACE_CHECK; if (this->is_connected_i ()) - ACE_THROW (RtecEventChannelAdmin::AlreadyConnected ()); + { + if (this->event_channel_->consumer_reconnect () == 0) + ACE_THROW (RtecEventChannelAdmin::AlreadyConnected ()); + + // Re-connections are allowed, go ahead and disconnect the + // consumer... + this->consumer_ = + RtecEventComm::PushConsumer::_nil (); + + // @@ Why don't we have a destroy() method in the + // filter_builder? + delete this->child_; + this->child_ = 0; + + // @@ Are there any race conditions here: + // + The lock is released, but the object is marked as + // disconnected already, so: + // - No events will be pushed + // - Any disconnects will just return + // + But another thread could invoke connect_push_consumer() + // again, notice that by the time the lock is acquired + // again the connected() call may still be running. + // It seems like we need delayed operations again, or + // something similar to what the POA does in this + // scenario. + // Meanwhile we can tell the users: "if it hurts don't do + // it". + // + TAO_EC_Unlock reverse_lock (*this->lock_); + + { + ACE_GUARD_THROW_EX ( + TAO_EC_Unlock, ace_mon, reverse_lock, + RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR ()); + ACE_CHECK; + + this->event_channel_->disconnected (this, ACE_TRY_ENV); + ACE_CHECK; + } + + // What if a second thread connected us after this? + if (this->is_connected_i ()) + return; + } this->consumer_ = RtecEventComm::PushConsumer::_duplicate (push_consumer); |