mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-10-23 01:26:19 +00:00
Replace ThreadWorker with scgi::ThreadScgi.
This commit is contained in:
+4
-3
@@ -125,6 +125,9 @@ libsub_root_a_SOURCES = \
|
|||||||
rpc/tinyxml2/tinyxml2.cc \
|
rpc/tinyxml2/tinyxml2.cc \
|
||||||
rpc/nlohmann/json.h \
|
rpc/nlohmann/json.h \
|
||||||
\
|
\
|
||||||
|
scgi/thread_scgi.cc \
|
||||||
|
scgi/thread_scgi.h \
|
||||||
|
\
|
||||||
session/session_manager.cc \
|
session/session_manager.cc \
|
||||||
session/session_manager.h \
|
session/session_manager.h \
|
||||||
session/thread_session.cc \
|
session/thread_session.cc \
|
||||||
@@ -195,9 +198,7 @@ libsub_root_a_SOURCES = \
|
|||||||
option_parser.cc \
|
option_parser.cc \
|
||||||
option_parser.h \
|
option_parser.h \
|
||||||
signal_handler.cc \
|
signal_handler.cc \
|
||||||
signal_handler.h \
|
signal_handler.h
|
||||||
thread_worker.cc \
|
|
||||||
thread_worker.h
|
|
||||||
|
|
||||||
|
|
||||||
AM_CPPFLAGS = -I$(srcdir) -I$(top_srcdir) -DPACKAGE_DATADIR=\"$(pkgdatadir)\"
|
AM_CPPFLAGS = -I$(srcdir) -I$(top_srcdir) -DPACKAGE_DATADIR=\"$(pkgdatadir)\"
|
||||||
|
|||||||
@@ -185,7 +185,6 @@ cmd_file_append(const torrent::Object::list_type& args) {
|
|||||||
void
|
void
|
||||||
initialize_command_local() {
|
initialize_command_local() {
|
||||||
core::DownloadList* dList = control->core()->download_list();
|
core::DownloadList* dList = control->core()->download_list();
|
||||||
core::DownloadStore* dStore = control->core()->download_store();
|
|
||||||
torrent::ChunkManager* chunkManager = torrent::chunk_manager();
|
torrent::ChunkManager* chunkManager = torrent::chunk_manager();
|
||||||
torrent::FileManager* fileManager = torrent::file_manager();
|
torrent::FileManager* fileManager = torrent::file_manager();
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include "command_helpers.h"
|
#include "command_helpers.h"
|
||||||
#include "thread_worker.h"
|
|
||||||
#include "core/download.h"
|
#include "core/download.h"
|
||||||
#include "core/download_list.h"
|
#include "core/download_list.h"
|
||||||
#include "core/manager.h"
|
#include "core/manager.h"
|
||||||
@@ -135,12 +134,13 @@ initialize_command_logging() {
|
|||||||
CMD2_ANY_LIST ("log.append_file", std::bind(&apply_log_open, log_flag_append_file, std::placeholders::_2));
|
CMD2_ANY_LIST ("log.append_file", std::bind(&apply_log_open, log_flag_append_file, std::placeholders::_2));
|
||||||
CMD2_ANY_LIST ("log.append_gz_file", std::bind(&apply_log_open, log_flag_append_file, std::placeholders::_2));
|
CMD2_ANY_LIST ("log.append_gz_file", std::bind(&apply_log_open, log_flag_append_file, std::placeholders::_2));
|
||||||
|
|
||||||
CMD2_ANY_STRING_V("log.close", std::bind(&torrent::log_close_output_str, std::placeholders::_2));
|
CMD2_ANY_STRING_V("log.close", std::bind(&torrent::log_close_output_str, std::placeholders::_2));
|
||||||
|
|
||||||
CMD2_ANY_LIST ("log.add_output", std::bind(&apply_log_add_output, std::placeholders::_2));
|
CMD2_ANY_LIST ("log.add_output", std::bind(&apply_log_add_output, std::placeholders::_2));
|
||||||
|
|
||||||
CMD2_ANY_STRING ("log.execute", std::bind(&apply_log, std::placeholders::_2, 0));
|
CMD2_ANY_STRING ("log.execute", std::bind(&apply_log, std::placeholders::_2, 0));
|
||||||
CMD2_ANY_STRING ("log.vmmap.dump", std::bind(&log_vmmap_dump, std::placeholders::_2));
|
CMD2_ANY_STRING ("log.vmmap.dump", std::bind(&log_vmmap_dump, std::placeholders::_2));
|
||||||
CMD2_ANY_STRING_V("log.rpc", std::bind(&ThreadWorker::set_rpc_log, worker_thread, std::placeholders::_2));
|
CMD2_ANY_STRING_V("log.rpc", [](const auto&, const auto& str) { scgi_thread::set_rpc_log(str); });
|
||||||
CMD2_REDIRECT ("log.xmlrpc", "log.rpc"); // For backwards compatibility
|
|
||||||
|
CMD2_REDIRECT ("log.xmlrpc", "log.rpc"); // For backwards compatibility
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include "command_helpers.h"
|
#include "command_helpers.h"
|
||||||
#include "thread_worker.h"
|
|
||||||
#include "core/download.h"
|
#include "core/download.h"
|
||||||
#include "core/manager.h"
|
#include "core/manager.h"
|
||||||
#include "rpc/scgi.h"
|
#include "rpc/scgi.h"
|
||||||
@@ -79,7 +78,7 @@ initialize_rpc_handlers() {
|
|||||||
|
|
||||||
torrent::Object
|
torrent::Object
|
||||||
apply_scgi(const std::string& arg, int type) {
|
apply_scgi(const std::string& arg, int type) {
|
||||||
if (worker_thread->scgi() != NULL)
|
if (scgi_thread::scgi() != nullptr)
|
||||||
throw torrent::input_error("SCGI already enabled.");
|
throw torrent::input_error("SCGI already enabled.");
|
||||||
|
|
||||||
initialize_rpc_handlers();
|
initialize_rpc_handlers();
|
||||||
@@ -142,7 +141,7 @@ apply_scgi(const std::string& arg, int type) {
|
|||||||
throw torrent::input_error(e.what());
|
throw torrent::input_error(e.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
worker_thread->set_scgi(scgi);
|
scgi_thread::set_scgi(scgi);
|
||||||
return torrent::Object();
|
return torrent::Object();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-9
@@ -8,7 +8,6 @@
|
|||||||
#include <torrent/net/network_manager.h>
|
#include <torrent/net/network_manager.h>
|
||||||
#include <torrent/utils/directory_events.h>
|
#include <torrent/utils/directory_events.h>
|
||||||
|
|
||||||
#include "thread_worker.h"
|
|
||||||
#include "core/dht_manager.h"
|
#include "core/dht_manager.h"
|
||||||
#include "core/download_store.h"
|
#include "core/download_store.h"
|
||||||
#include "core/http_queue.h"
|
#include "core/http_queue.h"
|
||||||
@@ -63,7 +62,7 @@ Control::initialize() {
|
|||||||
session_thread::manager()->start();
|
session_thread::manager()->start();
|
||||||
session_thread::thread()->start_thread();
|
session_thread::thread()->start_thread();
|
||||||
|
|
||||||
worker_thread->start_thread();
|
scgi_thread::thread()->start_thread();
|
||||||
|
|
||||||
display::Canvas::initialize();
|
display::Canvas::initialize();
|
||||||
display::Window::slot_schedule([this](display::Window* w, std::chrono::microseconds t) { m_display->schedule(w, t); });
|
display::Window::slot_schedule([this](display::Window* w, std::chrono::microseconds t) { m_display->schedule(w, t); });
|
||||||
@@ -90,6 +89,9 @@ Control::cleanup() {
|
|||||||
if(!display::Canvas::daemon())
|
if(!display::Canvas::daemon())
|
||||||
m_inputStdin->remove(torrent::this_thread::poll());
|
m_inputStdin->remove(torrent::this_thread::poll());
|
||||||
|
|
||||||
|
if (scgi_thread::thread()->is_active())
|
||||||
|
scgi_thread::thread()->stop_thread_wait();
|
||||||
|
|
||||||
// Wait for all session files to be written.
|
// Wait for all session files to be written.
|
||||||
session_thread::thread()->stop_thread_wait();
|
session_thread::thread()->stop_thread_wait();
|
||||||
|
|
||||||
@@ -109,7 +111,7 @@ Control::cleanup_exception() {
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
Control::is_shutdown_completed() {
|
Control::is_shutdown_completed() {
|
||||||
if (!m_shutdownQuick || worker_thread->is_active())
|
if (!m_shutdownQuick)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Tracker requests can be disowned, so wait for these to
|
// Tracker requests can be disowned, so wait for these to
|
||||||
@@ -128,10 +130,10 @@ void
|
|||||||
Control::handle_shutdown() {
|
Control::handle_shutdown() {
|
||||||
rpc::commands.call_catch("event.system.shutdown", rpc::make_target(), "shutdown", "System shutdown event action failed: ");
|
rpc::commands.call_catch("event.system.shutdown", rpc::make_target(), "shutdown", "System shutdown event action failed: ");
|
||||||
|
|
||||||
if (!m_shutdownQuick) {
|
if (scgi_thread::thread()->is_active())
|
||||||
if (worker_thread->is_active())
|
scgi_thread::thread()->stop_thread_wait();
|
||||||
worker_thread->stop_thread_wait();
|
|
||||||
|
|
||||||
|
if (!m_shutdownQuick) {
|
||||||
torrent::runtime::network_manager()->listen_close();
|
torrent::runtime::network_manager()->listen_close();
|
||||||
|
|
||||||
m_directory_events->close();
|
m_directory_events->close();
|
||||||
@@ -141,9 +143,6 @@ Control::handle_shutdown() {
|
|||||||
torrent::this_thread::scheduler()->wait_for_ceil_seconds(&m_task_shutdown, 5s);
|
torrent::this_thread::scheduler()->wait_for_ceil_seconds(&m_task_shutdown, 5s);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (worker_thread->is_active())
|
|
||||||
worker_thread->stop_thread_wait();
|
|
||||||
|
|
||||||
m_core->shutdown(true);
|
m_core->shutdown(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,4 +5,3 @@
|
|||||||
rpc::ip_table_list ip_tables;
|
rpc::ip_table_list ip_tables;
|
||||||
|
|
||||||
Control* control{};
|
Control* control{};
|
||||||
ThreadWorker* worker_thread{};
|
|
||||||
|
|||||||
+18
-5
@@ -6,20 +6,33 @@
|
|||||||
#include "rpc/ip_table_list.h"
|
#include "rpc/ip_table_list.h"
|
||||||
|
|
||||||
class Control;
|
class Control;
|
||||||
class ThreadWorker;
|
|
||||||
|
|
||||||
extern rpc::ip_table_list ip_tables;
|
extern rpc::ip_table_list ip_tables;
|
||||||
|
|
||||||
extern Control* control;
|
extern Control* control;
|
||||||
|
|
||||||
// TODO: Update to new thread model.
|
namespace rpc {
|
||||||
extern ThreadWorker* worker_thread;
|
class SCgi;
|
||||||
|
}
|
||||||
|
|
||||||
namespace session {
|
namespace session {
|
||||||
|
|
||||||
class SessionManager;
|
class SessionManager;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace session
|
namespace scgi_thread {
|
||||||
|
|
||||||
|
torrent::utils::Thread* thread();
|
||||||
|
std::thread::id thread_id();
|
||||||
|
|
||||||
|
void callback(void* target, std::function<void ()>&& fn);
|
||||||
|
void cancel_callback(void* target);
|
||||||
|
void cancel_callback_and_wait(void* target);
|
||||||
|
|
||||||
|
rpc::SCgi* scgi();
|
||||||
|
void set_scgi(rpc::SCgi* scgi);
|
||||||
|
void set_rpc_log(const std::string& filename);
|
||||||
|
|
||||||
|
} // namespace torrent::scgi_thread
|
||||||
|
|
||||||
|
|
||||||
namespace session_thread {
|
namespace session_thread {
|
||||||
|
|||||||
+3
-9
@@ -31,6 +31,7 @@
|
|||||||
#include "rpc/command_scheduler.h"
|
#include "rpc/command_scheduler.h"
|
||||||
#include "rpc/command_scheduler_item.h"
|
#include "rpc/command_scheduler_item.h"
|
||||||
#include "rpc/parse_commands.h"
|
#include "rpc/parse_commands.h"
|
||||||
|
#include "scgi/thread_scgi.h"
|
||||||
#include "session/thread_session.h"
|
#include "session/thread_session.h"
|
||||||
#include "ui/root.h"
|
#include "ui/root.h"
|
||||||
#include "utils/directory.h"
|
#include "utils/directory.h"
|
||||||
@@ -41,8 +42,6 @@
|
|||||||
#include "signal_handler.h"
|
#include "signal_handler.h"
|
||||||
#include "option_parser.h"
|
#include "option_parser.h"
|
||||||
|
|
||||||
#include "thread_worker.h"
|
|
||||||
|
|
||||||
#define LT_LOG(log_fmt, ...) \
|
#define LT_LOG(log_fmt, ...) \
|
||||||
lt_log_print(torrent::LOG_SYSTEM, "system: " log_fmt, __VA_ARGS__);
|
lt_log_print(torrent::LOG_SYSTEM, "system: " log_fmt, __VA_ARGS__);
|
||||||
|
|
||||||
@@ -215,12 +214,9 @@ main(int argc, char** argv) {
|
|||||||
torrent::initialize();
|
torrent::initialize();
|
||||||
torrent::set_main_thread_slots(std::bind(&client_perform));
|
torrent::set_main_thread_slots(std::bind(&client_perform));
|
||||||
|
|
||||||
|
scgi::ThreadScgi::create_thread();
|
||||||
session::ThreadSession::create_thread();
|
session::ThreadSession::create_thread();
|
||||||
|
|
||||||
// TODO: Move to controller.
|
|
||||||
worker_thread = new ThreadWorker();
|
|
||||||
worker_thread->init_thread();
|
|
||||||
|
|
||||||
// Initialize option handlers after libtorrent to ensure
|
// Initialize option handlers after libtorrent to ensure
|
||||||
// torrent::ConnectionManager* are valid etc.
|
// torrent::ConnectionManager* are valid etc.
|
||||||
initialize_commands();
|
initialize_commands();
|
||||||
@@ -535,11 +531,9 @@ main(int argc, char** argv) {
|
|||||||
delete control;
|
delete control;
|
||||||
control = nullptr;
|
control = nullptr;
|
||||||
|
|
||||||
|
scgi::ThreadScgi::destroy_thread();
|
||||||
session::ThreadSession::destroy_thread();
|
session::ThreadSession::destroy_thread();
|
||||||
|
|
||||||
delete worker_thread;
|
|
||||||
worker_thread = nullptr;
|
|
||||||
|
|
||||||
torrent::log_cleanup();
|
torrent::log_cleanup();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
+2
-3
@@ -11,7 +11,6 @@
|
|||||||
|
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "thread_worker.h"
|
|
||||||
#include "rpc/scgi_task.h"
|
#include "rpc/scgi_task.h"
|
||||||
#include "utils/socket_fd.h"
|
#include "utils/socket_fd.h"
|
||||||
|
|
||||||
@@ -93,7 +92,7 @@ SCgi::open(void* sa, unsigned int length) {
|
|||||||
|
|
||||||
void
|
void
|
||||||
SCgi::activate() {
|
SCgi::activate() {
|
||||||
assert(std::this_thread::get_id() == worker_thread->thread_id() && "SCgi::activate() must be called from the worker thread.");
|
assert(torrent::this_thread::thread() == scgi_thread::thread());
|
||||||
|
|
||||||
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);
|
||||||
@@ -102,7 +101,7 @@ SCgi::activate() {
|
|||||||
|
|
||||||
void
|
void
|
||||||
SCgi::deactivate() {
|
SCgi::deactivate() {
|
||||||
assert(std::this_thread::get_id() == worker_thread->thread_id() && "SCgi::deactivate() must be called from the worker thread.");
|
assert(torrent::this_thread::thread() == scgi_thread::thread());
|
||||||
|
|
||||||
torrent::this_thread::poll()->remove_and_close(this);
|
torrent::this_thread::poll()->remove_and_close(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,143 @@
|
|||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "scgi/thread_scgi.h"
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <rak/path.h>
|
||||||
|
#include <torrent/exceptions.h>
|
||||||
|
#include <torrent/utils/log.h>
|
||||||
|
|
||||||
|
#include "rpc/scgi.h"
|
||||||
|
|
||||||
|
namespace scgi {
|
||||||
|
|
||||||
|
class ThreadScgiInternal {
|
||||||
|
public:
|
||||||
|
static ThreadScgi* thread_scgi() { return ThreadScgi::internal_thread_scgi(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
ThreadScgi* ThreadScgi::m_thread_scgi{};
|
||||||
|
|
||||||
|
void
|
||||||
|
ThreadScgi::create_thread() {
|
||||||
|
auto thread = new ThreadScgi;
|
||||||
|
|
||||||
|
m_thread_scgi = thread;
|
||||||
|
m_thread_scgi->m_state = STATE_INITIALIZED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ThreadScgi::destroy_thread() {
|
||||||
|
delete m_thread_scgi;
|
||||||
|
m_thread_scgi = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadScgi*
|
||||||
|
ThreadScgi::thread_scgi() {
|
||||||
|
return m_thread_scgi;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Remove '= 0'.
|
||||||
|
void
|
||||||
|
ThreadScgi::init_thread() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ThreadScgi::cleanup_thread() {
|
||||||
|
if (m_scgi != nullptr)
|
||||||
|
m_scgi.load()->deactivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
rpc::SCgi*
|
||||||
|
ThreadScgi::scgi() {
|
||||||
|
return m_scgi;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ThreadScgi::set_scgi(rpc::SCgi* scgi) {
|
||||||
|
rpc::SCgi* expected = nullptr;
|
||||||
|
|
||||||
|
if (!m_scgi.compare_exchange_strong(expected, scgi))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
change_rpc_log();
|
||||||
|
|
||||||
|
callback(nullptr, [this]() {
|
||||||
|
if (m_scgi == NULL)
|
||||||
|
throw torrent::internal_error("Tried to start SCGI but object was not present.");
|
||||||
|
|
||||||
|
m_scgi.load()->activate();
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ThreadScgi::set_rpc_log(const std::string& filename) {
|
||||||
|
callback(nullptr, [this, filename]() {
|
||||||
|
m_rpc_log_filename = filename;
|
||||||
|
change_rpc_log();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ThreadScgi::change_rpc_log() {
|
||||||
|
if (scgi() == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (scgi()->log_fd() != -1) {
|
||||||
|
::close(scgi()->log_fd());
|
||||||
|
scgi()->set_log_fd(-1);
|
||||||
|
lt_log_print(torrent::LOG_NOTICE, "Closed RPC log.", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_rpc_log_filename.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
scgi()->set_log_fd(open(rak::path_expand(m_rpc_log_filename).c_str(), O_WRONLY | O_APPEND | O_CREAT, 0644));
|
||||||
|
|
||||||
|
if (scgi()->log_fd() == -1) {
|
||||||
|
lt_log_print(torrent::LOG_NOTICE, "Could not open RPC log file '%s'.", m_rpc_log_filename.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lt_log_print(torrent::LOG_NOTICE, "Logging RPC events to '%s'.", m_rpc_log_filename.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ThreadScgi::call_events() {
|
||||||
|
if ((m_flags & flag_do_shutdown)) {
|
||||||
|
if ((m_flags & flag_did_shutdown))
|
||||||
|
throw torrent::internal_error("Already trigged shutdown.");
|
||||||
|
|
||||||
|
m_flags |= flag_did_shutdown;
|
||||||
|
throw torrent::shutdown_exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
process_callbacks();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::chrono::microseconds
|
||||||
|
ThreadScgi::next_timeout() {
|
||||||
|
// TODO: This leads to kqueue crash?
|
||||||
|
// return std::chrono::microseconds(1h);
|
||||||
|
return std::chrono::microseconds(10min);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace scgi
|
||||||
|
|
||||||
|
namespace scgi_thread {
|
||||||
|
|
||||||
|
torrent::utils::Thread* thread() { return scgi::ThreadScgiInternal::thread_scgi(); }
|
||||||
|
std::thread::id thread_id() { return scgi::ThreadScgiInternal::thread_scgi()->thread_id(); }
|
||||||
|
|
||||||
|
void callback(void* target, std::function<void ()>&& fn) { scgi::ThreadScgiInternal::thread_scgi()->callback(target, std::move(fn)); }
|
||||||
|
void cancel_callback(void* target) { scgi::ThreadScgiInternal::thread_scgi()->cancel_callback(target); }
|
||||||
|
void cancel_callback_and_wait(void* target) { scgi::ThreadScgiInternal::thread_scgi()->cancel_callback_and_wait(target); }
|
||||||
|
|
||||||
|
rpc::SCgi* scgi() { return scgi::ThreadScgiInternal::thread_scgi()->scgi(); }
|
||||||
|
void set_scgi(rpc::SCgi* scgi) { scgi::ThreadScgiInternal::thread_scgi()->set_scgi(scgi); }
|
||||||
|
void set_rpc_log(const std::string& filename) { scgi::ThreadScgiInternal::thread_scgi()->set_rpc_log(filename); }
|
||||||
|
|
||||||
|
} // namespace scgi_thread
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#ifndef RTORRENT_THREAD_WORKER_H
|
#ifndef RTORRENT_SCGI_THREAD_SCGI_H
|
||||||
#define RTORRENT_THREAD_WORKER_H
|
#define RTORRENT_SCGI_THREAD_SCGI_H
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -9,30 +9,49 @@ namespace rpc {
|
|||||||
class SCgi;
|
class SCgi;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ThreadWorker : public torrent::utils::Thread {
|
namespace scgi {
|
||||||
public:
|
|
||||||
ThreadWorker() = default;
|
|
||||||
~ThreadWorker();
|
|
||||||
|
|
||||||
const char* name() const override { return "rtorrent scgi"; }
|
class ThreadScgiInternal;
|
||||||
|
|
||||||
|
class ThreadScgi : public torrent::utils::Thread {
|
||||||
|
public:
|
||||||
|
|
||||||
|
static void create_thread();
|
||||||
|
static void destroy_thread();
|
||||||
|
static ThreadScgi* thread_scgi();
|
||||||
|
|
||||||
|
const char* name() const override { return "rtorrent-scgi"; }
|
||||||
|
|
||||||
void init_thread() override;
|
void init_thread() override;
|
||||||
void cleanup_thread() override;
|
void cleanup_thread() override;
|
||||||
|
|
||||||
rpc::SCgi* scgi() { return m_scgi; }
|
rpc::SCgi* scgi();
|
||||||
bool set_scgi(rpc::SCgi* scgi);
|
bool set_scgi(rpc::SCgi* scgi);
|
||||||
|
|
||||||
void set_rpc_log(const std::string& filename);
|
void set_rpc_log(const std::string& filename);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
friend class ThreadScgiInternal;
|
||||||
|
|
||||||
|
ThreadScgi() = default;
|
||||||
|
|
||||||
|
static auto internal_thread_scgi() { return m_thread_scgi; }
|
||||||
|
|
||||||
|
void call_events() override;
|
||||||
|
std::chrono::microseconds next_timeout() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void task_touch_log();
|
void task_touch_log();
|
||||||
void change_rpc_log();
|
void change_rpc_log();
|
||||||
|
|
||||||
void call_events() override;
|
static ThreadScgi* m_thread_scgi;
|
||||||
std::chrono::microseconds next_timeout() override;
|
|
||||||
|
|
||||||
std::atomic<rpc::SCgi*> m_scgi{nullptr};
|
std::atomic<rpc::SCgi*> m_scgi{nullptr};
|
||||||
std::string m_rpc_log_filename;
|
std::string m_rpc_log_filename;
|
||||||
|
|
||||||
|
// std::unique_ptr<ScgiManager> m_manager;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // RTORRENT_THREAD_WORKER_H
|
} // namespace scgi
|
||||||
|
|
||||||
|
#endif // RTORRENT_SCGI_THREAD_SCGI_H
|
||||||
@@ -76,7 +76,7 @@ std::chrono::microseconds
|
|||||||
ThreadSession::next_timeout() {
|
ThreadSession::next_timeout() {
|
||||||
// TODO: This leads to kqueue crash?
|
// TODO: This leads to kqueue crash?
|
||||||
// return std::chrono::microseconds(1h);
|
// return std::chrono::microseconds(1h);
|
||||||
return std::chrono::microseconds(10s);
|
return std::chrono::microseconds(10min);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace session
|
} // namespace session
|
||||||
|
|||||||
@@ -1,97 +0,0 @@
|
|||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include "thread_worker.h"
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <cassert>
|
|
||||||
#include <rak/path.h>
|
|
||||||
#include <torrent/exceptions.h>
|
|
||||||
|
|
||||||
#include "globals.h"
|
|
||||||
#include "control.h"
|
|
||||||
#include "core/manager.h"
|
|
||||||
#include "rpc/scgi.h"
|
|
||||||
#include "rpc/parse_commands.h"
|
|
||||||
|
|
||||||
ThreadWorker::~ThreadWorker() = default;
|
|
||||||
|
|
||||||
void
|
|
||||||
ThreadWorker::init_thread() {
|
|
||||||
m_state = STATE_INITIALIZED;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ThreadWorker::cleanup_thread() {
|
|
||||||
if (m_scgi != nullptr)
|
|
||||||
m_scgi.load()->deactivate();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
ThreadWorker::set_scgi(rpc::SCgi* scgi) {
|
|
||||||
rpc::SCgi* expected = nullptr;
|
|
||||||
|
|
||||||
if (!m_scgi.compare_exchange_strong(expected, scgi))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
change_rpc_log();
|
|
||||||
|
|
||||||
callback(nullptr, [this]() {
|
|
||||||
if (m_scgi == NULL)
|
|
||||||
throw torrent::internal_error("Tried to start SCGI but object was not present.");
|
|
||||||
|
|
||||||
m_scgi.load()->activate();
|
|
||||||
});
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ThreadWorker::set_rpc_log(const std::string& filename) {
|
|
||||||
callback(nullptr, [this, filename]() {
|
|
||||||
m_rpc_log_filename = filename;
|
|
||||||
change_rpc_log();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ThreadWorker::change_rpc_log() {
|
|
||||||
if (scgi() == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (scgi()->log_fd() != -1) {
|
|
||||||
::close(scgi()->log_fd());
|
|
||||||
scgi()->set_log_fd(-1);
|
|
||||||
control->core()->push_log("Closed RPC log.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_rpc_log_filename.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
scgi()->set_log_fd(open(rak::path_expand(m_rpc_log_filename).c_str(), O_WRONLY | O_APPEND | O_CREAT, 0644));
|
|
||||||
|
|
||||||
if (scgi()->log_fd() == -1) {
|
|
||||||
control->core()->push_log_std("Could not open RPC log file '" + m_rpc_log_filename + "'.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
control->core()->push_log_std("Logging RPC events to '" + m_rpc_log_filename + "'.");
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ThreadWorker::call_events() {
|
|
||||||
if ((m_flags & flag_do_shutdown)) {
|
|
||||||
if ((m_flags & flag_did_shutdown))
|
|
||||||
throw torrent::internal_error("Already trigged shutdown.");
|
|
||||||
|
|
||||||
m_flags |= flag_did_shutdown;
|
|
||||||
throw torrent::shutdown_exception();
|
|
||||||
}
|
|
||||||
|
|
||||||
process_callbacks();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::chrono::microseconds
|
|
||||||
ThreadWorker::next_timeout() {
|
|
||||||
return std::chrono::microseconds(10min);
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user