mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-10-19 15:46:17 +00:00
Add a timeout to scgi tasks.
A hundred connections sending a partial header held the whole task pool.
This commit is contained in:
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user