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;
}
Beispiel #3
0
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 ();
}
Beispiel #4
0
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 */
  }
}