From 6558f0ad4212f407d72b7336b14542c7d73f8432 Mon Sep 17 00:00:00 2001 From: Jari Sundell Date: Mon, 29 Jun 2026 09:18:56 +0200 Subject: [PATCH] Fixed shutdown handling of stalled http requests. --- src/control.cc | 29 ++++++++++++++++++++++++----- src/control.h | 18 ++++++++++++------ src/core/manager.cc | 5 +++-- 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/src/control.cc b/src/control.cc index c747d999..a76bafb7 100644 --- a/src/control.cc +++ b/src/control.cc @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "core/dht_manager.h" @@ -46,7 +47,8 @@ Control::Control() m_inputStdin->slot_pressed(std::bind(&input::Manager::pressed, m_input.get(), std::placeholders::_1)); - m_task_shutdown.slot() = std::bind(&Control::handle_shutdown, this); + m_task_shutdown.slot() = [this] { handle_shutdown(); }; + m_task_shutdown_clear_requests.slot() = [this] { handle_shutdown_clear_requests(); }; m_commandScheduler->set_slot_error_message([this](const std::string& msg) { m_core->push_log_std(msg); }); } @@ -84,6 +86,7 @@ Control::cleanup() { rpc::rpc.cleanup(); torrent::this_thread::scheduler()->erase(&m_task_shutdown); + torrent::this_thread::scheduler()->erase(&m_task_shutdown_clear_requests); if(!display::Canvas::daemon()) m_inputStdin->remove(); @@ -113,7 +116,7 @@ Control::cleanup_exception() { bool Control::is_shutdown_completed() { - if (!m_shutdownQuick) + if (!m_shutdown_quick) return false; // Tracker requests can be disowned, so wait for these to @@ -137,8 +140,9 @@ Control::handle_shutdown() { if (scgi_thread::thread()->is_active()) scgi_thread::thread()->stop_thread_wait(); - if (!m_shutdownQuick) { + if (!m_shutdown_quick) { torrent::runtime::network_manager()->listen_close(); + torrent::runtime::shutdown(); m_directory_events->close(); m_core->shutdown(false); @@ -147,9 +151,24 @@ Control::handle_shutdown() { torrent::this_thread::scheduler()->wait_for_ceil_seconds(&m_task_shutdown, 5s); } else { + torrent::runtime::quick_shutdown(); m_core->shutdown(true); } - m_shutdownQuick = true; - m_shutdownReceived = false; + if (!m_task_shutdown_clear_requests.is_scheduled()) + torrent::this_thread::scheduler()->wait_for_ceil_seconds(&m_task_shutdown_clear_requests, 10s); + + m_shutdown_quick = true; + m_shutdown_received = false; +} + +void +Control::handle_shutdown_clear_requests() { + torrent::net_thread::http_stack()->clear_requests(); + + // Use 5s for the initial wait to ensure trackers get a chance to finish both IPv4 and IPv6 requests. + if (m_clear_requests_count++ == 0) + torrent::this_thread::scheduler()->wait_for(&m_task_shutdown_clear_requests, 5s); + else + torrent::this_thread::scheduler()->wait_for(&m_task_shutdown_clear_requests, 1s); } diff --git a/src/control.h b/src/control.h index 69ae6a49..397c996e 100644 --- a/src/control.h +++ b/src/control.h @@ -48,17 +48,18 @@ public: ~Control(); bool is_shutdown_completed(); - bool is_shutdown_received() { return m_shutdownReceived; } - bool is_shutdown_started() { return m_shutdownQuick; } + bool is_shutdown_received() { return m_shutdown_received; } + bool is_shutdown_started() { return m_shutdown_quick; } void initialize(); void cleanup(); void cleanup_exception(); void handle_shutdown(); + void handle_shutdown_clear_requests(); - void receive_normal_shutdown() { m_shutdownReceived = true; } - void receive_quick_shutdown() { m_shutdownReceived = true; m_shutdownQuick = true; } + void receive_normal_shutdown() { m_shutdown_received = true; } + void receive_quick_shutdown() { m_shutdown_received = true; m_shutdown_quick = true; } core::Manager* core() { return m_core.get(); } core::ViewManager* view_manager() { return m_view_manager.get(); } @@ -107,9 +108,14 @@ private: std::string m_workingDirectory; torrent::utils::SchedulerEntry m_task_shutdown; + torrent::utils::SchedulerEntry m_task_shutdown_clear_requests; - std::atomic m_shutdownReceived{}; - std::atomic m_shutdownQuick{}; + int m_clear_requests_count{}; + + align_cacheline + + std::atomic m_shutdown_received{}; + std::atomic m_shutdown_quick{}; }; #endif diff --git a/src/core/manager.cc b/src/core/manager.cc index 3228699f..f756093c 100644 --- a/src/core/manager.cc +++ b/src/core/manager.cc @@ -151,12 +151,13 @@ Manager::cleanup() { void Manager::shutdown(bool force) { - if (!force) + if (!force) { for (auto d : *m_download_list) m_download_list->pause_default(d); - else + } else { for (auto d : *m_download_list) m_download_list->close_quick(d); + } } void