diff --git a/documentation/vsomeipUserGuide.md b/documentation/vsomeipUserGuide.md index e2a3cc0df..10ca0f29d 100644 --- a/documentation/vsomeipUserGuide.md +++ b/documentation/vsomeipUserGuide.md @@ -497,11 +497,6 @@ Configuration file element explanation: considered to be blocked (and an additional thread is used to execute pending callbacks if max_dispatchers is configured greater than 0). The default value if not specified is 100ms. - * 'max_detached_thread_wait_time' (optional) - - The maximum time in seconds that an application will wait for a detached dispatcher thread - to finish executing. The default value if not specified is 5s. - * 'threads' (optional) The number of internal threads to process messages and events within an application. diff --git a/implementation/configuration/include/application_configuration.hpp b/implementation/configuration/include/application_configuration.hpp index 81ab7aa6a..e19d3df3a 100644 --- a/implementation/configuration/include/application_configuration.hpp +++ b/implementation/configuration/include/application_configuration.hpp @@ -22,7 +22,6 @@ struct application_configuration { client_t client_; std::size_t max_dispatchers_; std::size_t max_dispatch_time_; - std::size_t max_detach_thread_wait_time_; std::size_t thread_count_; std::size_t request_debouncing_; std::map > plugins_; diff --git a/implementation/configuration/include/configuration.hpp b/implementation/configuration/include/configuration.hpp index 15fbc9c7d..f129f37f6 100644 --- a/implementation/configuration/include/configuration.hpp +++ b/implementation/configuration/include/configuration.hpp @@ -141,7 +141,6 @@ class configuration { virtual std::size_t get_max_dispatchers(const std::string &_name) const = 0; virtual std::size_t get_max_dispatch_time(const std::string &_name) const = 0; - virtual std::size_t get_max_detached_thread_wait_time(const std::string& _name) const = 0; virtual std::size_t get_io_thread_count(const std::string &_name) const = 0; virtual int get_io_thread_nice_level(const std::string &_name) const = 0; virtual std::size_t get_request_debouncing(const std::string &_name) const = 0; diff --git a/implementation/configuration/include/configuration_impl.hpp b/implementation/configuration/include/configuration_impl.hpp index d9ed9cbc0..85b0eb49e 100644 --- a/implementation/configuration/include/configuration_impl.hpp +++ b/implementation/configuration/include/configuration_impl.hpp @@ -140,7 +140,6 @@ class configuration_impl: VSOMEIP_EXPORT std::size_t get_max_dispatchers(const std::string &_name) const; VSOMEIP_EXPORT std::size_t get_max_dispatch_time(const std::string &_name) const; - VSOMEIP_EXPORT std::size_t get_max_detached_thread_wait_time(const std::string& _name) const; VSOMEIP_EXPORT std::size_t get_io_thread_count(const std::string &_name) const; VSOMEIP_EXPORT int get_io_thread_nice_level(const std::string &_name) const; VSOMEIP_EXPORT std::size_t get_request_debouncing(const std::string &_name) const; diff --git a/implementation/configuration/include/internal.hpp.in b/implementation/configuration/include/internal.hpp.in index 7a188fef4..406925083 100644 --- a/implementation/configuration/include/internal.hpp.in +++ b/implementation/configuration/include/internal.hpp.in @@ -102,8 +102,6 @@ #define VSOMEIP_MAX_DISPATCHERS 10 #define VSOMEIP_MAX_DISPATCH_TIME 100 -#define VSOMEIP_MAX_WAIT_TIME_DETACHED_THREADS 5 - #define VSOMEIP_REQUEST_DEBOUNCE_TIME 10 #define VSOMEIP_DEFAULT_STATISTICS_MAX_MSG 50 #define VSOMEIP_DEFAULT_STATISTICS_MIN_FREQ 50 diff --git a/implementation/configuration/include/internal_android.hpp b/implementation/configuration/include/internal_android.hpp index b9631b041..4905631cc 100644 --- a/implementation/configuration/include/internal_android.hpp +++ b/implementation/configuration/include/internal_android.hpp @@ -87,8 +87,6 @@ #define VSOMEIP_MAX_DISPATCHERS 10 #define VSOMEIP_MAX_DISPATCH_TIME 100 -#define VSOMEIP_MAX_WAIT_TIME_DETACHED_THREADS 5 - #define VSOMEIP_REQUEST_DEBOUNCE_TIME 10 #define VSOMEIP_DEFAULT_STATISTICS_MAX_MSG 50 #define VSOMEIP_DEFAULT_STATISTICS_MIN_FREQ 50 diff --git a/implementation/configuration/src/configuration_impl.cpp b/implementation/configuration/src/configuration_impl.cpp index 4e8215100..8ec0a1a1a 100644 --- a/implementation/configuration/src/configuration_impl.cpp +++ b/implementation/configuration/src/configuration_impl.cpp @@ -982,7 +982,6 @@ void configuration_impl::load_application_data( client_t its_id(VSOMEIP_CLIENT_UNSET); std::size_t its_max_dispatchers(VSOMEIP_MAX_DISPATCHERS); std::size_t its_max_dispatch_time(VSOMEIP_MAX_DISPATCH_TIME); - std::size_t its_max_detached_thread_wait_time(VSOMEIP_MAX_WAIT_TIME_DETACHED_THREADS); std::size_t its_io_thread_count(VSOMEIP_DEFAULT_IO_THREAD_COUNT); std::size_t its_request_debounce_time(VSOMEIP_REQUEST_DEBOUNCE_TIME); std::map> plugins; @@ -1008,9 +1007,6 @@ void configuration_impl::load_application_data( } else if (its_key == "max_dispatch_time") { its_converter << std::dec << its_value; its_converter >> its_max_dispatch_time; - } else if (its_key == "max_detached_thread_wait_time") { - its_converter << std::dec << its_value; - its_converter >> its_max_detached_thread_wait_time; } else if (its_key == "threads") { its_converter << std::dec << its_value; its_converter >> its_io_thread_count; @@ -1041,7 +1037,8 @@ void configuration_impl::load_application_data( } catch (...) { // intentionally empty } - } else if (its_key == "has_session_handling") { + } + else if (its_key == "has_session_handling") { has_session_handling = (its_value != "false"); } } @@ -1059,16 +1056,17 @@ void configuration_impl::load_application_data( } } - applications_[its_name] = {its_id, - its_max_dispatchers, - its_max_dispatch_time, - its_max_detached_thread_wait_time, - its_io_thread_count, - its_request_debounce_time, - plugins, - its_io_thread_nice_level, - its_debounces, - has_session_handling}; + applications_[its_name] = { + its_id, + its_max_dispatchers, + its_max_dispatch_time, + its_io_thread_count, + its_request_debounce_time, + plugins, + its_io_thread_nice_level, + its_debounces + , has_session_handling + }; } else { VSOMEIP_WARNING << "Multiple configurations for application " << its_name << ". Ignoring a configuration from " @@ -3189,17 +3187,6 @@ std::size_t configuration_impl::get_max_dispatch_time( return its_max_dispatch_time; } -std::size_t configuration_impl::get_max_detached_thread_wait_time(const std::string& _name) const { - std::size_t its_max_detached_thread_wait_time = VSOMEIP_MAX_WAIT_TIME_DETACHED_THREADS; - - if (auto found_application = applications_.find(_name); - found_application != applications_.end()) { - its_max_detached_thread_wait_time = found_application->second.max_detach_thread_wait_time_; - } - - return its_max_detached_thread_wait_time; -} - bool configuration_impl::has_session_handling(const std::string &_name) const { bool its_value(true); diff --git a/implementation/runtime/include/application_impl.hpp b/implementation/runtime/include/application_impl.hpp index 082c21471..c1b95d91a 100644 --- a/implementation/runtime/include/application_impl.hpp +++ b/implementation/runtime/include/application_impl.hpp @@ -8,9 +8,7 @@ #include #include -#include #include -#include #include #include #include @@ -19,12 +17,6 @@ #include #include -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#define NOMINMAX -#include -#include -#endif #include #include @@ -313,6 +305,7 @@ class application_impl: public application, instance_t _instance, const availability_state_handler_t &_handler, major_version_t _major, minor_version_t _minor); + void main_dispatch(); void dispatch(); void invoke_handler(std::shared_ptr &_handler); @@ -352,10 +345,6 @@ class application_impl: public application, void invoke_availability_handler(service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor); - void increment_active_threads(); - void decrement_active_threads(); - std::uint16_t get_active_threads() const; - using availability_state_t = std::map>>>; @@ -457,23 +446,11 @@ class application_impl: public application, // Mutex to protect access to dispatchers_ & elapsed_dispatchers_ mutable std::mutex dispatcher_mutex_; - // Map of promises/futures to check status of dispatcher threads -#ifdef _WIN32 - std::map>> dispatchers_control_; -#else - std::map>> dispatchers_control_; -#endif - // Condition to wakeup the dispatcher thread mutable std::condition_variable dispatcher_condition_; std::size_t max_dispatchers_; std::size_t max_dispatch_time_; - // Counter for dispatcher threads - std::atomic dispatcher_counter_; - - std::size_t max_detached_thread_wait_time; - std::condition_variable stop_cv_; std::mutex start_stop_mutex_; bool stopped_; diff --git a/implementation/runtime/src/application_impl.cpp b/implementation/runtime/src/application_impl.cpp index e632770ab..b7eea42cd 100644 --- a/implementation/runtime/src/application_impl.cpp +++ b/implementation/runtime/src/application_impl.cpp @@ -48,22 +48,33 @@ configuration::~configuration() {} uint32_t application_impl::app_counter__ = 0; std::mutex application_impl::app_counter_mutex__; -application_impl::application_impl(const std::string& _name, const std::string& _path) : - runtime_(runtime::get()), client_(VSOMEIP_CLIENT_UNSET), session_(0), is_initialized_(false), - name_(_name), path_(_path), - work_(std::make_shared< - boost::asio::executor_work_guard>( - io_.get_executor())), - routing_(nullptr), state_(state_type_e::ST_DEREGISTERED), - security_mode_(security_mode_e::SM_ON), +application_impl::application_impl(const std::string &_name, const std::string &_path) + : runtime_(runtime::get()), + client_(VSOMEIP_CLIENT_UNSET), + session_(0), + is_initialized_(false), + name_(_name), + path_(_path), + work_(std::make_shared >(io_.get_executor())), + routing_(0), + state_(state_type_e::ST_DEREGISTERED), + security_mode_(security_mode_e::SM_ON), #ifdef VSOMEIP_ENABLE_SIGNAL_HANDLING - signals_(io_, SIGINT, SIGTERM), catched_signal_(false), + signals_(io_, SIGINT, SIGTERM), + catched_signal_(false), #endif - is_dispatching_(false), max_dispatchers_(VSOMEIP_MAX_DISPATCHERS), - max_dispatch_time_(VSOMEIP_MAX_DISPATCH_TIME), dispatcher_counter_(0), - max_detached_thread_wait_time(VSOMEIP_MAX_WAIT_TIME_DETACHED_THREADS), stopped_(false), - block_stopping_(false), is_routing_manager_host_(false), stopped_called_(false), - watchdog_timer_(io_), client_side_logging_(false), has_session_handling_(true) { + is_dispatching_(false), + max_dispatchers_(VSOMEIP_MAX_DISPATCHERS), + max_dispatch_time_(VSOMEIP_MAX_DISPATCH_TIME), + stopped_(false), + block_stopping_(false), + is_routing_manager_host_(false), + stopped_called_(false), + watchdog_timer_(io_), + client_side_logging_(false), + has_session_handling_(true) +{ } application_impl::~application_impl() { @@ -262,7 +273,6 @@ bool application_impl::init() { // the main dispatcher max_dispatchers_ = its_configuration->get_max_dispatchers(name_) + 1; max_dispatch_time_ = its_configuration->get_max_dispatch_time(name_); - max_detached_thread_wait_time = its_configuration->get_max_detached_thread_wait_time(name_); has_session_handling_ = its_configuration->has_session_handling(name_); if (!has_session_handling_) @@ -424,21 +434,10 @@ void application_impl::start() { { std::lock_guard its_lock(dispatcher_mutex_); is_dispatching_ = true; - std::packaged_task dispatcher_task_( - std::bind(&application_impl::main_dispatch, shared_from_this())); - std::future dispatcher_future_ = dispatcher_task_.get_future(); - auto its_main_dispatcher = std::make_shared(std::move(dispatcher_task_)); -#ifdef _WIN32 - dispatchers_control_[its_main_dispatcher->get_id()] = { - OpenThread(THREAD_ALL_ACCESS, false, - GetThreadId(its_main_dispatcher->native_handle())), - std::move(dispatcher_future_)}; -#else - dispatchers_control_[its_main_dispatcher->get_id()] = { - its_main_dispatcher->native_handle(), std::move(dispatcher_future_)}; -#endif + auto its_main_dispatcher = std::make_shared( + &application_impl::main_dispatch, shared_from_this() + ); dispatchers_[its_main_dispatcher->get_id()] = its_main_dispatcher; - increment_active_threads(); } if (stop_thread_.joinable()) { @@ -2018,24 +2017,9 @@ void application_impl::invoke_handler(std::shared_ptr &_handler) { if (dispatcher_mutex_.try_lock()) { if (dispatchers_.size() < max_dispatchers_) { if (is_dispatching_) { - std::packaged_task dispatcher_task_( - std::bind(&application_impl::dispatch, shared_from_this())); - std::future dispatcher_future_ = - dispatcher_task_.get_future(); - auto its_dispatcher = - std::make_shared(std::move(dispatcher_task_)); -#ifdef _WIN32 - dispatchers_control_[its_dispatcher->get_id()] = { - OpenThread(THREAD_ALL_ACCESS, false, - GetThreadId(its_dispatcher->native_handle())), - std::move(dispatcher_future_)}; -#else - dispatchers_control_[its_dispatcher->get_id()] = { - its_dispatcher->native_handle(), - std::move(dispatcher_future_)}; -#endif + auto its_dispatcher = std::make_shared( + std::bind(&application_impl::dispatch, shared_from_this())); dispatchers_[its_dispatcher->get_id()] = its_dispatcher; - increment_active_threads(); } else { VSOMEIP_INFO << "Won't start new dispatcher " "thread as Client=" << std::hex @@ -2142,12 +2126,9 @@ void application_impl::remove_elapsed_dispatchers() { if (is_dispatching_) { std::lock_guard its_lock(dispatcher_mutex_); for (auto id : elapsed_dispatchers_) { - if (auto its_dispatcher = dispatchers_.find(id); its_dispatcher->second->joinable()) { - dispatchers_control_.erase(id); + auto its_dispatcher = dispatchers_.find(id); + if (its_dispatcher->second->joinable()) its_dispatcher->second->join(); - decrement_active_threads(); - } - dispatchers_.erase(id); } elapsed_dispatchers_.clear(); @@ -2221,9 +2202,7 @@ void application_impl::shutdown() { for (const auto& its_dispatcher : dispatchers_) { if (its_dispatcher.second->get_id() != stop_caller_id_) { if (its_dispatcher.second->joinable()) { - dispatchers_control_.erase(its_dispatcher.second->get_id()); its_dispatcher.second->join(); - decrement_active_threads(); } } else { // If the caller of stop() is one of our dispatchers @@ -2237,7 +2216,6 @@ void application_impl::shutdown() { // after it will return to "main_dispatch" it will be // properly shutdown anyways because "is_dispatching_" // was set to "false" here. - its_dispatcher.second->detach(); } } @@ -2258,65 +2236,6 @@ void application_impl::shutdown() { << " catched exception: " << e.what(); } - try { - while (get_active_threads() > 0) { - auto its_dispatcher_control_ = dispatchers_control_.begin(); - bool os_flag_ = false; - - if (its_dispatcher_control_ != dispatchers_control_.end()) { - if (std::get<1>(its_dispatcher_control_->second) - .wait_for(std::chrono::seconds(max_detached_thread_wait_time)) - == std::future_status::timeout) { - -#ifdef _WIN32 - TerminateThread(std::get<0>(its_dispatcher_control_->second), 0); -#else - pthread_t thread_to_kill = std::get<0>(its_dispatcher_control_->second); - - // Using pthread_cancel for UNIX based systems and pthread_kill(SIGKILL) - // for android since pthread_cancel is not implemented on android. - // The major difference is that pthread_cancel allows for signal handling - // and proper resource cleanup to be done on the application side - // while pthread_kill(SIGKILL) stops the thread immediately. - // This should not however be an issue since this will only be called - // if the thread is already stuck for some time during app->stop() -#if defined(ANDROID) - os_flag_ = true; - if (pthread_kill(thread_to_kill, SIGKILL) != 0) { -#elif defined(__linux__) || defined(__QNX__) - if (pthread_cancel(thread_to_kill) != 0) { -#endif - VSOMEIP_ERROR - << "[OS=" << (os_flag_ ? "ANDROID" : "UNIX") << "] " - << "Failed to kill detached thread with id: " << std::hex - << its_dispatcher_control_->first - << "; Number of threads still active : " << get_active_threads(); - } else { - decrement_active_threads(); - VSOMEIP_INFO - << "[OS=" << (os_flag_ ? "ANDROID" : "UNIX") << "] " - << "Force killed thread with id: " << std::hex - << its_dispatcher_control_->first - << "; Number of threads still active : " << get_active_threads(); - dispatchers_control_.erase(its_dispatcher_control_); - } -#endif - } else { - decrement_active_threads(); - VSOMEIP_INFO << "[OS=" << (os_flag_ ? "ANDROID" : "UNIX") << "] " - << "Detached thread with id: " << std::hex - << its_dispatcher_control_->first << " exited successfully" - << "; Number of threads still active : " << get_active_threads(); - dispatchers_control_.erase(its_dispatcher_control_); - } - } - } - } catch (const std::exception& e) { - VSOMEIP_ERROR << "application_impl::" << __func__ - << ": waiting for detached threads to finish execution, " - << " catched exception: " << e.what(); - } - try { work_.reset(); io_.stop(); @@ -3106,20 +3025,4 @@ void application_impl::register_message_handler_ext( } } -void application_impl::increment_active_threads() { - dispatcher_counter_++; - VSOMEIP_DEBUG << "Thread created. Number of active threads for " << name_ << " : " - << get_active_threads(); -} - -void application_impl::decrement_active_threads() { - dispatcher_counter_--; - VSOMEIP_DEBUG << "Thread destroyed. Number of active threads for " << name_ << " : " - << get_active_threads(); -} - -std::uint16_t application_impl::get_active_threads() const { - return dispatcher_counter_; -} - } // namespace vsomeip_v3 diff --git a/implementation/runtime/src/runtime_impl.cpp b/implementation/runtime/src/runtime_impl.cpp index 3886f7e22..82f331486 100644 --- a/implementation/runtime/src/runtime_impl.cpp +++ b/implementation/runtime/src/runtime_impl.cpp @@ -59,7 +59,7 @@ std::shared_ptr runtime_impl::create_message(bool _reliable) const { } std::shared_ptr runtime_impl::create_request(bool _reliable) const { - auto its_request = std::make_shared(); + auto its_request = std::make_shared(); its_request->set_protocol_version(VSOMEIP_PROTOCOL_VERSION); its_request->set_message_type(message_type_e::MT_REQUEST); its_request->set_return_code(return_code_e::E_OK); @@ -125,4 +125,5 @@ void runtime_impl::remove_application( applications_.erase(_name); } } + } // namespace vsomeip_v3 diff --git a/test/network_tests/application_tests/CMakeLists.txt b/test/network_tests/application_tests/CMakeLists.txt index 65dd6eabe..a10cef917 100644 --- a/test/network_tests/application_tests/CMakeLists.txt +++ b/test/network_tests/application_tests/CMakeLists.txt @@ -13,10 +13,7 @@ set(configuration_files application_test_daemon.json application_test_no_dispatch_threads.json application_test_no_dispatch_threads_daemon.json - application_test_dispatch_threads.json application_test_starter.sh - application_test_dispatch_threads_starter.sh - application_test_dispatch_threads_executor_starter.sh ) configure_files("${configuration_files}") @@ -30,22 +27,10 @@ add_executable(application_test_multiple_init application_test_multiple_init.cpp ) -# Add the test executable for application_test_dispatch_threads_executor -add_executable(application_test_dispatch_threads_executor - application_test_dispatch_threads_executor.cpp -) - -# Add the test executable for application_test_dispatch_threads -add_executable(application_test_dispatch_threads - application_test_dispatch_threads.cpp -) - # Add build dependencies and link libraries to executables. set(executable_targets application_test application_test_multiple_init - application_test_dispatch_threads - application_test_dispatch_threads_executor ) targets_add_default_dependencies("${executable_targets}") targets_link_default_libraries("${executable_targets}") @@ -64,13 +49,6 @@ add_custom_test( TIMEOUT 180 ) -# Add custom test command. -add_custom_test( - NAME application_test_dispatch_threads_executor - COMMAND ${CMAKE_CURRENT_BINARY_DIR}/application_test_dispatch_threads_executor_starter.sh - TIMEOUT 180 -) - if (NOT ${TESTS_BAT}) # Configure necessary files and copy them to the build folder. diff --git a/test/network_tests/application_tests/application_test_dispatch_threads.cpp b/test/network_tests/application_tests/application_test_dispatch_threads.cpp deleted file mode 100644 index 33bc35dcc..000000000 --- a/test/network_tests/application_tests/application_test_dispatch_threads.cpp +++ /dev/null @@ -1,307 +0,0 @@ -// Copyright (C) 2015-2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include - -#include "application_test_globals.hpp" -#include "someip_test_globals.hpp" - -using namespace vsomeip; - -class someip_application_detach_dispatch { - -public: - bool is_registered_; - bool is_available_; - std::atomic_bool is_forcefully_stopped_; - std::atomic_bool is_finished_; - std::shared_ptr app_; - std::condition_variable cv_; - std::mutex mutex_; - std::thread thread_; - - someip_application_detach_dispatch() { } - ~someip_application_detach_dispatch() { } - - void init() { - is_registered_ = false; - is_available_ = false; - - app_ = runtime::get()->create_application("application_test_dispatch_threads"); - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - - app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, - vsomeip_test::TEST_SERVICE_DETACH_METHOD_ID, - std::bind(&someip_application_detach_dispatch::on_message, - this, std::placeholders::_1)); - - app_->register_message_handler( - vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, - vsomeip_test::TEST_SERVICE_DETACH_METHOD_ID_LOOP_SHORT, - std::bind(&someip_application_detach_dispatch::on_message_loop_short, this, - std::placeholders::_1)); - - app_->register_message_handler( - vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, - vsomeip_test::TEST_SERVICE_DETACH_METHOD_ID_LOOP_LONG, - std::bind(&someip_application_detach_dispatch::on_message_loop_long, this, - std::placeholders::_1)); - - app_->register_state_handler(std::bind(&someip_application_detach_dispatch::on_state, this, - std::placeholders::_1)); - app_->register_availability_handler( - vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, - std::bind(&someip_application_detach_dispatch::on_availability, this, - std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - } - - void cleanup() { - app_->stop(); - app_.reset(); - std::this_thread::sleep_for(std::chrono::milliseconds(5)); - } - - void on_state(vsomeip::state_type_e _state) { - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - std::lock_guard its_lock(mutex_); - is_registered_ = true; - cv_.notify_one(); - } - } - - void on_availability(vsomeip::service_t _service, vsomeip::instance_t _instance, - bool _is_available) { - (void)_service; - (void)_instance; - if (_is_available) { - std::lock_guard its_lock(mutex_); - is_available_ = _is_available; - cv_.notify_one(); - } - } - - void on_message_loop_short(const std::shared_ptr& _request) { - (void)_request; - VSOMEIP_INFO << "Processing something for 5 seconds"; - - pthread_cleanup_push(handler_cbk, nullptr); - - is_finished_ = false; - is_forcefully_stopped_ = false; - - for (int i = 0; i < 6; i++) { - std::unique_lock its_lock(mutex_); - VSOMEIP_INFO << "Elapsed time: " << i << " seconds"; - - // Call stop after 5 seconds - if (i == 5) { - VSOMEIP_INFO << "Sending stop signal after " << i << " seconds"; - app_->stop(); - } - // using a condition variable instead of sleep_for so that ThreadSanitizer does not - // raise any issues - cv_.wait_for(its_lock, std::chrono::seconds(1)); - pthread_testcancel(); - } - - VSOMEIP_INFO << "Finished processing"; - is_finished_ = true; - pthread_cleanup_pop(0); - } - - void on_message_loop_long(const std::shared_ptr& _request) { - (void)_request; - VSOMEIP_INFO << "Processing something for 50 seconds"; - - pthread_cleanup_push(handler_cbk, this); - - is_finished_ = false; - is_forcefully_stopped_ = false; - - for (int i = 0; i < 50; i++) { - std::unique_lock its_lock(mutex_); - VSOMEIP_INFO << "Elapsed time: " << i << " seconds"; - - // Call stop after 5 seconds - if (i == 5) { - VSOMEIP_INFO << "Sending stop signal after " << i << " seconds"; - app_->stop(); - } - // using a condition variable instead of sleep_for so that ThreadSanitizer does not - // raise any issues - cv_.wait_for(its_lock, std::chrono::seconds(1)); - pthread_testcancel(); - } - - VSOMEIP_INFO << "Finished processing"; - is_finished_ = true; - pthread_cleanup_pop(0); - } - - void on_message(const std::shared_ptr& _request) { - (void)_request; - VSOMEIP_INFO << "Processing something"; - - std::unique_lock its_lock(mutex_); - // using a condition variable instead of sleep_for so that ThreadSanitizer does not raise - // any issues - cv_.wait_for(its_lock, std::chrono::milliseconds(100)); - } - - static void handler_cbk(void* arg) { - if (arg != nullptr) { - static_cast(arg)->cleanup_handler(arg); - } - } - - void cleanup_handler(void* arg) { - (void)arg; - VSOMEIP_INFO << "Setting is_forcefully_stopped_ to true"; - is_forcefully_stopped_ = true; - } - - void send_messages(vsomeip_v3::method_t method_id) { - { - std::unique_lock its_lock(mutex_); - while (!is_registered_) { - if (std::cv_status::timeout == cv_.wait_for(its_lock, std::chrono::seconds(10))) { - ADD_FAILURE() << "Application wasn't registered in time!"; - is_registered_ = true; - } - } - app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID); - app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID); - while (!is_available_) { - if (std::cv_status::timeout == cv_.wait_for(its_lock, std::chrono::seconds(10))) { - ADD_FAILURE() << "Service didn't become available in time!"; - is_available_ = true; - } - } - } - - create_send_request(method_id); - create_send_request(vsomeip_test::TEST_SERVICE_DETACH_METHOD_ID); - } - - void create_send_request(vsomeip_v3::method_t method_id) { - std::shared_ptr t = runtime::get()->create_request(); - t->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); - t->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); - t->set_method(method_id); - app_->send(t); - } - - void execute(char** argv) { - // Create a shared memory object. - boost::interprocess::shared_memory_object shm( - boost::interprocess::open_only, // only create - "SharedCV", // name - boost::interprocess::read_write // read-write mode - ); - - try { - // Map the whole shared memory in this process - boost::interprocess::mapped_region region( - shm, // What to map - boost::interprocess::read_write // Map it as read-write - ); - - // Get the address of the mapped region - void* addr = region.get_address(); - - // Obtain a pointer to the shared structure - application_test::dispatch_threads_sync* data = - static_cast(addr); - - init(); - - std::promise its_promise; - std::thread t([&]() { app_->start(); }); - - { - boost::interprocess::scoped_lock lock( - data->mutex); - - // Set initial value of status_ - data->status_ = application_test::dispatch_threads_sync::TEST_FAILURE; - - // Read to argv[2] timeout and convert to tenths of a second - int timeout = std::stoi(argv[2]) * 10; - - // argv[1] should be the type of test to run - if (strcmp(argv[1], "force_abort") == 0) { - VSOMEIP_INFO << "Testing Force Abort"; - send_messages(vsomeip_test::TEST_SERVICE_DETACH_METHOD_ID_LOOP_LONG); - - for (int i = 0; i < timeout; i++) { - - if (is_forcefully_stopped_ == true && is_finished_ == false) { - VSOMEIP_INFO << "Updating CV"; - data->status_ = - application_test::dispatch_threads_sync::SUCCESS_ABORTING; - data->cv.notify_all(); - break; - } - - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - - } else if (strcmp(argv[1], "wait_finish") == 0) { - VSOMEIP_INFO << "Testing Wait Finish"; - send_messages(vsomeip_test::TEST_SERVICE_DETACH_METHOD_ID_LOOP_SHORT); - - for (int i = 0; i < timeout; i++) { - - if (is_forcefully_stopped_ == false && is_finished_ == true) { - VSOMEIP_INFO << "Updating CV"; - data->status_ = - application_test::dispatch_threads_sync::SUCCESS_WAITING; - data->cv.notify_all(); - break; - } - - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - } - } - - VSOMEIP_INFO << "Finishing execution"; - - t.join(); - - cleanup(); - - } catch (boost::interprocess::interprocess_exception& ex) { - FAIL() << ex.what(); - } - } -}; - -#if defined(__linux__) || defined(ANDROID) || defined(__QNX__) -int main(int argc, char** argv) { - (void)argc; - - someip_application_detach_dispatch exec; - exec.execute(argv); -} -#endif diff --git a/test/network_tests/application_tests/application_test_dispatch_threads_executor.cpp b/test/network_tests/application_tests/application_test_dispatch_threads_executor.cpp deleted file mode 100644 index e354b15ea..000000000 --- a/test/network_tests/application_tests/application_test_dispatch_threads_executor.cpp +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright (C) 2015-2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include - -#include "application_test_globals.hpp" -#include "someip_test_globals.hpp" - -using namespace vsomeip; - -class someip_application_detach_dispatch_executor : public ::testing::Test { - -protected: - void SetUp() { VSOMEIP_INFO << "Setting up test"; } - - void TearDown() { VSOMEIP_INFO << "Tearing down"; } - - int get_process_pid(std::string process_name) { - std::string file_name = "/tmp/" + process_name + ".pid"; - int pid = -1; - FILE* file = fopen(file_name.c_str(), "r"); - - if (file) { - if (fscanf(file, "%d", &pid) != 1) { // Check that fscanf successfully read one integer - std::cerr << "Failed to read PID from file" << std::endl; - pid = -1; // Indicate failure - } - fclose(file); - } else { - std::cerr << "Failed to open PID file" << std::endl; - } - - return pid; - } - - // Erase previous shared memory and schedule erasure on exit - - boost::interprocess::shared_memory_object shm; - - std::condition_variable cv_; - std::mutex mutex_; -}; - -/** - * @test Force detaching of dispatcher threads with long processing times - */ -TEST_F(someip_application_detach_dispatch_executor, dispatch_thread_detached_forcefully_stopped) { - - struct shm_remove { - shm_remove() { boost::interprocess::shared_memory_object::remove("SharedCV"); } - ~shm_remove() { boost::interprocess::shared_memory_object::remove("SharedCV"); } - } remover; - - // Create a shared memory object. - boost::interprocess::shared_memory_object shm( - boost::interprocess::open_or_create, // only create - "SharedCV", // name - boost::interprocess::read_write // read-write mode - ); - - // Timeout to pass into the test - int seconds_to_timeout = 20; - - // Define how long should the test wait for the condition variable to be set - boost::posix_time::ptime timeout = boost::posix_time::second_clock::local_time() - + boost::posix_time::seconds(seconds_to_timeout); - - try { - // Set size - shm.truncate(sizeof(application_test::dispatch_threads_sync)); - - // Map the whole shared memory in this process - boost::interprocess::mapped_region region( - shm, // What to map - boost::interprocess::read_write // Map it as read-write - ); - - // Get the address of the mapped region - void* addr = region.get_address(); - - // Construct the shared structure in memory - application_test::dispatch_threads_sync* data = - new (addr) application_test::dispatch_threads_sync; - - { - boost::interprocess::scoped_lock lock( - data->mutex); - - std::string exec_cmd = "./application_test_dispatch_threads_starter.sh force_abort " - + std::to_string(seconds_to_timeout); - std::cout << std::flush; - - EXPECT_EQ(system(exec_cmd.c_str()), 0); - - EXPECT_EQ(data->cv.timed_wait(lock, timeout, [&] { return data->status_; }), - application_test::dispatch_threads_sync::SUCCESS_ABORTING); - - // Retrieve the PID - int pid = get_process_pid("application_test_dispatch_threads"); - - std::string check_cmd = "kill -0 " + std::to_string(pid); - - if (system(check_cmd.c_str()) - == 0) { // If the process exists, the command will return 0 - std::string kill_cmd = "kill -9 " + std::to_string(pid); - EXPECT_EQ(system(kill_cmd.c_str()), 0); - } - } - } catch (boost::interprocess::interprocess_exception& ex) { - std::cout << ex.what() << std::endl; - } -} - -/** - * @test Force detaching of dispatcher threads with but dispatcher finishes processing - */ -TEST_F(someip_application_detach_dispatch_executor, dispatch_thread_detached_finishes_execution) { - - struct shm_remove { - shm_remove() { boost::interprocess::shared_memory_object::remove("SharedCV"); } - ~shm_remove() { boost::interprocess::shared_memory_object::remove("SharedCV"); } - } remover; - - // Create a shared memory object. - boost::interprocess::shared_memory_object shm( - boost::interprocess::open_or_create, // only create - "SharedCV", // name - boost::interprocess::read_write // read-write mode - ); - - VSOMEIP_INFO << "Starting test"; - - // Timeout to pass into the test - int seconds_to_timeout = 8; - - // Define how long should the test wait for the condition variable to be set - boost::posix_time::ptime timeout = boost::posix_time::second_clock::local_time() - + boost::posix_time::seconds(seconds_to_timeout); - - VSOMEIP_INFO << "Timeout set to " << timeout; - - try { - // Set size - shm.truncate(sizeof(application_test::dispatch_threads_sync)); - - // Map the whole shared memory in this process - boost::interprocess::mapped_region region( - shm, // What to map - boost::interprocess::read_write // Map it as read-write - ); - - // Get the address of the mapped region - void* addr = region.get_address(); - - // Construct the shared structure in memory - application_test::dispatch_threads_sync* data = - new (addr) application_test::dispatch_threads_sync; - - { - boost::interprocess::scoped_lock lock( - data->mutex); - - std::string exec_cmd = "./application_test_dispatch_threads_starter.sh wait_finish " - + std::to_string(seconds_to_timeout); - - ASSERT_EQ(system(exec_cmd.c_str()), 0); - - EXPECT_EQ(data->cv.timed_wait(lock, timeout, [&] { return data->status_; }), - application_test::dispatch_threads_sync::SUCCESS_WAITING); - - // Retrieve the PID - int pid = get_process_pid("application_test_dispatch_threads"); - - std::string check_cmd = "kill -0 " + std::to_string(pid); - - if (system(check_cmd.c_str()) - == 0) { // If the process exists, the command will return 0 - std::string kill_cmd = "kill -9 " + std::to_string(pid); - EXPECT_EQ(system(kill_cmd.c_str()), 0); - } - } - } catch (boost::interprocess::interprocess_exception& ex) { - std::cout << ex.what() << std::endl; - } -} - -#if defined(__linux__) || defined(ANDROID) || defined(__QNX__) -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/network_tests/application_tests/application_test_globals.hpp b/test/network_tests/application_tests/application_test_globals.hpp index 7843d7025..7caa9db2c 100644 --- a/test/network_tests/application_tests/application_test_globals.hpp +++ b/test/network_tests/application_tests/application_test_globals.hpp @@ -6,9 +6,6 @@ #ifndef APPLICATION_TEST_GLOBALS_HPP_ #define APPLICATION_TEST_GLOBALS_HPP_ -#include -#include - namespace application_test { struct service_info { @@ -22,16 +19,8 @@ struct service_info { vsomeip::minor_version_t minor_version; }; -struct service_info service = {0x1111, 0x1, 0x1111, 0x1111, 0x1000, 0x1404, 0x2, 0x4711}; - -struct dispatch_threads_sync { - enum test_status { SUCCESS_ABORTING = 0x00, SUCCESS_WAITING = 0x01, TEST_FAILURE = 0x02 }; - boost::interprocess::interprocess_mutex mutex; - boost::interprocess::interprocess_condition cv; - - test_status status_; -}; +struct service_info service = { 0x1111, 0x1, 0x1111, 0x1111, 0x1000, 0x1404, 0x2, 0x4711 }; static constexpr int number_of_messages_to_send = 150; } diff --git a/test/network_tests/application_tests/conf/application_test_dispatch_threads.json.in b/test/network_tests/application_tests/conf/application_test_dispatch_threads.json.in deleted file mode 100644 index f65e893ae..000000000 --- a/test/network_tests/application_tests/conf/application_test_dispatch_threads.json.in +++ /dev/null @@ -1,39 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/someip.log" - }, - "dlt":"true" - }, - "applications": - [ - { - "name":"application_test_dispatch_threads", - "id":"0x7788", - "num_dispatchers":"5", - "max_detached_thread_wait_time":"5" - } - ], - "services": - [ - { - "service":"0x1234", - "instance":"0x5678", - "reliable":"30503" - } - ], - "routing":"application_test_dispatch_threads", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp" - } -} diff --git a/test/network_tests/application_tests/conf/application_test_dispatch_threads_executor_starter.sh.in b/test/network_tests/application_tests/conf/application_test_dispatch_threads_executor_starter.sh.in deleted file mode 100755 index b76444c77..000000000 --- a/test/network_tests/application_tests/conf/application_test_dispatch_threads_executor_starter.sh.in +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -export VSOMEIP_CONFIGURATION=application_test_dispatch_threads.json -./application_test_dispatch_threads_executor diff --git a/test/network_tests/application_tests/conf/application_test_dispatch_threads_starter.sh.in b/test/network_tests/application_tests/conf/application_test_dispatch_threads_starter.sh.in deleted file mode 100755 index fa294a813..000000000 --- a/test/network_tests/application_tests/conf/application_test_dispatch_threads_starter.sh.in +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2024 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -export VSOMEIP_CONFIGURATION=application_test_dispatch_threads.json -./application_test_dispatch_threads "$1" "$2" & -PROCESS_PID=$! -echo $PROCESS_PID > /tmp/application_test_dispatch_threads.pid - -if [ $? -ne 0 ] -then - exit 1 -else - exit 0 -fi diff --git a/test/network_tests/configuration_tests/conf/configuration_test.json.in b/test/network_tests/configuration_tests/conf/configuration_test.json.in index 6ee9168b8..3e24819fa 100644 --- a/test/network_tests/configuration_tests/conf/configuration_test.json.in +++ b/test/network_tests/configuration_tests/conf/configuration_test.json.in @@ -95,7 +95,6 @@ "id" : "0x7788", "max_dispatchers" : "25", "max_dispatch_time" : "1234", - "max_detached_thread_wait_time":"3", "threads" : "12", "request_debounce_time" : "5000", "plugins" : diff --git a/test/network_tests/configuration_tests/conf/configuration_test_deprecated.json.in b/test/network_tests/configuration_tests/conf/configuration_test_deprecated.json.in index a6cc993c8..3e4c118d6 100644 --- a/test/network_tests/configuration_tests/conf/configuration_test_deprecated.json.in +++ b/test/network_tests/configuration_tests/conf/configuration_test_deprecated.json.in @@ -71,7 +71,6 @@ "id" : "0x7788", "max_dispatchers" : "25", "max_dispatch_time" : "1234", - "max_detached_thread_wait_time":"3", "threads" : "12", "request_debounce_time" : "5000", "plugins" : diff --git a/test/network_tests/configuration_tests/configuration_test.cpp b/test/network_tests/configuration_tests/configuration_test.cpp index 68e017e37..c1e0acf21 100644 --- a/test/network_tests/configuration_tests/configuration_test.cpp +++ b/test/network_tests/configuration_tests/configuration_test.cpp @@ -43,7 +43,6 @@ namespace vsomeip = vsomeip_v3; // Application #define EXPECTED_APPLICATION_MAX_DISPATCHERS 25 #define EXPECTED_APPLICATION_MAX_DISPATCH_TIME 1234 -#define EXPECTED_APPLICATION_MAX_DETACHED_THREAD_WAIT_TIME 3 #define EXPECTED_APPLICATION_THREADS 12 #define EXPECTED_APPLICATION_REQUEST_DEBOUNCE_TIME 5000 @@ -127,7 +126,6 @@ void check_file(const std::string &_config_file, uint32_t _expected_version_logging_interval, uint32_t _expected_application_max_dispatcher, uint32_t _expected_application_max_dispatch_time, - uint32_t _expected_application_max_detached_thread_wait_time, uint32_t _expected_application_threads, uint32_t _expected_application_request_debounce_time, const std::string &_expected_logfile, @@ -334,8 +332,6 @@ void check_file(const std::string &_config_file, EXPECTED_ROUTING_MANAGER_HOST); std::size_t max_dispatch_time = its_configuration->get_max_dispatch_time( EXPECTED_ROUTING_MANAGER_HOST); - std::size_t max_detached_thread_wait_time = its_configuration->get_max_detached_thread_wait_time( - EXPECTED_ROUTING_MANAGER_HOST); std::size_t io_threads = its_configuration->get_io_thread_count( EXPECTED_ROUTING_MANAGER_HOST); std::size_t request_time = its_configuration->get_request_debouncing( @@ -345,8 +341,6 @@ void check_file(const std::string &_config_file, _expected_application_max_dispatcher, "MAX DISPATCHERS")); EXPECT_TRUE(check(max_dispatch_time, _expected_application_max_dispatch_time, "MAX DISPATCH TIME")); - EXPECT_TRUE(check(max_detached_thread_wait_time, - _expected_application_max_detached_thread_wait_time, "MAX DETACHED THREADS WAIT TIME")); EXPECT_TRUE(check(io_threads, _expected_application_threads, "IO THREADS")); EXPECT_TRUE(check(request_time, @@ -773,7 +767,6 @@ TEST(configuration_test, check_config_file) { EXPECTED_VERSION_LOGGING_INTERVAL, EXPECTED_APPLICATION_MAX_DISPATCHERS, EXPECTED_APPLICATION_MAX_DISPATCH_TIME, - EXPECTED_APPLICATION_MAX_DETACHED_THREAD_WAIT_TIME, EXPECTED_APPLICATION_THREADS, EXPECTED_APPLICATION_REQUEST_DEBOUNCE_TIME, EXPECTED_LOGFILE, @@ -817,7 +810,6 @@ TEST(configuration_test, check_deprecated_config_file) { EXPECTED_VERSION_LOGGING_INTERVAL, EXPECTED_APPLICATION_MAX_DISPATCHERS, EXPECTED_APPLICATION_MAX_DISPATCH_TIME, - EXPECTED_APPLICATION_MAX_DETACHED_THREAD_WAIT_TIME, EXPECTED_APPLICATION_THREADS, EXPECTED_APPLICATION_REQUEST_DEBOUNCE_TIME, EXPECTED_LOGFILE, diff --git a/test/network_tests/someip_test_globals.hpp b/test/network_tests/someip_test_globals.hpp index adaf6849f..805362717 100644 --- a/test/network_tests/someip_test_globals.hpp +++ b/test/network_tests/someip_test_globals.hpp @@ -23,9 +23,6 @@ constexpr vsomeip::service_t TEST_SERVICE_SERVICE_ID = 0x1234; constexpr vsomeip::instance_t TEST_SERVICE_INSTANCE_ID = 0x5678; constexpr vsomeip::method_t TEST_SERVICE_METHOD_ID = 0x8421; constexpr vsomeip::method_t TEST_SERVICE_METHOD_ID_SHUTDOWN = 0x7777; -constexpr vsomeip::method_t TEST_SERVICE_DETACH_METHOD_ID_LOOP_LONG = 0x8887; -constexpr vsomeip::method_t TEST_SERVICE_DETACH_METHOD_ID_LOOP_SHORT = 0x8888; -constexpr vsomeip::method_t TEST_SERVICE_DETACH_METHOD_ID = 0x8889; constexpr vsomeip::client_t TEST_SERVICE_CLIENT_ID = 0x1277; // Client local