From e20aff9795febe8d170e1e776f8b7a1b60d2b0cc Mon Sep 17 00:00:00 2001 From: Juergen Gehring Date: Thu, 25 Jan 2018 00:40:02 -0800 Subject: vsomeip 2.7.3 --- CHANGES | 4 + CMakeLists.txt | 2 +- .../endpoints/include/client_endpoint.hpp | 2 +- .../endpoints/include/client_endpoint_impl.hpp | 8 +- implementation/endpoints/include/endpoint.hpp | 2 +- implementation/endpoints/include/endpoint_impl.hpp | 2 +- .../include/local_client_endpoint_impl.hpp | 3 +- .../endpoints/include/tcp_client_endpoint_impl.hpp | 4 +- .../endpoints/include/tcp_server_endpoint_impl.hpp | 2 +- .../endpoints/include/udp_client_endpoint_impl.hpp | 6 +- .../endpoints/include/udp_server_endpoint_impl.hpp | 2 +- .../include/virtual_server_endpoint_impl.hpp | 4 +- .../endpoints/src/client_endpoint_impl.cpp | 13 +- implementation/endpoints/src/endpoint_impl.cpp | 2 +- .../endpoints/src/local_client_endpoint_impl.cpp | 6 +- .../endpoints/src/tcp_client_endpoint_impl.cpp | 9 +- .../endpoints/src/tcp_server_endpoint_impl.cpp | 2 +- .../endpoints/src/udp_client_endpoint_impl.cpp | 9 +- .../endpoints/src/udp_server_endpoint_impl.cpp | 2 +- .../endpoints/src/virtual_server_endpoint_impl.cpp | 4 +- .../routing/include/routing_manager_impl.hpp | 3 +- .../routing/src/routing_manager_impl.cpp | 133 ++++++++++++--------- .../include/service_discovery_impl.hpp | 1 + .../src/service_discovery_impl.cpp | 26 ++++ 24 files changed, 157 insertions(+), 94 deletions(-) diff --git a/CHANGES b/CHANGES index a38c85f..9305bf4 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,10 @@ Changes ======= +v.2.7.3 +- Fix deadlock when stopping client endpoints to remote services +- Fix deadlock during construction of Subscribe Eventgroup entries + v.2.7.2 - Avoid deadlock when printing error message about too large messages diff --git a/CMakeLists.txt b/CMakeLists.txt index 85de96f..1440c33 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ project (vsomeip) set (VSOMEIP_MAJOR_VERSION 2) set (VSOMEIP_MINOR_VERSION 7) -set (VSOMEIP_PATCH_VERSION 2) +set (VSOMEIP_PATCH_VERSION 3) set (VSOMEIP_VERSION ${VSOMEIP_MAJOR_VERSION}.${VSOMEIP_MINOR_VERSION}.${VSOMEIP_PATCH_VERSION}) set (PACKAGE_VERSION ${VSOMEIP_VERSION}) # Used in documentatin/doxygen.in set (CMAKE_VERBOSE_MAKEFILE off) diff --git a/implementation/endpoints/include/client_endpoint.hpp b/implementation/endpoints/include/client_endpoint.hpp index f607e49..4dc828a 100644 --- a/implementation/endpoints/include/client_endpoint.hpp +++ b/implementation/endpoints/include/client_endpoint.hpp @@ -15,7 +15,7 @@ public: virtual ~client_endpoint() {} virtual bool get_remote_address(boost::asio::ip::address &_address) const = 0; - virtual unsigned short get_remote_port() const = 0; + virtual std::uint16_t get_remote_port() const = 0; }; } // namespace vsomeip diff --git a/implementation/endpoints/include/client_endpoint_impl.hpp b/implementation/endpoints/include/client_endpoint_impl.hpp index 141e95f..57a3084 100644 --- a/implementation/endpoints/include/client_endpoint_impl.hpp +++ b/implementation/endpoints/include/client_endpoint_impl.hpp @@ -53,7 +53,9 @@ public: bool is_connected() const; virtual bool get_remote_address(boost::asio::ip::address &_address) const; - virtual unsigned short get_remote_port() const; + virtual std::uint16_t get_remote_port() const; + + std::uint16_t get_local_port() const; public: void connect_cbk(boost::system::error_code const &_error); @@ -90,6 +92,10 @@ protected: bool was_not_connected_; + std::atomic local_port_; + +private: + virtual void set_local_port() = 0; }; } // namespace vsomeip diff --git a/implementation/endpoints/include/endpoint.hpp b/implementation/endpoints/include/endpoint.hpp index e8752c0..94a892e 100644 --- a/implementation/endpoints/include/endpoint.hpp +++ b/implementation/endpoints/include/endpoint.hpp @@ -39,7 +39,7 @@ public: const std::string &_address, uint16_t _port) = 0; virtual void remove_default_target(service_t _service) = 0; - virtual unsigned short get_local_port() const = 0; + virtual std::uint16_t get_local_port() const = 0; virtual bool is_reliable() const = 0; virtual bool is_local() const = 0; diff --git a/implementation/endpoints/include/endpoint_impl.hpp b/implementation/endpoints/include/endpoint_impl.hpp index 6b8b274..3e5ac22 100644 --- a/implementation/endpoints/include/endpoint_impl.hpp +++ b/implementation/endpoints/include/endpoint_impl.hpp @@ -44,7 +44,7 @@ public: // Dummy implementations as we only need these for server endpoints // TODO: redesign - unsigned short get_local_port() const; + std::uint16_t get_local_port() const; bool is_reliable() const; void increment_use_count(); diff --git a/implementation/endpoints/include/local_client_endpoint_impl.hpp b/implementation/endpoints/include/local_client_endpoint_impl.hpp index 7b71968..eb1b310 100644 --- a/implementation/endpoints/include/local_client_endpoint_impl.hpp +++ b/implementation/endpoints/include/local_client_endpoint_impl.hpp @@ -43,7 +43,7 @@ public: bool is_local() const; bool get_remote_address(boost::asio::ip::address &_address) const; - unsigned short get_remote_port() const; + std::uint16_t get_remote_port() const; void restart(); @@ -56,6 +56,7 @@ private: void receive(); void receive_cbk(boost::system::error_code const &_error, std::size_t _bytes); + void set_local_port(); message_buffer_t recv_buffer_; }; diff --git a/implementation/endpoints/include/tcp_client_endpoint_impl.hpp b/implementation/endpoints/include/tcp_client_endpoint_impl.hpp index cd8420a..991949c 100644 --- a/implementation/endpoints/include/tcp_client_endpoint_impl.hpp +++ b/implementation/endpoints/include/tcp_client_endpoint_impl.hpp @@ -31,8 +31,7 @@ public: void restart(); bool get_remote_address(boost::asio::ip::address &_address) const; - unsigned short get_local_port() const; - unsigned short get_remote_port() const; + std::uint16_t get_remote_port() const; bool is_reliable() const; bool is_local() const; @@ -50,6 +49,7 @@ private: const std::string get_address_port_remote() const; const std::string get_address_port_local() const; void handle_recv_buffer_exception(const std::exception &_e); + void set_local_port(); const std::uint32_t recv_buffer_size_initial_; diff --git a/implementation/endpoints/include/tcp_server_endpoint_impl.hpp b/implementation/endpoints/include/tcp_server_endpoint_impl.hpp index 179825e..1fd4052 100644 --- a/implementation/endpoints/include/tcp_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/tcp_server_endpoint_impl.hpp @@ -42,7 +42,7 @@ public: bool get_default_target(service_t, endpoint_type &) const; - unsigned short get_local_port() const; + std::uint16_t get_local_port() const; bool is_reliable() const; bool is_local() const; diff --git a/implementation/endpoints/include/udp_client_endpoint_impl.hpp b/implementation/endpoints/include/udp_client_endpoint_impl.hpp index 0734d47..9f3e9b0 100644 --- a/implementation/endpoints/include/udp_client_endpoint_impl.hpp +++ b/implementation/endpoints/include/udp_client_endpoint_impl.hpp @@ -37,16 +37,16 @@ public: void receive_cbk(boost::system::error_code const &_error, std::size_t _bytes); - + bool get_remote_address(boost::asio::ip::address &_address) const; - unsigned short get_local_port() const; - unsigned short get_remote_port() const; + std::uint16_t get_remote_port() const; bool is_local() const; private: void send_queued(); void connect(); void receive(); + void set_local_port(); message_buffer_t recv_buffer_; diff --git a/implementation/endpoints/include/udp_server_endpoint_impl.hpp b/implementation/endpoints/include/udp_server_endpoint_impl.hpp index 44bca0d..50b5dda 100644 --- a/implementation/endpoints/include/udp_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/udp_server_endpoint_impl.hpp @@ -44,7 +44,7 @@ public: void remove_default_target(service_t _service); bool get_default_target(service_t _service, endpoint_type &_target) const; - unsigned short get_local_port() const; + std::uint16_t get_local_port() const; bool is_local() const; client_t get_client(std::shared_ptr _endpoint); diff --git a/implementation/endpoints/include/virtual_server_endpoint_impl.hpp b/implementation/endpoints/include/virtual_server_endpoint_impl.hpp index 5e8c49e..e8b6258 100644 --- a/implementation/endpoints/include/virtual_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/virtual_server_endpoint_impl.hpp @@ -40,8 +40,8 @@ public: void remove_default_target(service_t _service); bool get_remote_address(boost::asio::ip::address &_address) const; - unsigned short get_local_port() const; - unsigned short get_remote_port() const; + std::uint16_t get_local_port() const; + std::uint16_t get_remote_port() const; bool is_reliable() const; bool is_local() const; diff --git a/implementation/endpoints/src/client_endpoint_impl.cpp b/implementation/endpoints/src/client_endpoint_impl.cpp index c051194..9744a22 100644 --- a/implementation/endpoints/src/client_endpoint_impl.cpp +++ b/implementation/endpoints/src/client_endpoint_impl.cpp @@ -37,7 +37,8 @@ client_endpoint_impl::client_endpoint_impl( connect_timeout_(VSOMEIP_DEFAULT_CONNECT_TIMEOUT), // TODO: use config variable is_connected_(false), packetizer_(std::make_shared()), - was_not_connected_(false) { + was_not_connected_(false), + local_port_(0) { } template @@ -209,7 +210,7 @@ void client_endpoint_impl::connect_cbk( connect_timer_.cancel(); } connect_timeout_ = VSOMEIP_DEFAULT_CONNECT_TIMEOUT; // TODO: use config variable - + set_local_port(); if (!is_connected_) { is_connected_ = true; its_host->on_connect(this->shared_from_this()); @@ -282,6 +283,7 @@ void client_endpoint_impl::shutdown_and_close_socket() { template void client_endpoint_impl::shutdown_and_close_socket_unlocked() { + local_port_ = 0; if (socket_->is_open()) { boost::system::error_code its_error; socket_->shutdown(Protocol::socket::shutdown_both, its_error); @@ -297,10 +299,15 @@ bool client_endpoint_impl::get_remote_address( } template -unsigned short client_endpoint_impl::get_remote_port() const { +std::uint16_t client_endpoint_impl::get_remote_port() const { return 0; } +template +std::uint16_t client_endpoint_impl::get_local_port() const { + return local_port_; +} + template void client_endpoint_impl::start_connect_timer() { std::lock_guard its_lock(connect_timer_mutex_); diff --git a/implementation/endpoints/src/endpoint_impl.cpp b/implementation/endpoints/src/endpoint_impl.cpp index 4e9d9aa..cf35a39 100644 --- a/implementation/endpoints/src/endpoint_impl.cpp +++ b/implementation/endpoints/src/endpoint_impl.cpp @@ -108,7 +108,7 @@ void endpoint_impl::remove_default_target(service_t) { } template -unsigned short endpoint_impl::get_local_port() const { +std::uint16_t endpoint_impl::get_local_port() const { return 0; } diff --git a/implementation/endpoints/src/local_client_endpoint_impl.cpp b/implementation/endpoints/src/local_client_endpoint_impl.cpp index 3238153..f6e1b5c 100644 --- a/implementation/endpoints/src/local_client_endpoint_impl.cpp +++ b/implementation/endpoints/src/local_client_endpoint_impl.cpp @@ -206,8 +206,12 @@ bool local_client_endpoint_impl::get_remote_address( return false; } -unsigned short local_client_endpoint_impl::get_remote_port() const { +std::uint16_t local_client_endpoint_impl::get_remote_port() const { return 0; } +void local_client_endpoint_impl::set_local_port() { + // local_port_ is set to zero in ctor of client_endpoint_impl -> do nothing +} + } // namespace vsomeip diff --git a/implementation/endpoints/src/tcp_client_endpoint_impl.cpp b/implementation/endpoints/src/tcp_client_endpoint_impl.cpp index a66ad26..f0a0e10 100644 --- a/implementation/endpoints/src/tcp_client_endpoint_impl.cpp +++ b/implementation/endpoints/src/tcp_client_endpoint_impl.cpp @@ -210,22 +210,21 @@ bool tcp_client_endpoint_impl::get_remote_address( return true; } -unsigned short tcp_client_endpoint_impl::get_local_port() const { +void tcp_client_endpoint_impl::set_local_port() { std::lock_guard its_lock(socket_mutex_); boost::system::error_code its_error; if (socket_->is_open()) { endpoint_type its_endpoint = socket_->local_endpoint(its_error); if (!its_error) { - return its_endpoint.port(); + local_port_ = its_endpoint.port(); } else { - VSOMEIP_WARNING << "tcp_client_endpoint_impl::get_local_port() " + VSOMEIP_WARNING << "tcp_client_endpoint_impl::set_local_port() " << " couldn't get local_endpoint: " << its_error.message(); } } - return 0; } -unsigned short tcp_client_endpoint_impl::get_remote_port() const { +std::uint16_t tcp_client_endpoint_impl::get_remote_port() const { return remote_port_; } diff --git a/implementation/endpoints/src/tcp_server_endpoint_impl.cpp b/implementation/endpoints/src/tcp_server_endpoint_impl.cpp index 3f4e548..8e643c1 100644 --- a/implementation/endpoints/src/tcp_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/tcp_server_endpoint_impl.cpp @@ -185,7 +185,7 @@ void tcp_server_endpoint_impl::accept_cbk(connection::ptr _connection, } } -unsigned short tcp_server_endpoint_impl::get_local_port() const { +std::uint16_t tcp_server_endpoint_impl::get_local_port() const { return local_port_; } diff --git a/implementation/endpoints/src/udp_client_endpoint_impl.cpp b/implementation/endpoints/src/udp_client_endpoint_impl.cpp index cd51f47..1d28b98 100644 --- a/implementation/endpoints/src/udp_client_endpoint_impl.cpp +++ b/implementation/endpoints/src/udp_client_endpoint_impl.cpp @@ -143,22 +143,21 @@ bool udp_client_endpoint_impl::get_remote_address( return true; } -unsigned short udp_client_endpoint_impl::get_local_port() const { +void udp_client_endpoint_impl::set_local_port() { std::lock_guard its_lock(socket_mutex_); boost::system::error_code its_error; if (socket_->is_open()) { endpoint_type its_endpoint = socket_->local_endpoint(its_error); if (!its_error) { - return its_endpoint.port(); + local_port_ = its_endpoint.port(); } else { - VSOMEIP_WARNING << "udp_client_endpoint_impl::get_local_port() " + VSOMEIP_WARNING << "udp_client_endpoint_impl::set_local_port() " << " couldn't get local_endpoint: " << its_error.message(); } } - return 0; } -unsigned short udp_client_endpoint_impl::get_remote_port() const { +std::uint16_t udp_client_endpoint_impl::get_remote_port() const { return remote_port_; } diff --git a/implementation/endpoints/src/udp_server_endpoint_impl.cpp b/implementation/endpoints/src/udp_server_endpoint_impl.cpp index 3bc5938..e21f107 100644 --- a/implementation/endpoints/src/udp_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/udp_server_endpoint_impl.cpp @@ -258,7 +258,7 @@ bool udp_server_endpoint_impl::get_default_target(service_t _service, return is_valid; } -unsigned short udp_server_endpoint_impl::get_local_port() const { +std::uint16_t udp_server_endpoint_impl::get_local_port() const { return local_port_; } diff --git a/implementation/endpoints/src/virtual_server_endpoint_impl.cpp b/implementation/endpoints/src/virtual_server_endpoint_impl.cpp index 6f20929..6db9bc1 100644 --- a/implementation/endpoints/src/virtual_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/virtual_server_endpoint_impl.cpp @@ -79,11 +79,11 @@ bool virtual_server_endpoint_impl::get_remote_address( return false; } -unsigned short virtual_server_endpoint_impl::get_local_port() const { +std::uint16_t virtual_server_endpoint_impl::get_local_port() const { return port_; } -unsigned short virtual_server_endpoint_impl::get_remote_port() const { +std::uint16_t virtual_server_endpoint_impl::get_remote_port() const { return ILLEGAL_PORT; } diff --git a/implementation/routing/include/routing_manager_impl.hpp b/implementation/routing/include/routing_manager_impl.hpp index 0150d15..4b8d78a 100644 --- a/implementation/routing/include/routing_manager_impl.hpp +++ b/implementation/routing/include/routing_manager_impl.hpp @@ -226,7 +226,7 @@ private: std::shared_ptr create_client_endpoint( const boost::asio::ip::address &_address, uint16_t _local_port, uint16_t _remote_port, - bool _reliable, client_t _client, bool _start); + bool _reliable, client_t _client); std::shared_ptr create_server_endpoint(uint16_t _port, bool _reliable, bool _start); @@ -248,7 +248,6 @@ private: const byte_t *_data, length_t _size, endpoint *_receiver); void clear_client_endpoints(service_t _service, instance_t _instance, bool _reliable); - void stop_and_delete_client_endpoint(std::shared_ptr _endpoint); void clear_multicast_endpoints(service_t _service, instance_t _instance); bool is_identifying(client_t _client, service_t _service, diff --git a/implementation/routing/src/routing_manager_impl.cpp b/implementation/routing/src/routing_manager_impl.cpp index a66d273..1c48ca3 100644 --- a/implementation/routing/src/routing_manager_impl.cpp +++ b/implementation/routing/src/routing_manager_impl.cpp @@ -1508,11 +1508,19 @@ services_t routing_manager_impl::get_offered_services() const { std::shared_ptr routing_manager_impl::find_or_create_remote_client( service_t _service, instance_t _instance, bool _reliable, client_t _client) { - std::lock_guard its_lock(endpoint_mutex_); - std::shared_ptr its_endpoint = find_remote_client(_service, _instance, - _reliable, _client); - if (!its_endpoint) { - its_endpoint = create_remote_client(_service, _instance, _reliable, _client); + std::shared_ptr its_endpoint; + bool start_endpoint(false); + { + std::lock_guard its_lock(endpoint_mutex_); + its_endpoint = find_remote_client(_service, _instance, _reliable, _client); + if (!its_endpoint) { + its_endpoint = create_remote_client(_service, _instance, _reliable, _client); + start_endpoint = true; + } + } + if (start_endpoint && its_endpoint + && configuration_->is_someip(_service, _instance)) { + its_endpoint->start(); } return its_endpoint; } @@ -1583,7 +1591,7 @@ void routing_manager_impl::init_service_info( std::shared_ptr routing_manager_impl::create_client_endpoint( const boost::asio::ip::address &_address, uint16_t _local_port, uint16_t _remote_port, - bool _reliable, client_t _client, bool _start) { + bool _reliable, client_t _client) { (void)_client; std::shared_ptr its_endpoint; @@ -1617,8 +1625,6 @@ std::shared_ptr routing_manager_impl::create_client_endpoint( boost::asio::ip::udp::endpoint(_address, _remote_port), io_); } - if (_start) - its_endpoint->start(); } catch (...) { host_->on_error(error_code_e::CLIENT_ENDPOINT_CREATION_FAILED); } @@ -1757,8 +1763,7 @@ std::shared_ptr routing_manager_impl::create_remote_client( its_endpoint_def->get_address(), its_local_port, its_endpoint_def->get_port(), - _reliable, _client, - configuration_->is_someip(_service, _instance) + _reliable, _client ); } } @@ -2642,16 +2647,18 @@ bool routing_manager_impl::deliver_specific_endpoint_message(service_t _service, void routing_manager_impl::clear_client_endpoints(service_t _service, instance_t _instance, bool _reliable) { auto its_specific_endpoint_clients = get_specific_endpoint_clients(_service, _instance); + std::shared_ptr endpoint_to_delete; + bool other_services_reachable_through_endpoint(false); + std::vector> its_specific_endpoints; { std::lock_guard its_lock(endpoint_mutex_); - std::shared_ptr deleted_endpoint; // Clear client endpoints for remote services (generic and specific ones) if (remote_services_.find(_service) != remote_services_.end()) { if (remote_services_[_service].find(_instance) != remote_services_[_service].end()) { auto endpoint = remote_services_[_service][_instance][VSOMEIP_ROUTING_CLIENT][_reliable]; if (endpoint) { service_instances_[_service].erase(endpoint.get()); - deleted_endpoint = endpoint; + endpoint_to_delete = endpoint; } remote_services_[_service][_instance][VSOMEIP_ROUTING_CLIENT].erase(_reliable); auto found_endpoint = remote_services_[_service][_instance][VSOMEIP_ROUTING_CLIENT].find( @@ -2664,7 +2671,7 @@ void routing_manager_impl::clear_client_endpoints(service_t _service, instance_t auto endpoint = remote_services_[_service][_instance][client][_reliable]; if (endpoint) { service_instances_[_service].erase(endpoint.get()); - endpoint->stop(); + its_specific_endpoints.push_back(endpoint); } remote_services_[_service][_instance][client].erase(_reliable); auto found_endpoint = remote_services_[_service][_instance][client].find(!_reliable); @@ -2688,62 +2695,72 @@ void routing_manager_impl::clear_client_endpoints(service_t _service, instance_t if (!service_instances_[_service].size()) { service_instances_.erase(_service); } - if(deleted_endpoint) { - stop_and_delete_client_endpoint(deleted_endpoint); - } - } -} -void routing_manager_impl::stop_and_delete_client_endpoint( - std::shared_ptr _endpoint) { - // Only stop and delete the endpoint if none of the services - // reachable through it is online anymore. - bool delete_endpoint(true); - - for (const auto& service : remote_services_) { - for (const auto& instance : service.second) { - const auto& client = instance.second.find(VSOMEIP_ROUTING_CLIENT); - if(client != instance.second.end()) { - for (const auto& reliable : client->second) { - if(reliable.second == _endpoint) { - delete_endpoint = false; - break; + // Only stop and delete the endpoint if none of the services + // reachable through it is online anymore. + if (endpoint_to_delete) { + for (const auto& service : remote_services_) { + for (const auto& instance : service.second) { + const auto& client = instance.second.find(VSOMEIP_ROUTING_CLIENT); + if (client != instance.second.end()) { + for (const auto& reliable : client->second) { + if (reliable.second == endpoint_to_delete) { + other_services_reachable_through_endpoint = true; + break; + } + } } + if (other_services_reachable_through_endpoint) { break; } } + if (other_services_reachable_through_endpoint) { break; } } - if(!delete_endpoint) { break; } - } - if(!delete_endpoint) { break; } - } - if(delete_endpoint) { - _endpoint->stop(); - for (auto address = client_endpoints_by_ip_.begin(); - address != client_endpoints_by_ip_.end();) { - for (auto port = address->second.begin(); - port != address->second.end();) { - for (auto reliable = port->second.begin(); - reliable != port->second.end();) { - std::shared_ptr its_endpoint = reliable->second; - if (_endpoint == its_endpoint) { - reliable = port->second.erase(reliable); - } else { - ++reliable; + if (!other_services_reachable_through_endpoint) { + std::uint16_t its_port(0); + boost::asio::ip::address its_address; + if (_reliable) { + std::shared_ptr ep = + std::dynamic_pointer_cast(endpoint_to_delete); + if (ep) { + its_port = ep->get_remote_port(); + ep->get_remote_address(its_address); } - } - if (!port->second.size()) { - port = address->second.erase(port); } else { - ++port; + std::shared_ptr ep = + std::dynamic_pointer_cast(endpoint_to_delete); + if (ep) { + its_port = ep->get_remote_port(); + ep->get_remote_address(its_address); + } + } + const auto found_ip = client_endpoints_by_ip_.find(its_address); + if (found_ip != client_endpoints_by_ip_.end()) { + const auto found_port = found_ip->second.find(its_port); + if (found_port != found_ip->second.end()) { + const auto found_reliable = found_port->second.find(_reliable); + if (found_reliable != found_port->second.end()) { + if (found_reliable->second == endpoint_to_delete) { + found_port->second.erase(_reliable); + // delete if necessary + if (!found_port->second.size()) { + found_ip->second.erase(found_port); + if (!found_ip->second.size()) { + client_endpoints_by_ip_.erase(found_ip); + } + } + } + } + } } - } - if(!address->second.size()) { - address = client_endpoints_by_ip_.erase(address); - } else { - ++address; } } } + if (!other_services_reachable_through_endpoint && endpoint_to_delete) { + endpoint_to_delete->stop(); + } + for (const auto &specific_endpoint : its_specific_endpoints) { + specific_endpoint->stop(); + } } void routing_manager_impl::clear_multicast_endpoints(service_t _service, instance_t _instance) { diff --git a/implementation/service_discovery/include/service_discovery_impl.hpp b/implementation/service_discovery/include/service_discovery_impl.hpp index b7be7ff..bc3a842 100644 --- a/implementation/service_discovery/include/service_discovery_impl.hpp +++ b/implementation/service_discovery/include/service_discovery_impl.hpp @@ -311,6 +311,7 @@ private: std::weak_ptr runtime_; // TTL handling for services offered by other hosts + std::mutex ttl_timer_mutex_; boost::asio::steady_timer ttl_timer_; std::chrono::milliseconds smallest_ttl_; ttl_t ttl_; diff --git a/implementation/service_discovery/src/service_discovery_impl.cpp b/implementation/service_discovery/src/service_discovery_impl.cpp index e8937ed..b6a45b6 100644 --- a/implementation/service_discovery/src/service_discovery_impl.cpp +++ b/implementation/service_discovery/src/service_discovery_impl.cpp @@ -875,6 +875,12 @@ void service_discovery_impl::insert_subscription( const std::uint16_t its_port = its_endpoint->get_local_port(); if (its_port) { insert_option(_message, its_entry, unicast_, its_port, true); + } else { + VSOMEIP_WARNING << __func__ << ": Didn't insert subscription as " + "local reliable port is zero: [" + << std::hex << std::setw(4) << std::setfill('0') << _service << "." + << std::hex << std::setw(4) << std::setfill('0') << _instance << "." + << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "]"; } } } @@ -884,6 +890,12 @@ void service_discovery_impl::insert_subscription( const std::uint16_t its_port = its_endpoint->get_local_port(); if (its_port) { insert_option(_message, its_entry, unicast_, its_port, false); + } else { + VSOMEIP_WARNING << __func__ << ": Didn't insert subscription as " + " local unreliable port is zero: [" + << std::hex << std::setw(4) << std::setfill('0') << _service << "." + << std::hex << std::setw(4) << std::setfill('0') << _instance << "." + << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "]"; } } } @@ -925,6 +937,12 @@ void service_discovery_impl::insert_nack_subscription_on_resubscribe(std::shared if (its_port) { insert_option(_message, its_stop_entry, unicast_, its_port, true); insert_option(_message, its_entry, unicast_, its_port, true); + } else { + VSOMEIP_WARNING << __func__ << ": Didn't insert subscription as " + "local reliable port is zero: [" + << std::hex << std::setw(4) << std::setfill('0') << _service << "." + << std::hex << std::setw(4) << std::setfill('0') << _instance << "." + << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "]"; } } its_endpoint = _subscription->get_endpoint(false); @@ -933,6 +951,12 @@ void service_discovery_impl::insert_nack_subscription_on_resubscribe(std::shared if (its_port) { insert_option(_message, its_stop_entry, unicast_, its_port, false); insert_option(_message, its_entry, unicast_, its_port, false); + } else { + VSOMEIP_WARNING << __func__ << ": Didn't insert subscription as " + "local unreliable port is zero: [" + << std::hex << std::setw(4) << std::setfill('0') << _service << "." + << std::hex << std::setw(4) << std::setfill('0') << _instance << "." + << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "]"; } } } @@ -2123,6 +2147,7 @@ void service_discovery_impl::serialize_and_send( } void service_discovery_impl::start_ttl_timer() { + std::lock_guard its_lock(ttl_timer_mutex_); ttl_timer_.expires_from_now(std::chrono::milliseconds(smallest_ttl_)); ttl_timer_.async_wait( std::bind(&service_discovery_impl::check_ttl, shared_from_this(), @@ -2130,6 +2155,7 @@ void service_discovery_impl::start_ttl_timer() { } std::chrono::milliseconds service_discovery_impl::stop_ttl_timer() { + std::lock_guard its_lock(ttl_timer_mutex_); std::chrono::milliseconds remaining = std::chrono::duration_cast< std::chrono::milliseconds >(ttl_timer_.expires_from_now()); -- cgit v1.2.1