refactor: replace tr_thread with std::thread (#2548)

This commit is contained in:
Charles Kerr 2022-01-31 13:34:04 -06:00 committed by GitHub
parent bc9479d016
commit 87dfabb9d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 44 additions and 166 deletions

View File

@ -27,7 +27,6 @@
#include "transmission.h"
#include "crypto-utils.h"
#include "log.h"
#include "platform.h"
#include "tr-assert.h"
#include "utils.h"

View File

@ -25,7 +25,6 @@
#include "transmission.h"
#include "crypto-utils.h"
#include "log.h"
#include "platform.h"
#include "tr-assert.h"
#include "utils.h"

View File

@ -55,7 +55,6 @@
#include "error.h"
#include "file.h"
#include "log.h"
#include "platform.h"
#include "tr-assert.h"
#include "utils.h"

View File

@ -6,10 +6,11 @@
#include <algorithm>
#include <cerrno>
#include <cstdint>
#include <cstdlib> /* qsort */
#include <cstring> /* strcmp, strlen */
#include <mutex>
#include <optional>
#include <string_view>
#include <thread>
#include <event2/util.h> /* evutil_ascii_strcasecmp() */
@ -20,7 +21,6 @@
#include "file.h"
#include "log.h"
#include "makemeta.h"
#include "platform.h" /* threads, locks */
#include "session.h"
#include "tr-assert.h"
#include "utils.h" /* buildpath */
@ -505,11 +505,11 @@ static void tr_realMakeMetaInfo(tr_metainfo_builder* builder)
static tr_metainfo_builder* queue = nullptr;
static tr_thread* workerThread = nullptr;
static std::optional<std::thread::id> worker_thread_id;
static std::recursive_mutex queue_mutex_;
static void makeMetaWorkerFunc(void* /*user_data*/)
static void makeMetaWorkerFunc()
{
for (;;)
{
@ -535,7 +535,7 @@ static void makeMetaWorkerFunc(void* /*user_data*/)
tr_realMakeMetaInfo(builder);
}
workerThread = nullptr;
worker_thread_id.reset();
}
void tr_makeMetaInfo(
@ -591,8 +591,10 @@ void tr_makeMetaInfo(
builder->nextBuilder = queue;
queue = builder;
if (workerThread == nullptr)
if (!worker_thread_id)
{
workerThread = tr_threadNew(makeMetaWorkerFunc, nullptr);
auto thread = std::thread(makeMetaWorkerFunc);
worker_thread_id = thread.get_id();
thread.detach();
}
}

View File

@ -9,13 +9,7 @@
#include <list>
#include <string>
#include <string_view>
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 600 /* needed for recursive locks. */
#endif
#ifndef __USE_UNIX98
#define __USE_UNIX98 /* some older Linuxes need it spelt out for them */
#endif
#include <thread>
#ifdef __HAIKU__
#include <limits.h> /* PATH_MAX */
@ -27,16 +21,18 @@
#include <shlobj.h> /* SHGetKnownFolderPath(), FOLDERID_... */
#else
#include <unistd.h> /* getuid() */
#endif
#ifdef BUILD_MAC_CLIENT
#include <CoreFoundation/CoreFoundation.h>
#endif
#ifdef __HAIKU__
#include <FindDirectory.h>
#endif
#include <pthread.h>
#endif
#include "transmission.h"
#include "file.h"
#include "log.h"
#include "platform.h"
@ -90,106 +86,6 @@ static char* tr_buildPath(char const* first_element, ...)
return buf;
}
/***
**** THREADS
***/
#ifdef _WIN32
using tr_thread_id = DWORD;
#else
using tr_thread_id = pthread_t;
#endif
static tr_thread_id tr_getCurrentThread()
{
#ifdef _WIN32
return GetCurrentThreadId();
#else
return pthread_self();
#endif
}
unsigned long tr_threadCurrentId()
{
return (unsigned long)tr_getCurrentThread();
}
static bool tr_areThreadsEqual(tr_thread_id a, tr_thread_id b)
{
#ifdef _WIN32
return a == b;
#else
return pthread_equal(a, b) != 0;
#endif
}
/** @brief portability wrapper around OS-dependent threads */
struct tr_thread
{
void (*func)(void*);
void* arg;
tr_thread_id thread;
#ifdef _WIN32
HANDLE thread_handle;
#endif
};
bool tr_amInThread(tr_thread const* t)
{
return tr_areThreadsEqual(tr_getCurrentThread(), t->thread);
}
#ifdef _WIN32
#define ThreadFuncReturnType unsigned WINAPI
#else
#define ThreadFuncReturnType void*
#endif
static ThreadFuncReturnType ThreadFunc(void* _t)
{
#ifndef _WIN32
pthread_detach(pthread_self());
#endif
auto* t = static_cast<tr_thread*>(_t);
t->func(t->arg);
tr_free(t);
#ifdef _WIN32
_endthreadex(0);
return 0;
#else
return nullptr;
#endif
}
tr_thread* tr_threadNew(void (*func)(void*), void* arg)
{
auto* t = static_cast<tr_thread*>(tr_new0(tr_thread, 1));
t->func = func;
t->arg = arg;
#ifdef _WIN32
{
unsigned int id;
t->thread_handle = (HANDLE)_beginthreadex(nullptr, 0, &ThreadFunc, t, 0, &id);
t->thread = (DWORD)id;
}
#else
pthread_create(&t->thread, nullptr, (void* (*)(void*))ThreadFunc, t);
#endif
return t;
}
/***
**** PATHS
***/
@ -285,11 +181,6 @@ char const* tr_getTorrentDir(tr_session const* session)
return session->torrent_dir.c_str();
}
char const* tr_getResumeDir(tr_session const* session)
{
return session->resume_dir.c_str();
}
char const* tr_getDefaultConfigDir(char const* appname)
{
static char const* s = nullptr;

View File

@ -12,6 +12,8 @@
#include <string>
#include <string_view>
struct tr_session;
/**
* @addtogroup tr_session Session
* @{
@ -25,9 +27,6 @@
*/
void tr_setConfigDir(tr_session* session, std::string_view config_dir);
/** @brief return the directory where .resume files are stored */
char const* tr_getResumeDir(tr_session const*);
/** @brief return the directory where .torrent files are stored */
char const* tr_getTorrentDir(tr_session const*);
@ -39,20 +38,4 @@ std::string tr_getSessionIdDir();
/** @} */
/**
* @addtogroup utils Utilities
* @{
*/
struct tr_thread;
/** @brief Instantiate a new process thread */
tr_thread* tr_threadNew(void (*func)(void*), void* arg);
unsigned long tr_threadCurrentId();
/** @brief Return nonzero if this function is being called from `thread'
@param thread the thread being tested */
bool tr_amInThread(tr_thread const* thread);
/* @} */

View File

@ -16,7 +16,6 @@
#include "log.h"
#include "magnet-metainfo.h"
#include "peer-mgr.h" /* pex */
#include "platform.h" /* tr_getResumeDir() */
#include "resume.h"
#include "session.h"
#include "torrent.h"

View File

@ -9,7 +9,6 @@
#include "transmission.h"
#include "log.h"
#include "platform.h" /* tr_sessionGetConfigDir() */
#include "session.h"
#include "stats.h"
#include "utils.h"

View File

@ -43,7 +43,6 @@
#include "magnet-metainfo.h"
#include "peer-common.h" /* MAX_BLOCK_SIZE */
#include "peer-mgr.h"
#include "platform.h" /* TR_PATH_DELIMITER_STR */
#include "resume.h"
#include "session.h"
#include "subprocess.h"

View File

@ -10,6 +10,7 @@
#include <cstring> /* memcpy(), memset(), memchr(), strlen() */
#include <ctime>
#include <string_view>
#include <thread>
#ifdef _WIN32
#include <inttypes.h>
@ -34,7 +35,6 @@
#include "log.h"
#include "net.h"
#include "peer-mgr.h"
#include "platform.h"
#include "session.h"
#include "torrent.h"
#include "tr-assert.h"
@ -364,7 +364,7 @@ int tr_dhtInit(tr_session* ss)
cl->nodes6 = nodes6;
cl->len = len;
cl->len6 = len6;
tr_threadNew(dht_bootstrap, cl);
std::thread(dht_bootstrap, cl).detach();
dht_timer = evtimer_new(session_->event_base, timer_callback, session_);
tr_timerAdd(dht_timer, 0, tr_rand_int_weak(1000000));

View File

@ -7,6 +7,7 @@
#include <list>
#include <mutex>
#include <shared_mutex>
#include <thread>
#include <csignal>
@ -22,7 +23,6 @@
#include "log.h"
#include "net.h"
#include "platform.h"
#include "session.h"
#include "tr-assert.h"
#include "trevent.h"
@ -105,6 +105,11 @@ int cond_wait(void* cond_, void* lock_, struct timeval const* tv)
return success == std::cv_status::timeout ? 1 : 0;
}
unsigned long thread_current_id()
{
return std::hash<std::thread::id>()(std::this_thread::get_id());
}
} // namespace impl
void tr_evthread_init()
@ -123,7 +128,7 @@ void tr_evthread_init()
impl::cond_wait };
evthread_set_condition_callbacks(&cond_cbs);
evthread_set_id_callback(tr_threadCurrentId);
evthread_set_id_callback(impl::thread_current_id);
}
} // namespace
@ -162,7 +167,7 @@ struct tr_event_handle
event_base* base = nullptr;
tr_session* session = nullptr;
tr_thread* thread = nullptr;
std::thread::id thread_id;
};
static void onWorkAvailable(evutil_socket_t /*fd*/, short /*flags*/, void* vsession)
@ -185,10 +190,8 @@ static void onWorkAvailable(evutil_socket_t /*fd*/, short /*flags*/, void* vsess
}
}
static void libeventThreadFunc(void* vevents)
static void libeventThreadFunc(tr_event_handle* events)
{
auto* const events = static_cast<tr_event_handle*>(vevents);
#ifndef _WIN32
/* Don't exit when writing on a broken socket */
signal(SIGPIPE, SIG_IGN);
@ -224,7 +227,10 @@ void tr_eventInit(tr_session* session)
auto* const events = new tr_event_handle();
events->session = session;
events->thread = tr_threadNew(libeventThreadFunc, events);
auto thread = std::thread(libeventThreadFunc, events);
events->thread_id = thread.get_id();
thread.detach();
// wait until the libevent thread is running
while (session->events == nullptr)
@ -260,7 +266,7 @@ bool tr_amInEventThread(tr_session const* session)
TR_ASSERT(tr_isSession(session));
TR_ASSERT(session->events != nullptr);
return tr_amInThread(session->events->thread);
return std::this_thread::get_id() == session->events->thread_id;
}
/**
@ -273,7 +279,7 @@ void tr_runInEventThread(tr_session* session, void (*func)(void*), void* user_da
auto* events = session->events;
TR_ASSERT(events != nullptr);
if (tr_amInThread(events->thread))
if (tr_amInEventThread(session))
{
(*func)(user_data);
}

View File

@ -6,7 +6,9 @@
#include <algorithm>
#include <ctime>
#include <mutex>
#include <optional>
#include <set>
#include <thread>
#include <vector>
#include "transmission.h"
@ -14,7 +16,6 @@
#include "crypto-utils.h"
#include "file.h"
#include "log.h"
#include "platform.h"
#include "torrent.h"
#include "tr-assert.h"
#include "utils.h" /* tr_malloc(), tr_free() */
@ -197,12 +198,12 @@ struct verify_node
static struct verify_node currentNode;
// TODO: refactor s.t. this doesn't leak
static auto& verify_list{ *new std::set<verify_node>{} };
static tr_thread* verify_thread = nullptr;
static std::optional<std::thread::id> verify_thread_id;
static bool stopCurrent = false;
static std::mutex verify_mutex_;
static void verifyThreadFunc(void* /*user_data*/)
static void verifyThreadFunc()
{
for (;;)
{
@ -213,7 +214,7 @@ static void verifyThreadFunc(void* /*user_data*/)
if (std::empty(verify_list))
{
currentNode.torrent = nullptr;
verify_thread = nullptr;
verify_thread_id.reset();
return;
}
@ -256,9 +257,11 @@ void tr_verifyAdd(tr_torrent* tor, tr_verify_done_func callback_func, void* call
tor->setVerifyState(TR_VERIFY_WAIT);
verify_list.insert(node);
if (verify_thread == nullptr)
if (!verify_thread_id)
{
verify_thread = tr_threadNew(verifyThreadFunc, nullptr);
auto thread = std::thread(verifyThreadFunc);
verify_thread_id = thread.get_id();
thread.detach();
}
}

View File

@ -8,6 +8,7 @@
#include <set>
#include <string>
#include <string_view>
#include <thread>
#ifdef _WIN32
#include <windows.h>
@ -24,7 +25,6 @@
#include "log.h"
#include "net.h" /* tr_address */
#include "torrent.h"
#include "platform.h" /* mutex */
#include "session.h"
#include "tr-assert.h"
#include "tr-macros.h"
@ -342,8 +342,7 @@ static struct tr_web_task* tr_webRunImpl(
{
if (session->web == nullptr)
{
tr_threadNew(tr_webThreadFunc, session);
std::thread(tr_webThreadFunc, session).detach();
while (session->web == nullptr)
{
tr_wait_msec(20);