mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-06-17 00:43:56 +02:00
Fix Win32Thread not capturing by move
std::function does not allow non-movable lambdas, so capturing by move doesn't work there. And the old solution of course has issues with dangling pointers (but because this is C++ the compiler still thinks it's A-Ok).
This commit is contained in:
@@ -18,7 +18,8 @@
|
|||||||
|
|
||||||
PluginContext::PluginContext() : context(), events_timer(context) {}
|
PluginContext::PluginContext() : context(), events_timer(context) {}
|
||||||
|
|
||||||
uint32_t WINAPI win32_thread_trampoline(std::function<void()>* entry_point) {
|
uint32_t WINAPI
|
||||||
|
win32_thread_trampoline(fu2::unique_function<void()>* entry_point) {
|
||||||
(*entry_point)();
|
(*entry_point)();
|
||||||
delete entry_point;
|
delete entry_point;
|
||||||
|
|
||||||
|
|||||||
+22
-28
@@ -29,6 +29,7 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#include <boost/asio/io_context.hpp>
|
#include <boost/asio/io_context.hpp>
|
||||||
|
#include <function2/function2.hpp>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The delay between calls to the event loop at an even more than cinematic 30
|
* The delay between calls to the event loop at an even more than cinematic 30
|
||||||
@@ -122,19 +123,11 @@ class PluginContext {
|
|||||||
* We can't store the function pointer in the `Win32Thread` object because
|
* We can't store the function pointer in the `Win32Thread` object because
|
||||||
* moving a `Win32Thread` object would then cause issues.
|
* moving a `Win32Thread` object would then cause issues.
|
||||||
*
|
*
|
||||||
* @param win32_thread_trampoline A `std::function<void()>*` pointer to a
|
* @param entry_point A `fu2::unique_function<void()>*` pointer to a function
|
||||||
* function pointer, great.
|
* pointer, great.
|
||||||
*/
|
*/
|
||||||
uint32_t WINAPI win32_thread_trampoline(std::function<void()>* entry_point);
|
uint32_t WINAPI
|
||||||
|
win32_thread_trampoline(fu2::unique_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
|
* A simple RAII wrapper around the Win32 thread API that imitates
|
||||||
@@ -166,24 +159,25 @@ class Win32Thread {
|
|||||||
* @param entry_point The thread entry point that should be run.
|
* @param entry_point The thread entry point that should be run.
|
||||||
* @param parameter The parameter passed to the entry point function.
|
* @param parameter The parameter passed to the entry point function.
|
||||||
*/
|
*/
|
||||||
template <class Function, class... Args>
|
template <typename Function, typename... Args>
|
||||||
Win32Thread(Function&& f, Args&&... args)
|
Win32Thread(Function&& f, Args&&... args)
|
||||||
: handle(
|
: handle(
|
||||||
CreateThread(nullptr,
|
CreateThread(
|
||||||
0,
|
nullptr,
|
||||||
reinterpret_cast<LPTHREAD_START_ROUTINE>(
|
0,
|
||||||
win32_thread_trampoline),
|
reinterpret_cast<LPTHREAD_START_ROUTINE>(
|
||||||
// We'll capture the function by move since the
|
win32_thread_trampoline),
|
||||||
// lambda will often go out of scope in the time that
|
// `std::function` does not support functions with move
|
||||||
// the thread is starting. Alternatively we could
|
// captures the function has to be copy-constructable.
|
||||||
// wait for the thread to be up before continuing,
|
// Function2's unique_function lets us capture and move our
|
||||||
// that may be a bit safer.
|
// arguments to the lambda so we don't end up with dangling
|
||||||
new std::function<void()>([&, f = std::move(f)]() {
|
// references.
|
||||||
std::invoke(
|
new fu2::unique_function<void()>(
|
||||||
f, decay_copy(std::forward<Args>(args))...);
|
[f = std::move(f), ... args = std::move(args)]() mutable {
|
||||||
}),
|
f(std::move(args)...);
|
||||||
0,
|
}),
|
||||||
nullptr),
|
0,
|
||||||
|
nullptr),
|
||||||
CloseHandle) {}
|
CloseHandle) {}
|
||||||
|
|
||||||
Win32Thread(const Win32Thread&) = delete;
|
Win32Thread(const Win32Thread&) = delete;
|
||||||
|
|||||||
Reference in New Issue
Block a user