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; }
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 { ACE_DEBUG ((LM_DEBUG, "(%P|%t) publisher main\n")); DDS::DomainParticipantFactory_var dpf = TheParticipantFactoryWithArgs(argc, argv); if (parse_args (argc, argv) == -1) { return -1; } DDS::DomainParticipantQos partQos; dpf->get_default_participant_qos(partQos); // set up user data in DP qos CORBA::ULong part_user_data_len = static_cast<CORBA::ULong>(ACE_OS::strlen (PART_USER_DATA)); partQos.user_data.value.length (part_user_data_len); partQos.user_data.value.replace (part_user_data_len, part_user_data_len, reinterpret_cast<CORBA::Octet*>(PART_USER_DATA)); DDS::DomainParticipant_var participant = dpf->create_participant(411, partQos, DDS::DomainParticipantListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (participant.in ())) { cerr << "publisher: create_participant failed." << endl; return 1; } ::Messenger::MessageTypeSupport_var ts = new ::Messenger::MessageTypeSupportImpl(); if (DDS::RETCODE_OK != ts->register_type(participant.in (), "Messenger")) { cerr << "publisher: register_type failed." << endl; exit(1); } CORBA::String_var type_name = ts->get_type_name (); DDS::TopicQos topic_qos; participant->get_default_topic_qos(topic_qos); // set up topic data in topic qos CORBA::ULong topic_data_len = static_cast<CORBA::ULong>(ACE_OS::strlen (TOPIC_DATA)); topic_qos.topic_data.value.length (topic_data_len); topic_qos.topic_data.value.replace (topic_data_len, topic_data_len, reinterpret_cast<CORBA::Octet*>(TOPIC_DATA)); 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 << "publisher: create_topic failed." << endl; exit(1); } DDS::PublisherQos pub_qos; participant->get_default_publisher_qos (pub_qos); // set up group data in group qos CORBA::ULong group_data_len = static_cast<CORBA::ULong> (ACE_OS::strlen (GROUP_DATA)); pub_qos.group_data.value.length (group_data_len); pub_qos.group_data.value.replace (group_data_len, group_data_len, reinterpret_cast<CORBA::Octet*>(GROUP_DATA)); DDS::Publisher_var pub = participant->create_publisher(pub_qos, DDS::PublisherListener::_nil(), ::OpenDDS::DCPS::DEFAULT_STATUS_MASK); if (CORBA::is_nil (pub.in ())) { cerr << "publisher: create_publisher failed." << endl; exit(1); } // Create the datawriter DDS::DataWriterQos dw_qos; pub->get_default_datawriter_qos (dw_qos); dw_qos.durability.kind = DDS::TRANSIENT_LOCAL_DURABILITY_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; // set up user data in DW qos CORBA::ULong dw_user_data_len = static_cast<CORBA::ULong>(ACE_OS::strlen (DW_USER_DATA)); dw_qos.user_data.value.length (dw_user_data_len); dw_qos.user_data.value.replace (dw_user_data_len, dw_user_data_len, reinterpret_cast<CORBA::Octet*>(DW_USER_DATA)); 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 << "publisher: create_datawriter failed." << endl; exit(1); } // wait for Monitor 1 done 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 monitor1 done ...\n"))); ACE_OS::sleep (1); ++ i; fp = ACE_OS::fopen (synch_fname, ACE_TEXT("r")); } if (fp != 0) ACE_OS::fclose (fp); // Now change the changeable qos. The second monitor should get the updated qos from BIT. part_user_data_len = static_cast<CORBA::ULong>(ACE_OS::strlen (UPDATED_PART_USER_DATA)); partQos.user_data.value.length (part_user_data_len); partQos.user_data.value.replace (part_user_data_len, part_user_data_len, reinterpret_cast<CORBA::Octet*>(UPDATED_PART_USER_DATA)); participant->set_qos (partQos); dw_user_data_len = static_cast<CORBA::ULong>(ACE_OS::strlen (UPDATED_DW_USER_DATA)); dw_qos.user_data.value.length (dw_user_data_len); dw_qos.user_data.value.replace (dw_user_data_len, dw_user_data_len, reinterpret_cast<CORBA::Octet*>(UPDATED_DW_USER_DATA)); dw->set_qos (dw_qos); group_data_len = static_cast<CORBA::ULong> (ACE_OS::strlen (UPDATED_GROUP_DATA)); pub_qos.group_data.value.length (group_data_len); pub_qos.group_data.value.replace (group_data_len, group_data_len, reinterpret_cast<CORBA::Octet*>(UPDATED_GROUP_DATA)); pub->set_qos (pub_qos); topic_data_len = static_cast<CORBA::ULong>(ACE_OS::strlen (UPDATED_TOPIC_DATA)); topic_qos.topic_data.value.length (topic_data_len); topic_qos.topic_data.value.replace (topic_data_len, topic_data_len, reinterpret_cast<CORBA::Octet*>(UPDATED_TOPIC_DATA)); topic->set_qos (topic_qos); Writer* writer = new Writer(dw.in()); writer->start (); while ( !writer->is_finished()) { ACE_Time_Value small_time(0,250000); ACE_OS::sleep (small_time); } // Cleanup writer->end (); delete writer; participant->delete_contained_entities(); dpf->delete_participant(participant.in ()); TheServiceParticipant->shutdown (); } catch (CORBA::Exception& e) { cerr << "publisher: PUB: Exception caught in main.cpp:" << endl << e << endl; exit(1); } return 0; }