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") )); } }
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") )); } }
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); } }