From fe33b04fff43eb84dc7d2587676141203e432c64 Mon Sep 17 00:00:00 2001 From: JesusPoderoso Date: Thu, 14 Mar 2024 16:31:02 +0100 Subject: [PATCH] Refs #20543: Apply rev suggestions (3) Signed-off-by: JesusPoderoso --- examples/cpp/hello_world/CLIParser.hpp | 24 ++- examples/cpp/hello_world/CMakeLists.txt | 2 +- examples/cpp/hello_world/HelloWorld_main.cpp | 177 ++++++++++++++---- examples/cpp/hello_world/Publisher.cpp | 55 +----- examples/cpp/hello_world/Publisher.hpp | 6 +- examples/cpp/hello_world/Subscriber.cpp | 39 +--- examples/cpp/hello_world/Subscriber.hpp | 8 +- .../cpp/hello_world/SubscriberWaitset.cpp | 131 +++++-------- .../cpp/hello_world/SubscriberWaitset.hpp | 8 +- 9 files changed, 232 insertions(+), 218 deletions(-) diff --git a/examples/cpp/hello_world/CLIParser.hpp b/examples/cpp/hello_world/CLIParser.hpp index 231cd14b86b..039e0f35207 100644 --- a/examples/cpp/hello_world/CLIParser.hpp +++ b/examples/cpp/hello_world/CLIParser.hpp @@ -28,6 +28,13 @@ class CLIParser CLIParser() = delete; + enum entity_kind + { + PUBLISHER, + SUBSCRIBER, + UNDEFINED + }; + struct publisher_config { uint16_t samples = 0; @@ -40,7 +47,7 @@ class CLIParser struct hello_world_config { - std::string entity = ""; + entity_kind entity = entity_kind::UNDEFINED; publisher_config pub_config; subscriber_config sub_config; }; @@ -71,9 +78,13 @@ class CLIParser std::string first_argument = argv[1]; - if (first_argument == "publisher" || first_argument == "subscriber") + if (first_argument == "publisher" ) { - config.entity = first_argument; + config.entity = entity_kind::PUBLISHER; + } + else if ( first_argument == "subscriber") + { + config.entity = entity_kind::SUBSCRIBER; } else { @@ -102,11 +113,11 @@ class CLIParser try { uint16_t samples = static_cast(std::stoi(argv[++i])); - if (config.entity == "publisher") + if (config.entity == entity_kind::PUBLISHER) { config.pub_config.samples = samples; } - else if (config.entity == "subscriber") + else if (config.entity == entity_kind::SUBSCRIBER) { config.sub_config.samples = samples; } @@ -136,7 +147,7 @@ class CLIParser } else if (arg == "-w" || arg == "--waitset") { - if (config.entity == "subscriber") + if (config.entity == entity_kind::SUBSCRIBER) { config.sub_config.use_waitset = true; } @@ -155,6 +166,7 @@ class CLIParser return config; } + }; #endif // _FASTDDS_HELLO_WORLD_CLI_PARSER_HPP_ diff --git a/examples/cpp/hello_world/CMakeLists.txt b/examples/cpp/hello_world/CMakeLists.txt index 33b21dad5a1..34588413662 100644 --- a/examples/cpp/hello_world/CMakeLists.txt +++ b/examples/cpp/hello_world/CMakeLists.txt @@ -46,7 +46,7 @@ target_compile_definitions(hello_world PRIVATE ) target_link_libraries(hello_world fastdds fastcdr) install(TARGETS hello_world - RUNTIME DESTINATION examples/cpp/hello_world/${BIN_INSTALL_DIR}) + RUNTIME DESTINATION fastdds/examples/cpp/hello_world/${BIN_INSTALL_DIR}) # Copy the XML files over to the build directory file(GLOB_RECURSE XML_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.xml) diff --git a/examples/cpp/hello_world/HelloWorld_main.cpp b/examples/cpp/hello_world/HelloWorld_main.cpp index 46f69b0e0bb..d70ce6d4a52 100644 --- a/examples/cpp/hello_world/HelloWorld_main.cpp +++ b/examples/cpp/hello_world/HelloWorld_main.cpp @@ -17,7 +17,9 @@ * */ +#include #include +#include #include #include @@ -29,61 +31,172 @@ using eprosima::fastdds::dds::Log; +std::function signal_handler; + int main( int argc, char** argv) { auto ret = EXIT_SUCCESS; + HelloWorldPublisher* publisher = nullptr; + HelloWorldSubscriber* subscriber = nullptr; + HelloWorldSubscriberWaitset* subscriber_waitset = nullptr; + std::thread* thread = nullptr; const std::string topic_name = "hello_world_topic"; + std::string entity_name = "undefined"; + uint16_t samples = 0; CLIParser::hello_world_config config = CLIParser::parse_cli_options(argc, argv); - if (config.entity == "publisher") + switch (config.entity) { - try - { - HelloWorldPublisher hello_world_publisher(config.pub_config, topic_name); - hello_world_publisher.run(); - } - catch (const std::runtime_error& e) - { - EPROSIMA_LOG_ERROR(PUBLISHER, e.what()); - ret = EXIT_FAILURE; - } - } - else if (config.entity == "subscriber") - { - if (config.sub_config.use_waitset) - { + case CLIParser::entity_kind::PUBLISHER: + entity_name = "Publisher"; + samples = config.pub_config.samples; try { - HelloWorldSubscriberWaitset hello_world_subscriber_waitset(config.sub_config, topic_name); - hello_world_subscriber_waitset.run(); + publisher = new HelloWorldPublisher(config.pub_config, topic_name); + thread = new std::thread(&HelloWorldPublisher::run, publisher); } catch (const std::runtime_error& e) { - EPROSIMA_LOG_ERROR(SUBSCRIBER, e.what()); + EPROSIMA_LOG_ERROR(PUBLISHER, e.what()); ret = EXIT_FAILURE; } - } - else - { - try + break; + case CLIParser::entity_kind::SUBSCRIBER: + samples = config.sub_config.samples; + if (config.sub_config.use_waitset) { - HelloWorldSubscriber hello_world_subscriber(config.sub_config, topic_name); - hello_world_subscriber.run(); + entity_name = "Waitset Subscriber"; + try + { + subscriber_waitset = new HelloWorldSubscriberWaitset(config.sub_config, topic_name); + thread = new std::thread(&HelloWorldSubscriberWaitset::run, subscriber_waitset); + } + catch (const std::runtime_error& e) + { + EPROSIMA_LOG_ERROR(SUBSCRIBER, e.what()); + ret = EXIT_FAILURE; + } } - catch (const std::runtime_error& e) + else { - EPROSIMA_LOG_ERROR(SUBSCRIBER_WAITSET, e.what()); - ret = EXIT_FAILURE; + entity_name = "Subscriber"; + try + { + subscriber = new HelloWorldSubscriber(config.sub_config, topic_name); + thread = new std::thread(&HelloWorldSubscriber::run, subscriber); + } + catch (const std::runtime_error& e) + { + EPROSIMA_LOG_ERROR(SUBSCRIBER_WAITSET, e.what()); + ret = EXIT_FAILURE; + } } - } + break; + default: + EPROSIMA_LOG_ERROR(CLI_PARSER, "unknown entity"); + CLIParser::print_help(EXIT_FAILURE); + break; + } + + if (samples == 0) + { + std::cout << entity_name << " running. Please press Ctrl+C to stop the " + << entity_name << " at any time." << std::endl; } - // example should never reach this point else { - EPROSIMA_LOG_ERROR(CLI_PARSER, "unknown entity " + config.entity); - CLIParser::print_help(EXIT_FAILURE); + switch (config.entity) + { + case CLIParser::entity_kind::PUBLISHER: + std::cout << entity_name << " running " << samples << " samples. Please press Ctrl+C to stop the " + << entity_name << " at any time." << std::endl; + break; + case CLIParser::entity_kind::SUBSCRIBER: + default: + std::cout << entity_name << " running until " << samples << " samples have been received. Please press " + << "Ctrl+C to stop the " << entity_name << " at any time." << std::endl; + break; + } + } + + signal_handler = [&](std::string signal) + { + std::cout << "\n" << signal << " received, stopping " << entity_name << " execution." << std::endl; + switch (config.entity) + { + case CLIParser::entity_kind::PUBLISHER: + if (nullptr != publisher) + { + publisher->stop(); + } + break; + case CLIParser::entity_kind::SUBSCRIBER: + default: + if (config.sub_config.use_waitset) + { + if (nullptr != subscriber_waitset) + { + subscriber_waitset->stop(); + } + } + else + { + if (nullptr != subscriber) + { + subscriber->stop(); + } + } + break; + } + }; + signal(SIGINT, [](int /*signum*/) + { + signal_handler("SIGINT"); + }); + signal(SIGTERM, [](int /*signum*/) + { + signal_handler("SIGTERM"); + }); +#ifndef _WIN32 + signal(SIGQUIT, [](int /*signum*/) + { + signal_handler("SIGQUIT"); + }); + signal(SIGHUP, [](int /*signum*/) + { + signal_handler("SIGHUP"); + }); +#endif // _WIN32 + + thread->join(); + delete thread; + switch (config.entity) + { + case CLIParser::entity_kind::PUBLISHER: + if (nullptr != publisher) + { + delete publisher; + } + break; + case CLIParser::entity_kind::SUBSCRIBER: + default: + if (config.sub_config.use_waitset) + { + if (nullptr != subscriber_waitset) + { + delete subscriber_waitset; + } + } + else + { + if (nullptr != subscriber) + { + delete subscriber; + } + } + break; } Log::Reset(); diff --git a/examples/cpp/hello_world/Publisher.cpp b/examples/cpp/hello_world/Publisher.cpp index 2f5530220af..8dd8f6b8d0c 100644 --- a/examples/cpp/hello_world/Publisher.cpp +++ b/examples/cpp/hello_world/Publisher.cpp @@ -32,9 +32,6 @@ using namespace eprosima::fastdds::dds; -std::atomic HelloWorldPublisher::stop_(false); -std::condition_variable HelloWorldPublisher::matched_cv_; - HelloWorldPublisher::HelloWorldPublisher( const CLIParser::publisher_config& config, const std::string& topic_name) @@ -43,13 +40,14 @@ HelloWorldPublisher::HelloWorldPublisher( , topic_(nullptr) , writer_(nullptr) , type_(new HelloWorldPubSubType()) + , stop_(false) , matched_(0) , samples_ (config.samples) { // Set up the data type with initial values hello_.index(0); hello_.message("Hello world"); - + // Create the participant auto factory = DomainParticipantFactory::get_instance(); participant_ = factory->create_participant_with_default_profile(nullptr, StatusMask::none()); @@ -125,50 +123,15 @@ void HelloWorldPublisher::on_publication_matched( void HelloWorldPublisher::run() { - std::thread pub_thread([&] - { - while (!is_stopped() && (samples_ == 0 || hello_.index() < samples_)) - { - if (publish()) - { - std::cout << "Message: '" << hello_.message() << "' with index: '" << hello_.index() - << "' SENT" << std::endl; - } - std::this_thread::sleep_for(std::chrono::milliseconds(period_ms_)); - } - }); - if (samples_ == 0) + while (!is_stopped() && (samples_ == 0 || hello_.index() < samples_)) { - std::cout << "Publisher running. Please press Ctrl+C to stop the Publisher at any time." << std::endl; + if (publish()) + { + std::cout << "Message: '" << hello_.message() << "' with index: '" << hello_.index() + << "' SENT" << std::endl; + } + std::this_thread::sleep_for(std::chrono::milliseconds(period_ms_)); } - else - { - std::cout << "Publisher running " << samples_ << - " samples. Please press Ctrl+C to stop the Publisher at any time." << std::endl; - } - signal(SIGINT, [](int /*signum*/) - { - std::cout << "\nSIGINT received, stopping Publisher execution." << std::endl; - HelloWorldPublisher::stop(); - }); - signal(SIGTERM, [](int /*signum*/) - { - std::cout << "\nSIGTERM received, stopping Publisher execution." << std::endl; - HelloWorldPublisher::stop(); - }); -#ifndef _WIN32 - signal(SIGQUIT, [](int /*signum*/) - { - std::cout << "\nSIGQUIT received, stopping Publisher execution." << std::endl; - HelloWorldPublisher::stop(); - }); - signal(SIGHUP, [](int /*signum*/) - { - std::cout << "\nSIGHUP received, stopping Publisher execution." << std::endl; - HelloWorldPublisher::stop(); - }); -#endif // _WIN32 - pub_thread.join(); } bool HelloWorldPublisher::publish() diff --git a/examples/cpp/hello_world/Publisher.hpp b/examples/cpp/hello_world/Publisher.hpp index 090bd7952b4..d19ed7c52d8 100644 --- a/examples/cpp/hello_world/Publisher.hpp +++ b/examples/cpp/hello_world/Publisher.hpp @@ -50,7 +50,7 @@ class HelloWorldPublisher : public DataWriterListener void run(); //! Trigger the end of execution - static void stop(); + void stop(); private: @@ -72,7 +72,7 @@ class HelloWorldPublisher : public DataWriterListener TypeSupport type_; - static std::atomic stop_; + std::atomic stop_; int16_t matched_; @@ -80,7 +80,7 @@ class HelloWorldPublisher : public DataWriterListener std::mutex mutex_; - static std::condition_variable matched_cv_; + std::condition_variable matched_cv_; const uint32_t period_ms_ = 100; // in ms }; diff --git a/examples/cpp/hello_world/Subscriber.cpp b/examples/cpp/hello_world/Subscriber.cpp index b02a4f1d749..b9dc3d8a869 100644 --- a/examples/cpp/hello_world/Subscriber.cpp +++ b/examples/cpp/hello_world/Subscriber.cpp @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -34,9 +33,6 @@ using namespace eprosima::fastdds::dds; -std::atomic HelloWorldSubscriber::stop_(false); -std::condition_variable HelloWorldSubscriber::terminate_cv_; - HelloWorldSubscriber::HelloWorldSubscriber( const CLIParser::subscriber_config& config, const std::string& topic_name) @@ -47,6 +43,7 @@ HelloWorldSubscriber::HelloWorldSubscriber( , type_(new HelloWorldPubSubType()) , samples_ (config.samples) , received_samples_(0) + , stop_(false) { // Create the participant auto factory = DomainParticipantFactory::get_instance(); @@ -140,40 +137,8 @@ void HelloWorldSubscriber::on_data_available( void HelloWorldSubscriber::run() { - if (samples_ == 0) - { - std::cout << "Subscriber running. Please press Ctrl+C to stop the Subscriber at any time." << std::endl; - } - else - { - std::cout << "Subscriber running until " << samples_ << - " samples have been received. Please press Ctrl+C to stop the Subscriber at any time." << std::endl; - } - - signal(SIGINT, [](int /*signum*/) - { - std::cout << "\nSIGINT received, stopping Subscriber execution." << std::endl; - HelloWorldSubscriber::stop(); - }); - signal(SIGTERM, [](int /*signum*/) - { - std::cout << "\nSIGTERM received, stopping Subscriber execution." << std::endl; - HelloWorldSubscriber::stop(); - }); -#ifndef _WIN32 - signal(SIGQUIT, [](int /*signum*/) - { - std::cout << "\nSIGQUIT received, stopping Subscriber execution." << std::endl; - HelloWorldSubscriber::stop(); - }); - signal(SIGHUP, [](int /*signum*/) - { - std::cout << "\nSIGHUP received, stopping Subscriber execution." << std::endl; - HelloWorldSubscriber::stop(); - }); -#endif // _WIN32 std::unique_lock lck(terminate_cv_mtx_); - terminate_cv_.wait(lck, [] + terminate_cv_.wait(lck, [&] { return is_stopped(); }); diff --git a/examples/cpp/hello_world/Subscriber.hpp b/examples/cpp/hello_world/Subscriber.hpp index 2ffdba85820..14449b72f76 100644 --- a/examples/cpp/hello_world/Subscriber.hpp +++ b/examples/cpp/hello_world/Subscriber.hpp @@ -54,12 +54,12 @@ class HelloWorldSubscriber : public DataReaderListener void run(); //! Trigger the end of execution - static void stop(); + void stop(); private: //! Return the current state of execution - static bool is_stopped(); + bool is_stopped(); HelloWorld hello_; @@ -77,11 +77,11 @@ class HelloWorldSubscriber : public DataReaderListener uint16_t received_samples_; - static std::atomic stop_; + std::atomic stop_; mutable std::mutex terminate_cv_mtx_; - static std::condition_variable terminate_cv_; + std::condition_variable terminate_cv_; }; #endif /* _FASTDDS_HELLO_WORLD_SUBSCRIBER_HPP_ */ diff --git a/examples/cpp/hello_world/SubscriberWaitset.cpp b/examples/cpp/hello_world/SubscriberWaitset.cpp index e0ae1bba4a1..9eedb3d0988 100644 --- a/examples/cpp/hello_world/SubscriberWaitset.cpp +++ b/examples/cpp/hello_world/SubscriberWaitset.cpp @@ -36,9 +36,6 @@ using namespace eprosima::fastdds::dds; -std::atomic HelloWorldSubscriberWaitset::stop_(false); -GuardCondition HelloWorldSubscriberWaitset::terminate_condition_; - HelloWorldSubscriberWaitset::HelloWorldSubscriberWaitset( const CLIParser::subscriber_config& config, const std::string& topic_name) @@ -49,6 +46,7 @@ HelloWorldSubscriberWaitset::HelloWorldSubscriberWaitset( , type_(new HelloWorldPubSubType()) , samples_ (config.samples) , received_samples_(0) + , stop_(false) { // Create the participant auto factory = DomainParticipantFactory::get_instance(); @@ -107,100 +105,63 @@ HelloWorldSubscriberWaitset::~HelloWorldSubscriberWaitset() void HelloWorldSubscriberWaitset::run() { - std::thread sub_thread([&] + while (!is_stopped()) + { + ConditionSeq triggered_conditions; + ReturnCode_t ret_code = wait_set_.wait(triggered_conditions, eprosima::fastrtps::c_TimeInfinite); + if (ReturnCode_t::RETCODE_OK != ret_code) + { + EPROSIMA_LOG_ERROR(SUBSCRIBER_WAITSET, "Error waiting for conditions"); + continue; + } + for (Condition* cond : triggered_conditions) + { + StatusCondition* status_cond = dynamic_cast(cond); + if (nullptr != status_cond) { - while (!is_stopped()) + Entity* entity = status_cond->get_entity(); + StatusMask changed_statuses = entity->get_status_changes(); + if (changed_statuses.is_active(StatusMask::subscription_matched())) { - ConditionSeq triggered_conditions; - ReturnCode_t ret_code = wait_set_.wait(triggered_conditions, eprosima::fastrtps::c_TimeInfinite); - if (ReturnCode_t::RETCODE_OK != ret_code) + SubscriptionMatchedStatus status_; + reader_->get_subscription_matched_status(status_); + if (status_.current_count_change == 1) { - EPROSIMA_LOG_ERROR(SUBSCRIBER_WAITSET, "Error waiting for conditions"); - continue; + std::cout << "Waitset Subscriber matched." << std::endl; } - for (Condition* cond : triggered_conditions) + else if (status_.current_count_change == -1) { - StatusCondition* status_cond = dynamic_cast(cond); - if (nullptr != status_cond) + std::cout << "Waitset Subscriber unmatched." << std::endl; + } + else + { + std::cout << status_.current_count_change << + " is not a valid value for SubscriptionMatchedStatus current count change" << + std::endl; + } + } + if (changed_statuses.is_active(StatusMask::data_available())) + { + SampleInfo info; + while ((!is_stopped()) && + (ReturnCode_t::RETCODE_OK == reader_->take_next_sample(&hello_, &info))) + { + if ((info.instance_state == ALIVE_INSTANCE_STATE) && info.valid_data) { - Entity* entity = status_cond->get_entity(); - StatusMask changed_statuses = entity->get_status_changes(); - if (changed_statuses.is_active(StatusMask::subscription_matched())) - { - SubscriptionMatchedStatus status_; - reader_->get_subscription_matched_status(status_); - if (status_.current_count_change == 1) - { - std::cout << "Waitset Subscriber matched." << std::endl; - } - else if (status_.current_count_change == -1) - { - std::cout << "Waitset Subscriber unmatched." << std::endl; - } - else - { - std::cout << status_.current_count_change << - " is not a valid value for SubscriptionMatchedStatus current count change" << - std::endl; - } - } - if (changed_statuses.is_active(StatusMask::data_available())) + received_samples_++; + // Print Hello world message data + std::cout << "Message: '" << hello_.message() << "' with index: '" + << hello_.index() << "' RECEIVED" << std::endl; + if (samples_ > 0 && (received_samples_ >= samples_)) { - SampleInfo info; - while ((!is_stopped()) && - (ReturnCode_t::RETCODE_OK == reader_->take_next_sample(&hello_, &info))) - { - if ((info.instance_state == ALIVE_INSTANCE_STATE) && info.valid_data) - { - received_samples_++; - // Print Hello world message data - std::cout << "Message: '" << hello_.message() << "' with index: '" - << hello_.index() << "' RECEIVED" << std::endl; - if (samples_ > 0 && (received_samples_ >= samples_)) - { - stop(); - } - } - } + stop(); } } } } - }); - - if (samples_ == 0) - { - std::cout << "Waitset Subscriber running. Please press Ctrl+C to stop the Waitset Subscriber at any time." - << std::endl; - } - else - { - std::cout << "Waitset Subscriber running until " << samples_ << - " samples have been received. Please press Ctrl+C to stop the Waitset Subscriber at any time." << std::endl; + } + } } - signal(SIGINT, [](int /*signum*/) - { - std::cout << "\nSIGINT received, stopping Waitset Subscriber execution." << std::endl; - HelloWorldSubscriberWaitset::stop(); - }); - signal(SIGTERM, [](int /*signum*/) - { - std::cout << "\nSIGTERM received, stopping Waitset Subscriber execution." << std::endl; - HelloWorldSubscriberWaitset::stop(); - }); -#ifndef _WIN32 - signal(SIGQUIT, [](int /*signum*/) - { - std::cout << "\nSIGQUIT received, stopping Waitset Subscriber execution." << std::endl; - HelloWorldSubscriberWaitset::stop(); - }); - signal(SIGHUP, [](int /*signum*/) - { - std::cout << "\nSIGHUP received, stopping Waitset Subscriber execution." << std::endl; - HelloWorldSubscriberWaitset::stop(); - }); -#endif // _WIN32 - sub_thread.join(); } bool HelloWorldSubscriberWaitset::is_stopped() diff --git a/examples/cpp/hello_world/SubscriberWaitset.hpp b/examples/cpp/hello_world/SubscriberWaitset.hpp index 87b22ea944a..b187b13d5fa 100644 --- a/examples/cpp/hello_world/SubscriberWaitset.hpp +++ b/examples/cpp/hello_world/SubscriberWaitset.hpp @@ -47,12 +47,12 @@ class HelloWorldSubscriberWaitset void run(); //! Trigger the end of execution - static void stop(); + void stop(); private: //! Return the current state of execution - static bool is_stopped(); + bool is_stopped(); HelloWorld hello_; @@ -72,9 +72,9 @@ class HelloWorldSubscriberWaitset uint16_t received_samples_; - static std::atomic stop_; + std::atomic stop_; - static GuardCondition terminate_condition_; + GuardCondition terminate_condition_; }; #endif /* _FASTDDS_HELLO_WORLD_SUBSCRIBER_WAITSET_HPP_ */