| 534 | } |
| 535 | |
| 536 | void application_impl::stop() { |
| 537 | std::scoped_lock its_lock_start_stop{start_stop_mutex_}; |
| 538 | |
| 539 | VSOMEIP_INFO_P << "Stopping vsomeip application \"" << name_ << "\" (" << hex4(client_) << ")."; |
| 540 | |
| 541 | if (stopping_) { |
| 542 | VSOMEIP_WARNING_P << "Trying to stop an application that is already stopped, stopping_ = " << stopping_; |
| 543 | return; |
| 544 | } |
| 545 | |
| 546 | stopping_ = true; |
| 547 | stop_caller_id_ = std::this_thread::get_id(); |
| 548 | |
| 549 | // no need to pass a `shared_ptr`, because by definition the app must be alive if an io thread is still executing! |
| 550 | boost::asio::post(io_, [this]() { |
| 551 | // NOTE: quite a few assumptions baked here: |
| 552 | // 1) if the application did not yet start, it will, and it will start, then stop due to this handler |
| 553 | // 2) handler executes necessarily after `io.run()`, therefore after routing and dispatching starts |
| 554 | |
| 555 | auto its_plugins = configuration_->get_plugins(name_); |
| 556 | auto its_app_plugin_info = its_plugins.find(plugin_type_e::APPLICATION_PLUGIN); |
| 557 | if (its_app_plugin_info != its_plugins.end()) { |
| 558 | for (const auto& its_library : its_app_plugin_info->second) { |
| 559 | auto its_application_plugin = plugin_manager_->get_plugin(plugin_type_e::APPLICATION_PLUGIN, its_library); |
| 560 | if (its_application_plugin) { |
| 561 | std::dynamic_pointer_cast<application_plugin>(its_application_plugin) |
| 562 | ->on_application_state_change(name_, application_plugin_state_e::STATE_STOPPED); |
| 563 | } |
| 564 | } |
| 565 | } |
| 566 | |
| 567 | { |
| 568 | std::scoped_lock its_handler_lock{handlers_mutex_}; |
| 569 | is_dispatching_ = false; |
| 570 | dispatcher_condition_.notify_all(); |
| 571 | } |
| 572 | |
| 573 | if (routing_) { |
| 574 | routing_->stop(); |
| 575 | } |
| 576 | { |
| 577 | // no new handlers can be invoked as the routing_->stop ensures |
| 578 | // no io thread is pushing any task into the queue |
| 579 | // -> now we can clear all pending tasks |
| 580 | std::scoped_lock its_handler_lock{handlers_mutex_}; |
| 581 | subscription_handlers_.clear(); |
| 582 | } |
| 583 | if (routing_app_) { |
| 584 | routing_app_->stop(); |
| 585 | } |
| 586 | |
| 587 | io_.stop(); |
| 588 | }); |
| 589 | } |
| 590 | |
| 591 | void application_impl::process(int _number) { |
| 592 | (void)_number; |
nothing calls this directly
no test coverage detected