| 2407 | } |
| 2408 | |
| 2409 | void routing_manager_client::cleanup_subscriber(std::scoped_lock<std::mutex> const& _provider_lock) { |
| 2410 | // Tracks unique (service, instance, eventgroup, client) tuples for which |
| 2411 | // the user notification and table invalidation must fire exactly once. |
| 2412 | struct sub_tuple { |
| 2413 | service_t service; |
| 2414 | instance_t instance; |
| 2415 | eventgroup_t eventgroup; |
| 2416 | client_t client; |
| 2417 | auto operator<=>(const sub_tuple&) const = default; |
| 2418 | }; |
| 2419 | std::set<sub_tuple> unique_tuples; |
| 2420 | |
| 2421 | for (auto const& [si, evs] : provided_events_) { |
| 2422 | auto const service = si.service(); |
| 2423 | auto const instance = si.instance(); |
| 2424 | for (auto const& [event_id, event] : evs) { |
| 2425 | for (auto const group : event->get_eventgroups()) { |
| 2426 | for (auto const client : event->get_subscribers(group)) { |
| 2427 | // Per-event routing state mutation — fine to call once per event. |
| 2428 | unsubscribe_base(client, service, instance, group, event_id, _provider_lock); |
| 2429 | unique_tuples.insert({service, instance, group, client}); |
| 2430 | } |
| 2431 | } |
| 2432 | } |
| 2433 | } |
| 2434 | |
| 2435 | // Per unique (svc, inst, group, client): invalidate all table entries |
| 2436 | // (ANY_EVENT expansion covers both ANY_EVENT and specific-event subscriptions) |
| 2437 | // and notify the user exactly once. |
| 2438 | for (auto const& [service, instance, group, client] : unique_tuples) { |
| 2439 | auto ep = ep_mgr_->find_local_server_endpoint(client); |
| 2440 | auto const env = ep ? ep->get_env() : ""; |
| 2441 | auto const sec = ep ? ep->get_sec_client() : vsomeip_sec_client_t{}; |
| 2442 | VSOMEIP_INFO << "UNSUBSCRIBE(" << hex4(client) << "): [" << hex4(service) << "." << hex4(instance) << "." << hex4(group) << "." |
| 2443 | << hex4(ANY_EVENT) << "]"; |
| 2444 | host_->on_subscription(service, instance, group, client, &sec, env, false, [](bool) { |
| 2445 | // no need to execute anything, as the endpoint token is invalidated as well |
| 2446 | }); |
| 2447 | } |
| 2448 | } |
| 2449 | |
| 2450 | client_t routing_manager_client::get_client_by_address(const boost::asio::ip::address& _address, port_t _port) const { |
| 2451 | std::scoped_lock lock{consumer_mutex_}; |
nothing calls this directly
no test coverage detected