mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-07 03:50:11 +02:00
Properly forward arguments in Win32Thread
This commit is contained in:
@@ -25,14 +25,6 @@ uint32_t WINAPI win32_thread_trampoline(std::function<void()>* entry_point) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Win32Thread::~Win32Thread() {
|
||||
// Imitate std::jthread's joining behaviour, the thread handle will be
|
||||
// cleaned up by the `std::unique_ptr`
|
||||
if (handle) {
|
||||
WaitForSingleObject(handle.get(), INFINITE);
|
||||
}
|
||||
}
|
||||
|
||||
Win32Thread::Win32Thread(Win32Thread&& o) : handle(std::move(o.handle)) {}
|
||||
|
||||
Win32Thread& Win32Thread::operator=(Win32Thread&& o) {
|
||||
|
||||
+28
-19
@@ -127,9 +127,18 @@ class PluginContext {
|
||||
*/
|
||||
uint32_t WINAPI win32_thread_trampoline(std::function<void()>* entry_point);
|
||||
|
||||
/**
|
||||
* Taken from the C++ reference:
|
||||
* https://en.cppreference.com/w/cpp/thread/jthread
|
||||
*/
|
||||
template <class T>
|
||||
std::decay_t<T> decay_copy(T&& v) {
|
||||
return std::forward<T>(v);
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple RAII wrapper around the Win32 thread API that imitates
|
||||
* `std::jthread`.
|
||||
* `std::thread`.
|
||||
*
|
||||
* `std::thread` directly uses pthreads. This means that, like with
|
||||
* `CreateThread()`, some thread local information does not get initialized
|
||||
@@ -152,30 +161,30 @@ class Win32Thread {
|
||||
|
||||
/**
|
||||
* Constructor that immediately starts running the thread. This works
|
||||
* equivalently to `std::jthread`.
|
||||
* equivalently to `std::thread`.
|
||||
*
|
||||
* @param entry_point The thread entry point that should be run.
|
||||
* @param parameter The parameter passed to the entry point function.
|
||||
*/
|
||||
template <class Function, class... Args>
|
||||
Win32Thread(Function&& f, Args&&... args)
|
||||
: handle(CreateThread(
|
||||
nullptr,
|
||||
0,
|
||||
reinterpret_cast<LPTHREAD_START_ROUTINE>(
|
||||
win32_thread_trampoline),
|
||||
new std::function<void()>(
|
||||
[f = std::move(f), ... args = std::move(args)]() {
|
||||
std::invoke(f, args...);
|
||||
}),
|
||||
0,
|
||||
nullptr),
|
||||
CloseHandle) {}
|
||||
|
||||
/**
|
||||
* Join the thread on destruction, just like `std::jthread` does.
|
||||
*/
|
||||
~Win32Thread();
|
||||
: handle(
|
||||
CreateThread(nullptr,
|
||||
0,
|
||||
reinterpret_cast<LPTHREAD_START_ROUTINE>(
|
||||
win32_thread_trampoline),
|
||||
// We'll capture the function by move since the
|
||||
// lambda will often go out of scope in the time that
|
||||
// the thread is starting. Alternatively we could
|
||||
// wait for the thread to be up before continuing,
|
||||
// that may be a bit safer.
|
||||
new std::function<void()>([&, f = std::move(f)]() {
|
||||
std::invoke(
|
||||
f, decay_copy(std::forward<Args>(args))...);
|
||||
}),
|
||||
0,
|
||||
nullptr),
|
||||
CloseHandle) {}
|
||||
|
||||
Win32Thread(const Win32Thread&) = delete;
|
||||
Win32Thread& operator=(const Win32Thread&) = delete;
|
||||
|
||||
Reference in New Issue
Block a user