Add a timeout to scgi tasks.

A hundred connections sending a partial header held the whole task pool.
This commit is contained in:
xirvik
2026-08-17 15:31:20 +00:00
committed by Jari Sundell
parent 9066afc063
commit af6d8a10ad
2 changed files with 18 additions and 2 deletions
+11
View File
@@ -14,6 +14,7 @@
#include <torrent/runtime/socket_manager.h> #include <torrent/runtime/socket_manager.h>
#include <torrent/system/callbacks.h> #include <torrent/system/callbacks.h>
#include <torrent/system/poll.h> #include <torrent/system/poll.h>
#include <torrent/system/scheduler.h>
#include <torrent/utils/log.h> #include <torrent/utils/log.h>
#include "control.h" #include "control.h"
@@ -27,6 +28,8 @@ namespace rpc {
SCgiTask::SCgiTask() SCgiTask::SCgiTask()
: m_callback_id(torrent::system::make_callback_id()) { : m_callback_id(torrent::system::make_callback_id()) {
m_task_timeout.slot() = [this]() { close(); };
reset_file_descriptor(); reset_file_descriptor();
} }
@@ -50,6 +53,8 @@ SCgiTask::open(SCgi* parent, int fd) {
torrent::this_thread::poll()->open(this); torrent::this_thread::poll()->open(this);
torrent::this_thread::poll()->insert_read(this); torrent::this_thread::poll()->insert_read(this);
torrent::this_thread::scheduler()->update_wait_for_ceil_seconds(&m_task_timeout, timeout_request);
auto lock = std::lock_guard<std::mutex>(m_result_mutex); auto lock = std::lock_guard<std::mutex>(m_result_mutex);
// Leave room for terminating nul byte for parsing the header. // Leave room for terminating nul byte for parsing the header.
@@ -61,6 +66,8 @@ SCgiTask::cancel_open() {
if (!is_open()) if (!is_open())
return; return;
torrent::this_thread::scheduler()->erase(&m_task_timeout);
torrent::this_thread::poll()->remove_and_close(this); torrent::this_thread::poll()->remove_and_close(this);
torrent::fd_close(file_descriptor()); torrent::fd_close(file_descriptor());
@@ -72,6 +79,8 @@ SCgiTask::close() {
if (!is_open()) if (!is_open())
return; return;
torrent::this_thread::scheduler()->erase(&m_task_timeout);
torrent::system::cancel_callback_and_wait(m_callback_id, scgi_thread::thread(), torrent::main_thread::thread()); torrent::system::cancel_callback_and_wait(m_callback_id, scgi_thread::thread(), torrent::main_thread::thread());
torrent::runtime::socket_manager()->close_event_or_throw(this, [this]() { torrent::runtime::socket_manager()->close_event_or_throw(this, [this]() {
@@ -158,6 +167,8 @@ SCgiTask::event_read() {
torrent::this_thread::poll()->remove_read(this); torrent::this_thread::poll()->remove_read(this);
torrent::this_thread::scheduler()->update_wait_for_ceil_seconds(&m_task_timeout, timeout_request);
if (m_parent->log_fd() >= 0) { if (m_parent->log_fd() >= 0) {
[[maybe_unused]] int result; [[maybe_unused]] int result;
+5
View File
@@ -1,10 +1,12 @@
#ifndef RTORRENT_RPC_SCGI_TASK_H #ifndef RTORRENT_RPC_SCGI_TASK_H
#define RTORRENT_RPC_SCGI_TASK_H #define RTORRENT_RPC_SCGI_TASK_H
#include <chrono>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <vector> #include <vector>
#include <torrent/system/event.h> #include <torrent/system/event.h>
#include <torrent/system/scheduler.h>
namespace rpc { namespace rpc {
@@ -16,6 +18,8 @@ public:
static constexpr int max_header_size = 2000; static constexpr int max_header_size = 2000;
static constexpr int max_content_size = (2 << 23); static constexpr int max_content_size = (2 << 23);
static constexpr auto timeout_request = std::chrono::seconds(60);
enum ContentType { XML, JSON }; enum ContentType { XML, JSON };
SCgiTask(); SCgiTask();
@@ -56,6 +60,7 @@ private:
SCgi* m_parent{}; SCgi* m_parent{};
torrent::system::callback_id m_callback_id; torrent::system::callback_id m_callback_id;
torrent::system::SchedulerEntry m_task_timeout;
std::mutex m_result_mutex; std::mutex m_result_mutex;