int ACE_TMAIN (int argc, ACE_TCHAR *argv[]){ try { DDS::DomainParticipantFactory_var dpf = TheParticipantFactoryWithArgs(argc, argv); DDS::DomainParticipant_var participant = dpf->create_participant(311, PARTICIPANT_QOS_DEFAULT, DDS::DomainParticipantListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (participant.in ())) { cerr << "create_participant failed." << endl; return 1; } MessageTypeSupportImpl* servant = new MessageTypeSupportImpl(); if (DDS::RETCODE_OK != servant->register_type(participant.in (), "")) { cerr << "register_type failed." << endl; exit(1); } CORBA::String_var type_name = servant->get_type_name (); DDS::TopicQos topic_qos; participant->get_default_topic_qos(topic_qos); DDS::Topic_var topic = participant->create_topic ("Movie Discussion List", type_name.in (), topic_qos, DDS::TopicListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (topic.in ())) { cerr << "create_topic failed." << endl; exit(1); } DDS::PublisherQos pub_qos; participant->get_default_publisher_qos (pub_qos); pub_qos.partition.name.length (1); pub_qos.partition.name[0] = PARTITION_A; DDS::Publisher_var pub = participant->create_publisher(pub_qos, DDS::PublisherListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (pub.in ())) { cerr << "create_publisher failed." << endl; exit(1); } // ---------------------------------------------- // Create DataWriter which is belongs to PARTITION_A DDS::DataWriter_var dw = pub->create_datawriter (topic.in (), DATAWRITER_QOS_DEFAULT, DDS::DataWriterListener::_nil (), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); int const max_attempts = 15; int attempts = 1; // ---------------------------------------------- // Wait for first DataReader that belongs to PARTITION_A too, // then write samples. // cache handle for first reader. ::DDS::InstanceHandle_t handle = -1; { std::auto_ptr<Writer> writer (new Writer (dw.in ())); cout << "Pub waiting for match on A partition." << std::endl; if (OpenDDS::Model::WriterSync::wait_match(dw)) { cerr << "Error waiting for match on A partition" << std::endl; return 1; } while (attempts != max_attempts) { ::DDS::InstanceHandleSeq handles; dw->get_matched_subscriptions(handles); cout << "Pub matched " << handles.length() << " A subs." << std::endl; if (handles.length() == 1) { handle = handles[0]; break; } else ACE_OS::sleep(1); ++attempts; } if (attempts == max_attempts) { cerr << "ERROR: failed to wait for first DataReader." << endl; exit (1); } writer->start (); writer->end (); } // ---------------------------------------------- // Switch from PARTITION A to B, now the first DataReader belong to // PARTITION A should be disconnected and the second DataReader belong to // PARTITION B should be connected. pub_qos.partition.name[0] = PARTITION_B; if (pub->set_qos (pub_qos)!= ::DDS::RETCODE_OK) { cerr << "ERROR: DataWriter changed partition which should be compatible " << "but should disconnect with DataReaders" << endl; exit (1); } // ---------------------------------------------- // Now DataWriter is in PARTITION B, the second DataReader in PARTITION B // should receive the messages. { std::auto_ptr<Writer> writer (new Writer (dw.in ())); cout << "Pub waiting for match on B partition." << std::endl; if (OpenDDS::Model::WriterSync::wait_match(dw)) { cerr << "Error waiting for match on B partition" << std::endl; return 1; } attempts = 1; while (attempts != max_attempts) { ::DDS::InstanceHandleSeq handles; dw->get_matched_subscriptions(handles); cout << "Pub matched " << handles.length() << " B subs." << std::endl; if (handles.length() == 1 && handles[0] != handle) break; else ACE_OS::sleep(1); ++attempts; } if (attempts == max_attempts) { cerr << "ERROR: subscriptions failed to match." << endl; exit (1); } writer->start (); writer->end (); } // ---------------------------------------------- // Wait for first reader to switch from PARTITION A to B so // both two readers will receive the messages. { std::auto_ptr<Writer> writer (new Writer (dw.in ())); attempts = 1; while (attempts != max_attempts) { ::DDS::InstanceHandleSeq handles; dw->get_matched_subscriptions(handles); if (handles.length() == 2) break; else ACE_OS::sleep(1); ++ attempts; } if (attempts == max_attempts) { cerr << "ERROR: failed to wait for DataReader partition switch." << endl; exit (1); } writer->start (); writer->end (); } // ---------------------------------------------- // Now wait for subscriber exit. { attempts = 1; while (attempts != max_attempts) { ::DDS::InstanceHandleSeq handles; dw->get_matched_subscriptions(handles); if (handles.length() == 0) break; else ACE_OS::sleep(1); ++ attempts; } } participant->delete_contained_entities(); dpf->delete_participant(participant.in ()); } catch (CORBA::Exception& e) { cerr << "PUB: Exception caught in main.cpp:" << endl << e << endl; exit(1); } TheServiceParticipant->shutdown (); return 0; }
int ACE_TMAIN (int argc, ACE_TCHAR *argv[]){ try { DDS::DomainParticipantFactory_var dpf = TheParticipantFactoryWithArgs(argc, argv); DDS::DomainParticipant_var participant = dpf->create_participant(11, PARTICIPANT_QOS_DEFAULT, DDS::DomainParticipantListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (participant.in ())) { cerr << "create_participant failed." << endl; return 1; } MessageTypeSupportImpl* servant = new MessageTypeSupportImpl(); if (DDS::RETCODE_OK != servant->register_type(participant.in (), "")) { cerr << "register_type failed." << endl; exit(1); } CORBA::String_var type_name = servant->get_type_name (); DDS::TopicQos topic_qos; participant->get_default_topic_qos(topic_qos); DDS::Topic_var topic = participant->create_topic ("Movie Discussion List", type_name.in (), topic_qos, DDS::TopicListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (topic.in ())) { cerr << "create_topic failed." << endl; exit(1); } DDS::Publisher_var pub = participant->create_publisher(PUBLISHER_QOS_DEFAULT, DDS::PublisherListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (pub.in ())) { cerr << "create_publisher failed." << endl; exit(1); } // ---------------------------------------------- // Create the listener. DDS::DataWriterListener_var listener (new DataWriterListenerImpl); if (CORBA::is_nil (listener.in ())) { cerr << "ERROR: listener is nil." << endl; exit(1); } DDS::DataWriterQos dw_qos; // Good QoS. pub->get_default_datawriter_qos (dw_qos); assert (DEADLINE_PERIOD.sec > 1); // Requirement for the test. // First data writer will have a listener to test listener // callback on deadline expiration. DDS::DataWriter_var dw = pub->create_datawriter (topic.in (), dw_qos, listener.in (), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (dw.in ())) { cerr << "ERROR: create_datawriter failed." << endl; exit(1); } dw_qos.deadline.period.sec = DEADLINE_PERIOD.sec; dw_qos.deadline.period.nanosec = DEADLINE_PERIOD.nanosec; // Set qos with deadline. The watch dog starts now. if (dw->set_qos (dw_qos) != ::DDS::RETCODE_OK) { cerr << "ERROR: set deadline qos failed." << endl; exit(1); } { // Two threads use same datawriter to write different instances. std::auto_ptr<Writer> writer1 (new Writer (dw.in (), 99, SLEEP_DURATION)); std::auto_ptr<Writer> writer2 (new Writer (dw.in (), 100, SLEEP_DURATION)); writer1->start (); writer2->start (); // ---------------------------------------------- // Wait for fully associate with DataReaders. if (writer1->wait_for_start () == false || writer2->wait_for_start () == false) { cerr << "ERROR: took too long to associate. " << endl; exit (1); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Publisher: sleep for %d milliseconds\n"), SLEEP_DURATION.msec ())); // Wait for a set of deadline periods to expire. ACE_OS::sleep (SLEEP_DURATION); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Publisher: now verify missed ") ACE_TEXT ("deadline status \n"))); ::DDS::InstanceHandle_t handle1 = writer1->get_instance_handle (); ::DDS::InstanceHandle_t handle2 = writer2->get_instance_handle (); DDS::OfferedDeadlineMissedStatus deadline_status; if (dw->get_offered_deadline_missed_status(deadline_status) != ::DDS::RETCODE_OK) { cerr << "ERROR: Failed to get offered deadline missed status" << endl; exit (1); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Publisher: got missed") ACE_TEXT ("deadline status \n"))); if (deadline_status.total_count != NUM_EXPIRATIONS * NUM_WRITE_THREADS) { cerr << "ERROR: Unexpected number of missed offered " << "deadlines (" << deadline_status.total_count << " instead of " << NUM_EXPIRATIONS * NUM_WRITE_THREADS << ") " << endl; exit (1); } if (deadline_status.total_count_change != NUM_EXPIRATIONS * NUM_WRITE_THREADS) { cerr << "ERROR: Incorrect missed offered " << "deadline count change (" << deadline_status.total_count_change << ") instead of " << NUM_EXPIRATIONS * NUM_WRITE_THREADS << endl; exit (1); } if (deadline_status.last_instance_handle != handle1 && deadline_status.last_instance_handle != handle2) { cerr << "ERROR: Unexpected last instance handle " << deadline_status.last_instance_handle << " instead of " << handle1 << " or " << handle2 << endl; exit (1); } writer1->wait (); writer2->wait (); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Publisher: sleep for %d milliseconds\n"), SLEEP_DURATION.msec())); // Wait for another set of deadline periods to expire. ACE_OS::sleep (SLEEP_DURATION); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Publisher: now verify missed ") ACE_TEXT ("deadline status \n"))); if (dw->get_offered_deadline_missed_status(deadline_status) != ::DDS::RETCODE_OK) { cerr << "ERROR: Failed to get offered deadline missed status" << endl; exit (1); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Publisher: got missed") ACE_TEXT ("deadline status \n"))); if (deadline_status.total_count != (NUM_EXPIRATIONS + 2) * NUM_WRITE_THREADS) { cerr << "ERROR: Unexpected number of missed offered " << "deadlines (" << deadline_status.total_count << " instead of " << (NUM_EXPIRATIONS + 2) * NUM_WRITE_THREADS << ") " << endl; exit (1); } if (deadline_status.total_count_change != NUM_WRITE_THREADS * 2) { cerr << "ERROR: Incorrect missed offered " << "deadline count change (" << deadline_status.total_count_change << ") instead of " << NUM_WRITE_THREADS * 2 << endl; exit (1); } if (deadline_status.last_instance_handle != handle1 && deadline_status.last_instance_handle != handle2) { cerr << "ERROR: Unexpected last instance handle " << deadline_status.last_instance_handle << " instead of " << handle1 << " or " << handle2 << endl; exit (1); } // Wait for datareader finish. while (1) { ::DDS::InstanceHandleSeq handles; dw->get_matched_subscriptions (handles); if (handles.length () == 0) break; else ACE_OS::sleep(1); } } participant->delete_contained_entities(); dpf->delete_participant(participant.in ()); TheServiceParticipant->shutdown (); } catch (CORBA::Exception& e) { cerr << "PUB: Exception caught in main.cpp:" << endl << e << endl; exit(1); } return 0; }
int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) { try { DDS::DomainParticipantFactory_var dpf = TheParticipantFactoryWithArgs (argc, argv); DDS::DomainParticipant_var participant = dpf->create_participant (411, PARTICIPANT_QOS_DEFAULT, DDS::DomainParticipantListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (participant.in ())) { cerr << "create_participant failed." << endl; return 1; } if (parse_args (argc, argv) != 0) return -1; if (delete_data) { using OpenDDS::FileSystemStorage::Directory; Directory::create (ACE_TEXT_ALWAYS_CHAR (dir))->remove (); dpf->delete_participant (participant); TheServiceParticipant->shutdown (); return 0; } MessageTypeSupport_var servant = new MessageTypeSupportImpl (); if (DDS::RETCODE_OK != servant->register_type(participant.in (), "")) { cerr << "register_type failed." << endl; exit (1); } CORBA::String_var type_name = servant->get_type_name (); DDS::TopicQos topic_qos; participant->get_default_topic_qos (topic_qos); DDS::Topic_var topic = participant->create_topic ("Movie Discussion List", type_name.in (), topic_qos, DDS::TopicListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (topic.in ())) { cerr << "create_topic failed." << endl; exit (1); } DDS::Publisher_var pub = participant->create_publisher (PUBLISHER_QOS_DEFAULT, DDS::PublisherListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (pub.in ())) { cerr << "create_publisher failed." << endl; exit (1); } // Configure DataWriter QoS policies. DDS::DataWriterQos dw_qos; pub->get_default_datawriter_qos (dw_qos); dw_qos.durability.kind = DDS::PERSISTENT_DURABILITY_QOS; dw_qos.durability_service.history_kind = ::DDS::KEEP_ALL_HISTORY_QOS; dw_qos.reliability.kind = ::DDS::RELIABLE_RELIABILITY_QOS; dw_qos.resource_limits.max_samples_per_instance = 1000; dw_qos.history.kind = ::DDS::KEEP_ALL_HISTORY_QOS; // ------------------------------------------------------- { DataWriterListenerImpl* listener = new DataWriterListenerImpl; DDS::DataWriterListener_var dwl = listener; // Create a DataWriter. // Upon exiting this scope, all unsent data should be // transferred to OpenDDS's data durability cache since the // run_test.pl script should not have started the subscriber // until it detects the "Done writing" log text. DDS::DataWriter_var dw = pub->create_datawriter (topic.in (), dw_qos, dwl.in (), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (dw.in ())) { cerr << "create_datawriter failed." << endl; exit (1); } // Only write samples if configured to do so. The expectation // is to otherwise retrieve the data from the PERSISTENT data // durability cache. if (do_write) { // Write samples. std::auto_ptr<Writer> writer (new Writer (dw.in ())); if (!writer->start () || !writer->end ()) { // Error logging performed in above method call. exit (1); } // Explicitly destroy the DataWriter. if (pub->delete_datawriter (dw.in ()) == ::DDS::RETCODE_PRECONDITION_NOT_MET) { cerr << "Unable to delete DataWriter" << endl; exit (1); } } else { int const max_attempts = 50; int attempts; for (attempts = 1; attempts != max_attempts && listener->publication_matched_.value () == false; ++attempts) { ACE_OS::sleep (5); } if (attempts == max_attempts) { cerr << "ERROR: subscriptions failed to match." << endl; exit (1); } // Wait for DataReader to finish. ::DDS::InstanceHandleSeq handles; for (attempts = 1; attempts != max_attempts; ++attempts) { dw->get_matched_subscriptions (handles); if (handles.length () == 0) break; else ACE_OS::sleep(1); } // The data durability cache should no longer contain samples // for this domain/topic/type. } } // ------------------------------------------------------- { // Write samples that will not be sent. Exercise // service_cleanup_delay. We can either do this through the // durability member or durability_service member in either of // TopicQos or DataWriterQos. This test arbitrarily uses the // DataWriterQos::durability_service member. // Cleanup data after this number of seconds. CORBA::Long const delay_seconds = 5; ::DDS::Duration_t & cleanup_delay = dw_qos.durability_service.service_cleanup_delay; cleanup_delay.sec = delay_seconds; cleanup_delay.nanosec = 0; // Create a dummy topic which will have no subscriptions. DDS::Topic_var dummy_topic = participant->create_topic ("Dummy Topic", type_name.in (), topic_qos, DDS::TopicListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); DDS::DataWriter_var dummy_dw = pub->create_datawriter (dummy_topic.in (), dw_qos, ::DDS::DataWriterListener::_nil (), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (dummy_dw.in ())) { cerr << "create_datawriter for dummy topic failed." << endl; exit (1); } // Write samples using multiple threads. std::auto_ptr<Writer> writer (new Writer (dummy_dw.in ())); // Explicitly destroy the DataWriter. if (pub->delete_datawriter (dummy_dw.in ()) == ::DDS::RETCODE_PRECONDITION_NOT_MET) { cerr << "Unable to delete DataWriter" << endl; exit (1); } // Allow durability cleanup to occur ACE_OS::sleep (delay_seconds + 3); } participant->delete_contained_entities(); dpf->delete_participant(participant.in ()); TheServiceParticipant->shutdown (); } catch (CORBA::Exception& e) { cerr << "PUB: Exception caught in main.cpp:" << endl << e << endl; exit (1); } catch (const std::runtime_error& err) { ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("ERROR: main() - %s\n"), err.what()), -1); } return 0; }
int ACE_TMAIN (int argc, ACE_TCHAR *argv[]){ int result = 0; try { DDS::DomainParticipantFactory_var dpf = TheParticipantFactoryWithArgs(argc, argv); DDS::DomainParticipant_var participant = dpf->create_participant(11, PARTICIPANT_QOS_DEFAULT, DDS::DomainParticipantListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (participant.in ())) { cerr << "create_participant failed." << endl; return 1; } MessageTypeSupportImpl* servant = new MessageTypeSupportImpl(); if (DDS::RETCODE_OK != servant->register_type(participant.in (), "")) { cerr << "register_type failed." << endl; exit(1); } CORBA::String_var type_name = servant->get_type_name (); DDS::TopicQos topic_qos; participant->get_default_topic_qos(topic_qos); DDS::Topic_var topic = participant->create_topic ("Movie Discussion List", type_name.in (), topic_qos, DDS::TopicListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (topic.in ())) { cerr << "create_topic failed." << endl; exit(1); } DDS::Publisher_var pub = participant->create_publisher(PUBLISHER_QOS_DEFAULT, DDS::PublisherListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (pub.in ())) { cerr << "create_publisher failed." << endl; exit(1); } // ---------------------------------------------- DDS::DataWriterQos dw_qos; // Good QoS. pub->get_default_datawriter_qos (dw_qos); dw_qos.resource_limits.max_samples_per_instance = MAX_SAMPLES_PER_INSTANCES; dw_qos.resource_limits.max_samples = MAX_SAMPLES; dw_qos.resource_limits.max_instances = MAX_INSTANCES; #ifndef OPENDDS_NO_OWNERSHIP_PROFILE dw_qos.history.kind = ::DDS::KEEP_ALL_HISTORY_QOS; dw_qos.history.depth = MAX_SAMPLES_PER_INSTANCES; #endif DDS::DataWriter_var dw = pub->create_datawriter (topic.in (), dw_qos, DDS::DataWriterListener::_nil (), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (dw.in ())) { cerr << "ERROR: create_datawriter failed." << endl; exit(1); } DDS::DataWriter_var dw2 = pub->create_datawriter (topic.in (), dw_qos, DDS::DataWriterListener::_nil (), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (dw2.in ())) { cerr << "ERROR: create_datawriter failed." << endl; exit(1); } { // Two threads use same datawriter to write different instances. std::auto_ptr<Writer> writer1 (new Writer (dw.in (), 99, SLEEP_DURATION)); std::auto_ptr<Writer> writer2 (new Writer (dw.in (), 100, SLEEP_DURATION)); std::auto_ptr<Writer> writer3 (new Writer (dw.in (), 101, SLEEP_DURATION)); std::auto_ptr<Writer> writer4 (new Writer (dw2.in (), 101, SLEEP_DURATION)); writer1->start (); writer2->start (); // ---------------------------------------------- // Wait for first writer threads to register with DataReaders. if (writer1->wait_for_registered () == false || writer2->wait_for_registered () == false) { cerr << "ERROR: first writers took too long to connect. " << endl; exit (1); } writer3->start (); if (writer3->wait_for_registered () == false) { cerr << "ERROR: writer 3 took too long to connect. " << endl; exit (1); } writer4->start (); if (writer4->wait_for_registered () == false) { cerr << "ERROR: writer 4 took too long to connect. " << endl; exit (1); } writer1->start_sending (); writer2->start_sending (); writer3->start_sending (); writer4->start_sending (); writer1->wait (); writer2->wait (); writer3->wait (); writer4->wait (); // Wait for datareader finish. while (1) { ::DDS::InstanceHandleSeq handles; dw->get_matched_subscriptions (handles); if (handles.length () == 0) break; else ACE_OS::sleep(1); } if (writer1->failed_registration() ) { cerr << "ERROR: unexpected failed registration for writer 1. " << endl; result = 1; } if (writer2->failed_registration() ) { cerr << "ERROR: unexpected failed registration for writer 2. " << endl; result = 1; } if (!writer3->failed_registration() ) { cerr << "ERROR: unexpected registration for writer 3. " << endl; result = 1; } if (writer4->failed_registration() ) { cerr << "ERROR: unexpected failed registration for writer 4. " << endl; result = 1; } } participant->delete_contained_entities(); dpf->delete_participant(participant.in ()); TheServiceParticipant->shutdown (); } catch (CORBA::Exception& e) { cerr << "PUB: Exception caught in main.cpp:" << endl << e << endl; exit(1); } return result; }
int ACE_TMAIN (int argc, ACE_TCHAR *argv[]){ try { DDS::DomainParticipantFactory_var dpf = TheParticipantFactoryWithArgs(argc, argv); DDS::DomainParticipant_var participant = dpf->create_participant(11, PARTICIPANT_QOS_DEFAULT, DDS::DomainParticipantListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (participant.in ())) { ACE_DEBUG((LM_DEBUG, "create_participant failed.\n")); return 1; } MessageTypeSupportImpl* servant = new MessageTypeSupportImpl(); if (DDS::RETCODE_OK != servant->register_type(participant.in (), "")) { ACE_DEBUG((LM_DEBUG, "register_type failed.\n")); exit(1); } CORBA::String_var type_name = servant->get_type_name (); DDS::TopicQos topic_qos; participant->get_default_topic_qos(topic_qos); DDS::Topic_var topic = participant->create_topic ("Movie Discussion List", type_name.in (), topic_qos, DDS::TopicListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (topic.in ())) { ACE_DEBUG((LM_DEBUG, "create_topic failed.\n")); exit(1); } DDS::Publisher_var pub = participant->create_publisher(PUBLISHER_QOS_DEFAULT, DDS::PublisherListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (pub.in ())) { ACE_DEBUG((LM_DEBUG, "create_publisher failed.\n")); exit(1); } DDS::DataWriterQos dw_qos; pub->get_default_datawriter_qos (dw_qos); dw_qos.deadline.period.sec = 4; dw_qos.deadline.period.nanosec = 0; // Create DataWriter with 4 second deadline period which // should be compatible with first DataReader which has 5 // seconds deadline period and not with second DataReader // which has 3 seconds deadline period. DDS::DataWriter_var dw = pub->create_datawriter(topic, dw_qos, 0, OpenDDS::DCPS::DEFAULT_STATUS_MASK); int const max_attempts = 20000; int attempts = 1; { // Wait for both first DataReader connect and write messages. std::auto_ptr<Writer> writer (new Writer (dw.in ())); while (attempts != max_attempts) { ::DDS::InstanceHandleSeq handles; dw->get_matched_subscriptions(handles); if (handles.length() == 1) break; else ACE_OS::sleep(1); ++attempts; } if (attempts == max_attempts) { ACE_DEBUG((LM_DEBUG, "ERROR: subscriptions failed to match.\n")); exit (1); } writer->start (); writer->end (); ACE_DEBUG((LM_DEBUG, "Writer changing deadline to incompatible value\n")); // Now set DataWriter deadline to be 6 seconds which is not // compatible with the existing DataReader. This QoS change // should be applied and the association broken. dw_qos.deadline.period.sec = 6; if (dw->set_qos (dw_qos) != ::DDS::RETCODE_OK) { ACE_DEBUG((LM_DEBUG, "ERROR: DataWriter could not change deadline period which " "should break DataReader associations\n")); exit (1); } else { DDS::WaitSet_var ws = new DDS::WaitSet; DDS::StatusCondition_var sc = dw->get_statuscondition(); sc->set_enabled_statuses(DDS::PUBLICATION_MATCHED_STATUS); ws->attach_condition(sc); DDS::PublicationMatchedStatus matched; DDS::ConditionSeq active; const DDS::Duration_t timeout = {5, 0}; // seconds while (dw->get_publication_matched_status(matched) == DDS::RETCODE_OK && matched.current_count) { if (ws->wait(active, timeout) == DDS::RETCODE_TIMEOUT) { break; } } ws->detach_condition(sc); if (matched.current_count != 0) { ACE_DEBUG((LM_DEBUG, "ERROR: DataWriter changed deadline period which should " "break association with all existing DataReaders, but did not\n")); exit(1); } } // We know the reader has been disassociated, but the reader itself may // not have been notified yet. Introducing delay here to let the reader // sync up with the disassociated state before re-associating. // Wait for reader to finish unmatching. FILE* fp = ACE_OS::fopen (synch_fname, ACE_TEXT("r")); int i = 0; while (fp == 0 && i < 15) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT("(%P|%t) waiting reader to unmatch...\n"))); ACE_OS::sleep (1); ++i; fp = ACE_OS::fopen (synch_fname, ACE_TEXT("r")); } if (fp != 0) ACE_OS::fclose (fp); ACE_DEBUG((LM_DEBUG, "Writer restoring deadline to compatible value\n")); // change it back dw_qos.deadline.period.sec = 5; if (dw->set_qos (dw_qos) != ::DDS::RETCODE_OK) { ACE_DEBUG((LM_DEBUG, "ERROR: DataWriter could not change deadline period which " "should restore DataReader associations\n")); exit (1); } } { // Wait for both second DataReader connect which changed deadline period // from 3 seconds to 5 seconds. std::auto_ptr<Writer> writer (new Writer (dw.in ())); attempts = 1; while (attempts != max_attempts) { ::DDS::InstanceHandleSeq handles; dw->get_matched_subscriptions(handles); if (handles.length() == 2) break; else ACE_OS::sleep(1); ++attempts; } if (attempts == max_attempts) { ACE_DEBUG((LM_DEBUG, "ERROR: subscriptions failed to match.\n")); exit(1); } writer->start (); writer->end (); } { // Wait for subscriber exit. attempts = 1; while (attempts != max_attempts) { ::DDS::InstanceHandleSeq handles; dw->get_matched_subscriptions(handles); if (handles.length() == 0) break; else ACE_OS::sleep(1); ++ attempts; } if (attempts == max_attempts) { ACE_DEBUG((LM_DEBUG, "ERROR: failed to wait for DataReader exit.\n")); exit (1); } } participant->delete_contained_entities(); dpf->delete_participant(participant.in ()); } catch (CORBA::Exception& e) { cerr << "PUB: Exception caught in main.cpp:" << endl << e << endl; exit(1); } TheServiceParticipant->shutdown (); return 0; }