void TAO_EC_Default_ProxyPushConsumer::connect_push_supplier ( RtecEventComm::PushSupplier_ptr push_supplier, const RtecEventChannelAdmin::SupplierQOS& qos) { { ACE_GUARD_THROW_EX ( ACE_Lock, ace_mon, *this->lock_, CORBA::INTERNAL ()); // @@ RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR ()); if (this->is_connected_i ()) { if (this->event_channel_->supplier_reconnect () == 0) throw RtecEventChannelAdmin::AlreadyConnected (); // Re-connections are allowed, go ahead and disconnect the // consumer... this->cleanup_i (); // @@ Please read the comments in EC_ProxySuppliers about // possible race conditions in this area... TAO_EC_Unlock reverse_lock (*this->lock_); { ACE_GUARD_THROW_EX ( TAO_EC_Unlock, ace_mon, reverse_lock, CORBA::INTERNAL ()); // @@ RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR ()); this->event_channel_->reconnected (this); } // A separate thread could have connected siomultaneously, // this is probably an application error, handle it as // gracefully as possible if (this->is_connected_i ()) return; // @@ Should we throw } this->supplier_ = RtecEventComm::PushSupplier::_duplicate (push_supplier); this->connected_ = 1; this->qos_ = qos; #if TAO_EC_ENABLE_DEBUG_MESSAGES ORBSVCS_DEBUG ((LM_DEBUG, "Building filter for supplier <%x>.\n", this)); #endif /* TAO_EC_ENABLED_DEBUG_MESSAGES */ this->filter_ = this->event_channel_->supplier_filter_builder ()->create (this->qos_); this->filter_->bind (this); } // Notify the event channel... this->event_channel_->connected (this); }
CORBA::Boolean TAO_PG_ObjectGroupManager::valid_type_id ( PortableGroup::ObjectGroup_ptr object_group, TAO_PG_ObjectGroup_Map_Entry * group_entry, CORBA::Object_ptr member) { // @todo Strategize this -- e.g. strict type checking. if (CORBA::is_nil (member)) throw CORBA::BAD_PARAM (); // Before we can use this code, i.e. the reverse lock, the // TAO_PG_ObjectGroup_Entry should be made so that it is reference // counted. This is necessary since releasing the lock would // allow other threads to destroy/unbind the object group entry. // Another alternative is to simply attempt to reacquire the // object group map entry once the lock is reacquired, which is // easier to implement. // Copy the type_id before releasing the lock to avoid a race // condition. CORBA::String_var type_id = CORBA::string_dup (group_entry->type_id.in ()); CORBA::Boolean right_type_id = 0; { // Release the lock during the type_id check. No need to block // other threads during the invocation. ACE_Reverse_Lock<TAO_SYNCH_MUTEX> reverse_lock (this->lock_); ACE_GUARD_RETURN (ACE_Reverse_Lock<TAO_SYNCH_MUTEX>, reverse_guard, reverse_lock, right_type_id); // Make sure an Object of the correct type was created. It is // possible that an object of the wrong type was created if the // type_id parameter does not match the type of object the // GenericFactory creates. right_type_id = member->_is_a (type_id.in ()); } // Make sure the group entry still exists. It may have been // destroyed by another thread. (Call throws if problem.) static_cast<void> (this->get_group_entry (object_group)); return right_type_id; }
void TAO_EC_ProxyPushSupplier::push (const RtecEventComm::EventSet& event, TAO_EC_QOS_Info& qos_info) { // The mutex is already held by the caller (usually the filter() // method) if (!this->is_connected_i ()) return; // TAO_THROW (RtecEventComm::Disconnected ());???? if (this->suspended_) 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 = RtecEventComm::PushConsumer::_duplicate (this->consumer_.in ()); this->pre_dispatch_hook (const_cast<RtecEventComm::EventSet&> (event)); { // We have to release the lock to avoid dead-locks. TAO_EC_Unlock reverse_lock (*this->lock_); ACE_GUARD_THROW_EX (TAO_EC_Unlock, ace_mon, reverse_lock, RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR ()); this->event_channel_->dispatching ()->push (this, consumer.in (), event, qos_info); } if (this->child_ != 0) this->child_->clear (); }
void TAO_CEC_ProxyPushConsumer::connect_push_supplier ( CosEventComm::PushSupplier_ptr push_supplier) { { ACE_GUARD_THROW_EX ( ACE_Lock, ace_mon, *this->lock_, CORBA::INTERNAL ()); // @@ CosEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR ()); if (this->is_connected_i ()) { if (this->event_channel_->supplier_reconnect () == 0) throw CosEventChannelAdmin::AlreadyConnected (); // Re-connections are allowed, go ahead and disconnect the // consumer... this->cleanup_i (); // @@ Please read the comments in CEC_ProxyPushSupplier about // possible race conditions in this area... TAO_CEC_Unlock reverse_lock (*this->lock_); { ACE_GUARD_THROW_EX ( TAO_CEC_Unlock, ace_mon, reverse_lock, CORBA::INTERNAL ()); // @@ CosEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR ()); this->event_channel_->disconnected (this); } // What if a second thread connected us after this? if (this->is_connected_i ()) return; } this->supplier_ = apply_policy (push_supplier); this->connected_ = true; } // Notify the event channel... this->event_channel_->connected (this); }
void TAO_CEC_ProxyPullSupplier::connect_pull_consumer ( CosEventComm::PullConsumer_ptr pull_consumer) { { ACE_GUARD_THROW_EX ( ACE_Lock, ace_mon, *this->lock_, CORBA::INTERNAL ()); // @@ CosEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR ()); if (this->is_connected_i ()) { if (this->event_channel_->consumer_reconnect () == 0) throw CosEventChannelAdmin::AlreadyConnected (); // Re-connections are allowed.... this->cleanup_i (); this->consumer_ = apply_policy (pull_consumer); this->connected_ = 1; TAO_CEC_Unlock reverse_lock (*this->lock_); { ACE_GUARD_THROW_EX ( TAO_CEC_Unlock, ace_mon, reverse_lock, CORBA::INTERNAL ()); // @@ CosEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR ()); this->event_channel_->reconnected (this); } return; } this->consumer_ = apply_policy (pull_consumer); this->connected_ = 1; } // Notify the event channel... this->event_channel_->connected (this); }
void TAO_CEC_ProxyPushSupplier::push_nocopy (CORBA::Any &event) { Destroy_Guard auto_destroy (this->refcount_, this->event_channel_, this); { ACE_GUARD (ACE_Lock, ace_mon, *this->lock_); if (this->is_connected_i () == 0) return; TAO_ESF_RefCount_Guard<CORBA::ULong> cnt_mon (this->refcount_); { TAO_CEC_Unlock reverse_lock (*this->lock_); ACE_GUARD (TAO_CEC_Unlock, ace_mon, reverse_lock); this->event_channel_->dispatching ()->push_nocopy (this, event); } } }
void TAO_CEC_ProxyPushSupplier::invoke (const TAO_CEC_TypedEvent& typed_event) { Destroy_Guard_Typed auto_destroy (this->refcount_, this->typed_event_channel_, this); { ACE_GUARD (ACE_Lock, ace_mon, *this->lock_); if (this->is_connected_i () == 0) return; TAO_ESF_RefCount_Guard<CORBA::ULong> cnt_mon (this->refcount_); { TAO_CEC_Unlock reverse_lock (*this->lock_); ACE_GUARD (TAO_CEC_Unlock, ace_mon, reverse_lock); this->typed_event_channel_->dispatching ()->invoke (this, typed_event); } } }
void TAO_EC_Default_ProxyPushSupplier::connect_push_consumer ( RtecEventComm::PushConsumer_ptr push_consumer, const RtecEventChannelAdmin::ConsumerQOS& qos) { // Nil PushConsumers are illegal if (CORBA::is_nil (push_consumer)) throw CORBA::BAD_PARAM (); { ACE_GUARD_THROW_EX ( ACE_Lock, ace_mon, *this->lock_, CORBA::INTERNAL ()); // @@ RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR ()); if (this->is_connected_i ()) { if (this->event_channel_->consumer_reconnect () == 0) throw RtecEventChannelAdmin::AlreadyConnected (); // Re-connections are allowed.... this->cleanup_i (); this->consumer_ = RtecEventComm::PushConsumer::_duplicate (push_consumer); this->qos_ = qos; this->child_ = this->event_channel_->filter_builder ()->build (this, this->qos_); this->adopt_child (this->child_); TAO_EC_Unlock reverse_lock (*this->lock_); { ACE_GUARD_THROW_EX ( TAO_EC_Unlock, ace_mon, reverse_lock, CORBA::INTERNAL ()); // @@ RtecEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR ()); this->event_channel_->reconnected (this); } // A separate thread could have connected simultaneously, // this is probably an application error, handle it as // gracefully as possible if (this->is_connected_i ()) return; // @@ Should we throw } #if (TAO_HAS_CORBA_MESSAGING == 1) if ( consumer_validate_connection_ == 1 ) { // Validate connection during connect. CORBA::PolicyList_var unused; int status = push_consumer->_validate_connection (unused); #if TAO_EC_ENABLE_DEBUG_MESSAGES ORBSVCS_DEBUG ((LM_DEBUG, "Validated connection to PushConsumer on connect. Status[%d]\n", status)); #else ACE_UNUSED_ARG(status); #endif /* TAO_EC_ENABLED_DEBUG_MESSAGES */ } #endif /* TAO_HAS_CORBA_MESSAGING == 1 */ this->consumer_ = RtecEventComm::PushConsumer::_duplicate (push_consumer); this->qos_ = qos; #if TAO_EC_ENABLE_DEBUG_MESSAGES ORBSVCS_DEBUG ((LM_DEBUG, "Building filters for consumer <%x>.\n", this)); #endif /* TAO_EC_ENABLED_DEBUG_MESSAGES */ this->child_ = this->event_channel_->filter_builder ()->build (this, this->qos_); this->adopt_child (this->child_); } // Notify the event channel... this->event_channel_->connected (this); }
PortableGroup::ObjectGroup_ptr TAO_PG_ObjectGroupManager::remove_member ( PortableGroup::ObjectGroup_ptr object_group, const PortableGroup::Location & the_location) { ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, guard, this->lock_, 0); TAO_PG_ObjectGroup_Map_Entry * group_entry = this->get_group_entry (object_group); TAO_PG_ObjectGroup_Array * groups = 0; if (this->location_map_.find (the_location, groups) != 0) throw PortableGroup::ObjectGroupNotFound (); // Multiple members from different object groups may reside at the // same location. Iterate through the list to attempt to find a // match for the exact object group. If no match, -1 is returned. int to_be_removed = this->get_object_group_position (*groups, group_entry); if (to_be_removed == -1) throw PortableGroup::ObjectGroupNotFound (); // remove the element from the array and resize the array. this->remove_entry_from_groups (to_be_removed, groups); TAO_PG_MemberInfo_Set & member_infos = group_entry->member_infos; TAO_PG_MemberInfo_Set::iterator end = member_infos.end (); for (TAO_PG_MemberInfo_Set::iterator iter = member_infos.begin (); iter != end; ++iter) { const TAO_PG_MemberInfo & info = *iter; if (info.location == the_location) { // Give the GenericFactory a chance to delete a member if // its membership is under infrastructure control. if (this->generic_factory_) { CORBA::ULong group_id = group_entry->group_id; // Release the lock during the factory delete_member() // which may invoke delete_object()on registered factory. // No need to block other threads during the invocation. ACE_Reverse_Lock<TAO_SYNCH_MUTEX> reverse_lock (this->lock_); ACE_GUARD_RETURN (ACE_Reverse_Lock<TAO_SYNCH_MUTEX>, reverse_guard, reverse_lock, PortableGroup::ObjectGroup::_nil ()); this->generic_factory_->delete_member (group_id, the_location); } if (member_infos.remove (info) == 0) { if (this->generic_factory_) { this->generic_factory_->check_minimum_number_members ( object_group, group_entry->group_id, group_entry->type_id.in ()); } return PortableGroup::ObjectGroup::_duplicate (object_group); } else break; } } throw PortableGroup::MemberNotFound (); }
void TAO_CEC_ProxyPushSupplier::connect_push_consumer ( CosEventComm::PushConsumer_ptr push_consumer) { // Nil PushConsumers are illegal if (CORBA::is_nil (push_consumer)) throw CORBA::BAD_PARAM (); { #if defined (TAO_HAS_TYPED_EVENT_CHANNEL) // Check if we have a typed event channel if (this->is_typed_ec () ) { if (TAO_debug_level >= 10) { ORBSVCS_DEBUG ((LM_DEBUG, ACE_TEXT ("***** connect_push_consumer, ") ACE_TEXT ("Event channel is typed *****\n"))); } // Temporary for the TypedPushConsumer and it's Typed interface, // declared and obtained before the Guard to avoid deadlock during the // _is_a (during _narrow) and get_typed_consumer invocations. // They are eventually assigned onto this object inside the Guard. CosTypedEventComm::TypedPushConsumer_var local_typed_consumer = CosTypedEventComm::TypedPushConsumer::_narrow (push_consumer); // Obtain the typed object interface from the consumer CORBA::Object_var local_typed_consumer_obj = CORBA::Object::_duplicate (local_typed_consumer->get_typed_consumer () ); { ACE_GUARD_THROW_EX ( ACE_Lock, ace_mon, *this->lock_, CORBA::INTERNAL ()); // @@ CosEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR ()); if (this->is_connected_i ()) { if (this->typed_event_channel_->consumer_reconnect () == 0) throw CosEventChannelAdmin::AlreadyConnected (); // Re-connections are allowed.... this->cleanup_i (); this->typed_consumer_ = apply_policy (local_typed_consumer.in () ); TAO_CEC_Unlock reverse_lock (*this->lock_); { ACE_GUARD_THROW_EX ( TAO_CEC_Unlock, ace_mon, reverse_lock, CORBA::INTERNAL ()); // @@ CosEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR ()); this->typed_event_channel_->reconnected (this); } return; } this->typed_consumer_ = apply_policy (local_typed_consumer.in () ); // Store the typed object interface from the consumer this->typed_consumer_obj_ = apply_policy_obj (local_typed_consumer_obj.in () ); } // Notify the event channel... this->typed_event_channel_->connected (this); } /* this->is_typed_ec */ else { #endif /* TAO_HAS_TYPED_EVENT_CHANNEL */ if (TAO_debug_level >= 10) { ORBSVCS_DEBUG ((LM_DEBUG, ACE_TEXT ("***** connect_push_consumer, ") ACE_TEXT ("Event channel is un-typed *****\n"))); } { ACE_GUARD_THROW_EX ( ACE_Lock, ace_mon, *this->lock_, CORBA::INTERNAL ()); // @@ CosEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR ()); if (this->is_connected_i ()) { if (this->event_channel_->consumer_reconnect () == 0) throw CosEventChannelAdmin::AlreadyConnected (); // Re-connections are allowed.... this->cleanup_i (); this->consumer_ = apply_policy (push_consumer); TAO_CEC_Unlock reverse_lock (*this->lock_); { ACE_GUARD_THROW_EX ( TAO_CEC_Unlock, ace_mon, reverse_lock, CORBA::INTERNAL ()); // @@ CosEventChannelAdmin::EventChannel::SYNCHRONIZATION_ERROR ()); this->event_channel_->reconnected (this); } return; } this->consumer_ = apply_policy (push_consumer); } // Notify the event channel... this->event_channel_->connected (this); #if defined (TAO_HAS_TYPED_EVENT_CHANNEL) } /* ! this->is_typed_ec */ #endif /* TAO_HAS_TYPED_EVENT_CHANNEL */ } }