From 2d565d1c8079e1709c0fa28baf6410290ec04d62 Mon Sep 17 00:00:00 2001 From: rakshasa Date: Fri, 30 May 2025 10:16:03 +0200 Subject: [PATCH] Do thread cleanup within the same thread context. --- src/thread_worker.cc | 11 ++++--- src/thread_worker.h | 1 + test/helpers/test_main_thread.cc | 53 ++++++++++++++++++++++++++------ test/helpers/test_main_thread.h | 44 +++++++++++++++++++++++--- test/helpers/test_thread.cc | 11 ++++--- test/helpers/test_thread.h | 2 ++ test/helpers/test_utils.h | 21 +++++++++++++ 7 files changed, 119 insertions(+), 24 deletions(-) create mode 100644 test/helpers/test_utils.h diff --git a/src/thread_worker.cc b/src/thread_worker.cc index 2114efb4..23ad3e03 100644 --- a/src/thread_worker.cc +++ b/src/thread_worker.cc @@ -14,16 +14,19 @@ #include "rpc/scgi.h" #include "rpc/parse_commands.h" -ThreadWorker::~ThreadWorker() { - if (m_scgi != nullptr) - m_scgi.load()->deactivate(); -} +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; diff --git a/src/thread_worker.h b/src/thread_worker.h index ff41a244..0eb3caf9 100644 --- a/src/thread_worker.h +++ b/src/thread_worker.h @@ -17,6 +17,7 @@ public: const char* name() const override { return "rtorrent scgi"; } void init_thread() override; + void cleanup_thread() override; rpc::SCgi* scgi() { return m_scgi; } bool set_scgi(rpc::SCgi* scgi); diff --git a/test/helpers/test_main_thread.cc b/test/helpers/test_main_thread.cc index a01ed3b9..7a48a07b 100644 --- a/test/helpers/test_main_thread.cc +++ b/test/helpers/test_main_thread.cc @@ -2,26 +2,24 @@ #include "test_main_thread.h" -#include "globals.h" +#include + #include "test/helpers/mock_function.h" #include "torrent/exceptions.h" -#include "torrent/poll.h" #include "torrent/net/resolver.h" +#include "torrent/utils/log.h" #include "torrent/utils/scheduler.h" std::unique_ptr TestMainThread::create() { // Needs to be called before Thread is created. mock_redirect_defaults(); - - auto thread = new TestMainThread(); - return std::unique_ptr(thread); + return std::unique_ptr(new TestMainThread()); } -TestMainThread::TestMainThread() {} - -TestMainThread::~TestMainThread() { - m_self = nullptr; +std::unique_ptr +TestMainThread::create_with_mock() { + return std::unique_ptr(new TestMainThread()); } void @@ -34,6 +32,10 @@ TestMainThread::init_thread() { init_thread_local(); } +void +TestMainThread::cleanup_thread() { +} + void TestMainThread::call_events() { process_callbacks(); @@ -41,5 +43,36 @@ TestMainThread::call_events() { std::chrono::microseconds TestMainThread::next_timeout() { - return std::chrono::microseconds(10min); + return 10min; } + +void +TestFixtureWithMainThread::setUp() { + test_fixture::setUp(); + + m_main_thread = TestMainThread::create(); + m_main_thread->init_thread(); +} + +void +TestFixtureWithMainThread::tearDown() { + m_main_thread.reset(); + + test_fixture::tearDown(); +} + +void +TestFixtureWithMockAndMainThread::setUp() { + test_fixture::setUp(); + + m_main_thread = TestMainThread::create_with_mock(); + m_main_thread->init_thread(); +} + +void +TestFixtureWithMockAndMainThread::tearDown() { + m_main_thread.reset(); + + test_fixture::tearDown(); +} + diff --git a/test/helpers/test_main_thread.h b/test/helpers/test_main_thread.h index 512a58e1..03a294eb 100644 --- a/test/helpers/test_main_thread.h +++ b/test/helpers/test_main_thread.h @@ -2,29 +2,63 @@ #define TEST_HELPERS_TEST_MAIN_THREAD_H #include -#include -#include +#include "test/helpers/test_fixture.h" #include "test/helpers/test_thread.h" +#include "torrent/common.h" +#include "torrent/utils/thread.h" class TestMainThread : public torrent::utils::Thread { public: static std::unique_ptr create(); - - ~TestMainThread() override; + static std::unique_ptr create_with_mock(); const char* name() const override { return "rtorrent test main"; } void init_thread() override; + void cleanup_thread() override; void test_set_cached_time(std::chrono::microseconds t) { set_cached_time(365 * 24h + t); } + void test_add_cached_time(std::chrono::microseconds t) { set_cached_time(cached_time() + t); } void test_process_events_without_cached_time() { process_events_without_cached_time(); } private: - TestMainThread(); + TestMainThread() = default; void call_events() override; std::chrono::microseconds next_timeout() override; }; +class TestFixtureWithMainThread : public test_fixture { +public: + void setUp(); + void tearDown(); + + std::unique_ptr m_main_thread; +}; + +class TestFixtureWithMainAndDiskThread : public test_fixture { +public: + void setUp(); + void tearDown(); + + std::unique_ptr m_main_thread; +}; + +class TestFixtureWithMainAndTrackerThread : public test_fixture { +public: + void setUp(); + void tearDown(); + + std::unique_ptr m_main_thread; +}; + +class TestFixtureWithMockAndMainThread : public test_fixture { +public: + void setUp(); + void tearDown(); + + std::unique_ptr m_main_thread; +}; + #endif // TEST_HELPERS_TEST_MAIN_THREAD_H diff --git a/test/helpers/test_thread.cc b/test/helpers/test_thread.cc index 45d2275a..c1f93798 100644 --- a/test/helpers/test_thread.cc +++ b/test/helpers/test_thread.cc @@ -3,11 +3,10 @@ #include "test_thread.h" #include -#include -#include -#include #include "test/helpers/mock_function.h" +#include "torrent/exceptions.h" +#include "torrent/poll.h" const int test_thread::test_flag_pre_stop; const int test_thread::test_flag_long_timeout; @@ -33,8 +32,6 @@ test_thread::test_thread() : test_thread::~test_thread() { if (is_active()) stop_thread_wait(); - - m_self = nullptr; } void @@ -43,6 +40,10 @@ test_thread::init_thread() { m_test_state = TEST_PRE_START; } +void +test_thread::cleanup_thread() { +} + void test_thread::call_events() { m_loop_count++; diff --git a/test/helpers/test_thread.h b/test/helpers/test_thread.h index abb90cf5..b3e19f17 100644 --- a/test/helpers/test_thread.h +++ b/test/helpers/test_thread.h @@ -4,6 +4,7 @@ #include #include +#include "test/helpers/test_utils.h" #include "torrent/common.h" #include "torrent/utils/thread.h" @@ -40,6 +41,7 @@ public: const char* name() const override { return "test_thread"; } void init_thread() override; + void cleanup_thread() override; void set_pre_stop() { m_test_flags |= test_flag_pre_stop; } void set_test_flag(int flags) { m_test_flags |= flags; } diff --git a/test/helpers/test_utils.h b/test/helpers/test_utils.h new file mode 100644 index 00000000..4c8e7150 --- /dev/null +++ b/test/helpers/test_utils.h @@ -0,0 +1,21 @@ +#ifndef LIBTORRENT_TEST_UTILS_H +#define LIBTORRENT_TEST_UTILS_H + +#include +#include + +inline bool +wait_for_true(std::function test_function) { + int i = 100; + + do { + if (test_function()) + return true; + + usleep(10 * 1000); + } while (--i); + + return false; +} + +#endif // LIBTORRENT_TEST_UTILS_H