Prevent race conditions from simultaneous dispatch calls

This commit is contained in:
Robbert van der Helm
2020-03-14 18:08:23 +01:00
parent 5f584323c2
commit f2597ca0b9
3 changed files with 25 additions and 4 deletions
-2
View File
@@ -9,8 +9,6 @@ There are a few things that should be done before making this public, including:
- Implement missing features: - Implement missing features:
- GUIs. Right now I'm just ignoring all of the opcodes related to GUIs so that - GUIs. Right now I'm just ignoring all of the opcodes related to GUIs so that
the plugins don't crash when you open their GUI. the plugins don't crash when you open their GUI.
- The initial host callback fails in Bitwig if the plugin is bridged, but it
works if it's directly loaded into Bitwig.
- Check whether sidechaining and ~~MPE~~ work since they're unofficial additions - Check whether sidechaining and ~~MPE~~ work since they're unofficial additions
to the VST 2.4 spec. Should either work out of the box or with a minor to the VST 2.4 spec. Should either work out of the box or with a minor
adjustment. MPE works! adjustment. MPE works!
+14 -2
View File
@@ -269,8 +269,20 @@ intptr_t HostBridge::dispatch(AEffect* /*plugin*/,
} }
// TODO: Maybe reuse buffers here when dealing with chunk data // TODO: Maybe reuse buffers here when dealing with chunk data
return send_event(host_vst_dispatch, converter, opcode, index, value, data,
option, std::pair<Logger&, bool>(logger, true)); // Finish message Bitwig's plugin host sometimes calls the dispatch function
// for opcode 52 from an off thread. This shouldn't be happening, but it
// does. To prevent race conditions from multiple writes over the same
// socket at once we'll make sure that only one thread can send sockets at
// once. These locks are actually only needed around the `write_object()`
// part of `send_event()`.
dispatch_semaphore.lock();
const auto return_value =
send_event(host_vst_dispatch, converter, opcode, index, value, data,
option, std::pair<Logger&, bool>(logger, true));
dispatch_semaphore.unlock();
return return_value;
} }
void HostBridge::process_replacing(AEffect* /*plugin*/, void HostBridge::process_replacing(AEffect* /*plugin*/,
+11
View File
@@ -23,6 +23,7 @@
#include <boost/asio/streambuf.hpp> #include <boost/asio/streambuf.hpp>
#include <boost/process/async_pipe.hpp> #include <boost/process/async_pipe.hpp>
#include <boost/process/child.hpp> #include <boost/process/child.hpp>
#include <mutex>
#include <thread> #include <thread>
#include "../common/logging.h" #include "../common/logging.h"
@@ -156,6 +157,16 @@ class HostBridge {
*/ */
std::thread host_callback_handler; std::thread host_callback_handler;
/**
* A binary semaphore for preventing the dispatch function from being called
* by two threads at once. This rarely happens and shouldn't event really be
* happening, but in Bitwig's plugin bridge sometimes calls the dispatch
* function with opcode 52 while it's still waiting for another dispatch
* call to return, which would cause two threads to write over the same
* socket at the same time.
*/
std::mutex dispatch_semaphore;
/** /**
* The callback function passed by the host to the VST plugin instance. * The callback function passed by the host to the VST plugin instance.
*/ */