From fac820c25ab2dc19e305636cd72e559db71f9cbf Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Tue, 27 Oct 2020 23:18:59 +0100 Subject: [PATCH] Execute all non-unsafe opcodes on calling thread This will require more testing of course, but I think it should be safe. This would increase the potential maximal throughput in group hosts significantly. --- src/wine-host/bridges/vst2.cpp | 19 +++++++------------ src/wine-host/utils.h | 3 --- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/wine-host/bridges/vst2.cpp b/src/wine-host/bridges/vst2.cpp index ecac52ce..4093dd21 100644 --- a/src/wine-host/bridges/vst2.cpp +++ b/src/wine-host/bridges/vst2.cpp @@ -335,7 +335,7 @@ bool Vst2Bridge::should_skip_message_loop() const { void Vst2Bridge::handle_dispatch() { sockets.host_vst_dispatch.receive( - std::nullopt, [&](Event& event, bool on_main_thread) { + std::nullopt, [&](Event& event, bool /*on_main_thread*/) { // TODO: As per the TODO in `passthrough_event`, this can use a // round of refactoring now that we never use its returned // lambda directly anymore @@ -343,17 +343,12 @@ void Vst2Bridge::handle_dispatch() { plugin, [&](AEffect* plugin, int opcode, int index, intptr_t value, void* data, float option) -> intptr_t { - // On the main thread, instead of running - // `plugin->dispatcher()` (or `dispatch_wrapper()`) - // directly, we'll run the function within the IO context so - // all events will be executed on the same thread as the one - // that runs the Win32 message loop. In some scenarios we'll - // receive incoming calls from multiple threads or we'll - // receive calls while we're currently stuck in the Win32 - // message loop. In those cases we'll assume that these - // events can be safely handled directlyfrom another thread. - if (unsafe_opcodes.contains(opcode) || - (on_main_thread && !plugin_context.event_loop_active)) { + // Certain functions will most definitely involve the GUI or + // the Win32 message loop. These functions have to be + // performed on the thread that is running the IO context, + // since this is also where the plugins were instantiated + // and where the Win32 message loop is handled. + if (unsafe_opcodes.contains(opcode)) { std::promise dispatch_result; boost::asio::dispatch(plugin_context.context, [&]() { const intptr_t result = dispatch_wrapper( diff --git a/src/wine-host/utils.h b/src/wine-host/utils.h index 81f5c8e1..b442ed0d 100644 --- a/src/wine-host/utils.h +++ b/src/wine-host/utils.h @@ -137,9 +137,6 @@ win32_thread_trampoline(fu2::unique_function* entry_point); * `CreateThread()`, some thread local information does not get initialized * which can lead to memory errors. * - * TODO: Once these changes are complete, check if we can drop `PluginContext` - * again and execute all 'safe' opcodes on the calling thread. - * * @note This should be used instead of `std::thread` or `std::jthread` whenever * the thread directly calls third party library code, i.e. `LoadLibrary()`, * `FreeLibrary()`, the plugin's entry point, or any of the `AEffect::*()`