예제 #1
0
void
Publisher::run()
{
  DDS::Duration_t   timeout = { DDS::DURATION_INFINITE_SEC, DDS::DURATION_INFINITE_NSEC};
  DDS::ConditionSeq conditions;
  DDS::PublicationMatchedStatus matches = { 0, 0, 0, 0, 0};
  unsigned int cummulative_count = 0;
  do {
    if( this->options_.verbose()) {
      ACE_DEBUG((LM_DEBUG,
        ACE_TEXT("(%P|%t) Publisher::run() - ")
        ACE_TEXT("%d of %d subscriptions attached, waiting for more.\n"),
        cummulative_count,
        this->publications_.size()
      ));
    }
    if( DDS::RETCODE_OK != this->waiter_->wait( conditions, timeout)) {
      ACE_ERROR((LM_ERROR,
        ACE_TEXT("(%P|%t) ERROR: Publisher::run() - ")
        ACE_TEXT("failed to synchronize at start of test.\n")
      ));
      throw BadSyncException();
    }
    for( unsigned long index = 0; index < conditions.length(); ++index) {
      DDS::StatusCondition_var condition
        = DDS::StatusCondition::_narrow( conditions[ index].in());

      DDS::DataWriter_var writer = DDS::DataWriter::_narrow( condition->get_entity());
      if( !CORBA::is_nil( writer.in())) {
        DDS::StatusMask changes = writer->get_status_changes();
        if( changes & DDS::PUBLICATION_MATCHED_STATUS) {
          if (writer->get_publication_matched_status(matches) != ::DDS::RETCODE_OK)
          {
            ACE_ERROR ((LM_ERROR,
              "ERROR: failed to get publication matched status\n"));
            ACE_OS::exit (1);
          }
          cummulative_count += matches.current_count_change;
        }
      }
    }

  } while( cummulative_count < this->publications_.size());

  // Kluge to bias the race between BuiltinTopic samples and application
  // samples towards the BuiltinTopics during association establishment.
  ACE_OS::sleep( 2);

  if( this->options_.verbose()) {
    ACE_DEBUG((LM_DEBUG,
      ACE_TEXT("(%P|%t) Publisher::run() - ")
      ACE_TEXT("starting to publish samples with %d matched subscriptions.\n"),
      cummulative_count
    ));
  }

  for( PublicationMap::const_iterator current = this->publications_.begin();
       current != this->publications_.end();
       ++current
     ) {
    current->second->start();
  }

  // Execute test for specified duration, or block until terminated externally.
  if( this->options_.duration() > 0) {
    ACE_Time_Value duration( this->options_.duration(), 0);
    ACE_OS::sleep( duration);

  } else {
    // Block the main thread, leaving the others working.
    ACE_Thread_Manager::instance()->wait();
  }

  // Signal the writers to terminate.
  for( PublicationMap::const_iterator current = this->publications_.begin();
       current != this->publications_.end();
       ++current
     ) {
    current->second->stop();
  }

  // Separate loop so the termination messages can be handled concurrently.
  for( PublicationMap::const_iterator current = this->publications_.begin();
       current != this->publications_.end();
       ++current
     ) {
    // Join and clean up.
    current->second->wait();
    ACE_DEBUG((LM_DEBUG,
      ACE_TEXT("(%P|%t) Publisher::run() - ")
      ACE_TEXT("publication %C stopping after sending %d messages.\n"),
      current->first.c_str(),
      current->second->messages()
    ));
    delete current->second;
  }
  this->publications_.clear();

  if( this->options_.verbose()) {
    ACE_DEBUG((LM_DEBUG,
      ACE_TEXT("(%P|%t) Publisher::run() - ")
      ACE_TEXT("finished publishing samples.\n")
    ));
  }
}
예제 #2
0
void
Publisher::run()
{
  DDS::Duration_t   timeout = { DDS::DURATION_INFINITE_SEC, DDS::DURATION_INFINITE_NSEC};
  DDS::ConditionSeq conditions;
  DDS::PublicationMatchedStatus matches = { 0, 0, 0, 0, 0};
  const int readers_per_publication = 2;
  unsigned int cummulative_count = 0;
  do {
    if( this->options_.verbose()) {
      ACE_DEBUG((LM_DEBUG,
        ACE_TEXT("(%P|%t) Publisher::run() - ")
        ACE_TEXT("%d of %d subscriptions attached, waiting for more.\n"),
        cummulative_count,
        this->publications_.size()*readers_per_publication
      ));
    }
    if( DDS::RETCODE_OK != this->waiter_->wait( conditions, timeout)) {
      ACE_ERROR((LM_ERROR,
        ACE_TEXT("(%P|%t) ERROR: Publisher::run() - ")
        ACE_TEXT("failed to synchronize at start of test.\n")
      ));
      throw BadSyncException();
    }
    for( unsigned long index = 0; index < conditions.length(); ++index) {
      DDS::StatusCondition_var condition
        = DDS::StatusCondition::_narrow( conditions[ index].in());

      DDS::Entity_var writer_entity = condition->get_entity();
      DDS::DataWriter_var writer = DDS::DataWriter::_narrow( writer_entity);
      if( !CORBA::is_nil( writer.in())) {
        DDS::StatusMask changes = writer->get_status_changes();
        if( changes & DDS::PUBLICATION_MATCHED_STATUS) {
          if (writer->get_publication_matched_status(matches) != ::DDS::RETCODE_OK)
          {
            ACE_ERROR ((LM_ERROR,
              "ERROR: failed to get publication matched status\n"));
            ACE_OS::exit (1);
          }
          cummulative_count += matches.current_count_change;
        }
      }
    }

  // We know that there are 2 subscriptions matched with each publication.
  } while( cummulative_count < (readers_per_publication*this->publications_.size()));

  // Kluge to bias the race between BuiltinTopic samples and application
  // samples towards the BuiltinTopics during association establishment.
  // ACE_OS::sleep( 2);

  if( this->options_.verbose()) {
    ACE_DEBUG((LM_DEBUG,
      ACE_TEXT("(%P|%t) Publisher::run() - ")
      ACE_TEXT("starting to publish samples with %d matched subscriptions.\n"),
      cummulative_count
    ));
  }

  for( unsigned int index = 0; index < this->publications_.size(); ++index) {
    this->publications_[ index]->start();
  }

  // Allow some traffic to occur before making any wait() calls.
  ACE_OS::sleep( 2);

  ::DDS::Duration_t delay = { 5, 0 }; // Wait for up to 5 seconds.
  if (this->options_.publisher())
  {
    DDS::ReturnCode_t error =
      this->publisher_->wait_for_acknowledgments(delay);
    if (error != DDS::RETCODE_OK)
    {
      ACE_DEBUG((LM_DEBUG,
        ACE_TEXT("(%P|%t) ERROR: Publisher::run() - ")
        ACE_TEXT("publisher wait failed with code: %d.\n"),
        error));
      ++this->status_;
    }
  }
  else
  {
    for( unsigned int index = 0; index < this->publications_.size(); ++index) {
      // First wait on this writer.
      ::DDS::ReturnCode_t result
        = this->publications_[ index]->wait_for_acks( delay);
      if( result != ::DDS::RETCODE_OK) {
        ACE_DEBUG((LM_DEBUG,
          ACE_TEXT("(%P|%t) ERROR: Publisher::run() - ")
          ACE_TEXT("publication %d wait failed with code: %d.\n"),
          index,
          result
        ));
        ++this->status_;
      }
    }
  }

  // Signal the writers to terminate.
  for( unsigned int index = 0; index < this->publications_.size(); ++index) {
    this->publications_[ index]->stop();
  }

  // Additional wait() calls will be made by each thread during shutdown.

  // Separate loop so the termination messages can be handled concurrently.
  for( unsigned int index = 0; index < this->publications_.size(); ++index) {
    // Join and clean up.
    this->publications_[ index]->wait();
    ACE_DEBUG((LM_DEBUG,
      ACE_TEXT("(%P|%t) Publisher::run() - ")
      ACE_TEXT("publication %d stopping after sending %d messages.\n"),
      index,
      this->publications_[ index]->messages()
    ));
    this->status_ += this->publications_[ index]->status();
    delete this->publications_[ index];
  }
  this->publications_.clear();

  if( this->options_.verbose()) {
    ACE_DEBUG((LM_DEBUG,
      ACE_TEXT("(%P|%t) Publisher::run() - ")
      ACE_TEXT("finished publishing samples.\n")
    ));
  }
}
예제 #3
0
void
Publisher::run()
{
  DDS::Duration_t   timeout = { DDS::DURATION_INFINITE_SEC, DDS::DURATION_INFINITE_NSEC};
  DDS::ConditionSeq conditions;
  DDS::PublicationMatchedStatus matches = { 0, 0, 0, 0, 0};
  unsigned int cummulative_count = 0;
  do {
    if( this->options_.verbose()) {
      ACE_DEBUG((LM_DEBUG,
        ACE_TEXT("(%P|%t) Publisher::run() - ")
        ACE_TEXT("%d of 2 subscriptions attached, waiting for more.\n"),
        cummulative_count
      ));
    }
    if( DDS::RETCODE_OK != this->waiter_->wait( conditions, timeout)) {
      ACE_ERROR((LM_ERROR,
        ACE_TEXT("(%P|%t) ERROR: Publisher::run() - ")
        ACE_TEXT("failed to synchronize at start of test.\n")
      ));
      throw BadSyncException();
    }
    for( unsigned long index = 0; index < conditions.length(); ++index) {
      DDS::StatusCondition_var condition
        = DDS::StatusCondition::_narrow( conditions[ index].in());

      DDS::Entity_var writer_entity = condition->get_entity();
      DDS::DataWriter_var writer = DDS::DataWriter::_narrow( writer_entity);
      if( !CORBA::is_nil( writer.in())) {
        DDS::StatusMask changes = writer->get_status_changes();
        if( changes & DDS::PUBLICATION_MATCHED_STATUS) {
          if (writer->get_publication_matched_status(matches) != ::DDS::RETCODE_OK)
          {
            ACE_ERROR ((LM_ERROR,
              "ERROR: failed to get publication matched status\n"));
            ACE_OS::exit (1);
          }
          cummulative_count += matches.current_count_change;
        }
      }
    }

  } while( cummulative_count < 2);

  /// Kluge to ensure that the remote/subscriber side endpoints have
  /// been fully associated before starting to send.  This appears to be
  /// a race between the association creation and use and the BuiltIn
  /// Topic data becoming available.  There is no existing mechanism (nor
  /// should there be) to prevent an association from exchanging data
  /// prior to the remote endpoint information becoming available via the
  /// BuiltIn Topic publications.
  ACE_OS::sleep( 2);

  ACE_DEBUG((LM_DEBUG,
    ACE_TEXT("(%P|%t) Publisher::run() - ")
    ACE_TEXT("starting to publish samples.\n")
  ));

  Test::DataDataWriter_var writer0
    = Test::DataDataWriter::_narrow( this->writer_[0].in());
  Test::DataDataWriter_var writer1
    = Test::DataDataWriter::_narrow( this->writer_[1].in());
  Test::Data sample0;
  Test::Data sample1;
  sample0.key = 1;
  sample0.value = 0;
  // before_value is just for the high priority sample, low priority samples are in order
  sample0.before_value = 0;
  sample0.priority = false;
  // add some extra baggage to ensure
  sample0.baggage.length(9999);

  if (options_.multipleInstances())
    sample1.key = 2;
  else
    sample1.key = 1;
  sample1.value = 0;
  // will determine later which value this sample should be seen before
  sample1.before_value = 0;
  sample1.priority = true;
  bool sent = false;
  for (unsigned long num_samples = 1; num_samples < (unsigned long)-1 && !sent; ++num_samples) {
    ++sample0.value;
    if (writer0->write( sample0, DDS::HANDLE_NIL) == DDS::RETCODE_TIMEOUT) {
      // indicate the high priority sample should arrive before the indicated low priority sample
      sample1.before_value = sample0.value - 1;
      while (writer1->write( sample1, DDS::HANDLE_NIL) == DDS::RETCODE_TIMEOUT) {
        ACE_ERROR((LM_ERROR,
          ACE_TEXT("(%P|%t) ERROR: Publisher::run() - ")
          ACE_TEXT("should not have backpressure for the second writer.\n")
        ));
      }
      sent = true;
    }
  }

  ACE_DEBUG((LM_DEBUG,
    ACE_TEXT("(%P|%t) Publisher::run() - ")
    ACE_TEXT("finished publishing %d samples.\n"),
    sample0.value
  ));

  // Make sure that the data has arriven.
  ::DDS::Duration_t shutdownDelay = {15, 0}; // Wait up to a total of 15
                                             // seconds to finish the test.
  if (this->options_.transportType() != Options::UDP) {
    writer0->wait_for_acknowledgments(shutdownDelay);
    writer1->wait_for_acknowledgments(shutdownDelay);
  } else {
    // Wait for acks won't work with UDP...
    ACE_OS::sleep(15);
  }
}