Do thread cleanup within the same thread context.

This commit is contained in:
rakshasa
2025-05-30 10:16:03 +02:00
committed by Jari Sundell
parent de6c48ca3f
commit 2d565d1c80
7 changed files with 119 additions and 24 deletions
+7 -4
View File
@@ -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;
+1
View File
@@ -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);
+43 -10
View File
@@ -2,26 +2,24 @@
#include "test_main_thread.h"
#include "globals.h"
#include <signal.h>
#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>
TestMainThread::create() {
// Needs to be called before Thread is created.
mock_redirect_defaults();
auto thread = new TestMainThread();
return std::unique_ptr<TestMainThread>(thread);
return std::unique_ptr<TestMainThread>(new TestMainThread());
}
TestMainThread::TestMainThread() {}
TestMainThread::~TestMainThread() {
m_self = nullptr;
std::unique_ptr<TestMainThread>
TestMainThread::create_with_mock() {
return std::unique_ptr<TestMainThread>(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();
}
+39 -5
View File
@@ -2,29 +2,63 @@
#define TEST_HELPERS_TEST_MAIN_THREAD_H
#include <memory>
#include <torrent/common.h>
#include <torrent/utils/thread.h>
#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<TestMainThread> create();
~TestMainThread() override;
static std::unique_ptr<TestMainThread> 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<TestMainThread> m_main_thread;
};
class TestFixtureWithMainAndDiskThread : public test_fixture {
public:
void setUp();
void tearDown();
std::unique_ptr<TestMainThread> m_main_thread;
};
class TestFixtureWithMainAndTrackerThread : public test_fixture {
public:
void setUp();
void tearDown();
std::unique_ptr<TestMainThread> m_main_thread;
};
class TestFixtureWithMockAndMainThread : public test_fixture {
public:
void setUp();
void tearDown();
std::unique_ptr<TestMainThread> m_main_thread;
};
#endif // TEST_HELPERS_TEST_MAIN_THREAD_H
+6 -5
View File
@@ -3,11 +3,10 @@
#include "test_thread.h"
#include <unistd.h>
#include <cppunit/extensions/HelperMacros.h>
#include <torrent/exceptions.h>
#include <torrent/poll.h>
#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++;
+2
View File
@@ -4,6 +4,7 @@
#include <atomic>
#include <memory>
#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; }
+21
View File
@@ -0,0 +1,21 @@
#ifndef LIBTORRENT_TEST_UTILS_H
#define LIBTORRENT_TEST_UTILS_H
#include <functional>
#include <unistd.h>
inline bool
wait_for_true(std::function<bool ()> test_function) {
int i = 100;
do {
if (test_function())
return true;
usleep(10 * 1000);
} while (--i);
return false;
}
#endif // LIBTORRENT_TEST_UTILS_H