Make plugin initialization thread safe

This commit is contained in:
Robbert van der Helm
2020-05-22 22:42:24 +02:00
parent b4b471523f
commit bea924c0e1
+17 -11
View File
@@ -31,6 +31,11 @@ using VstEntryPoint = AEffect*(VST_CALL_CONV*)(audioMasterCallback);
* from an `AEffect` when it performs a host callback during its initialization. * from an `AEffect` when it performs a host callback during its initialization.
*/ */
Vst2Bridge* current_bridge_instance = nullptr; Vst2Bridge* current_bridge_instance = nullptr;
/**
* Needed for the rare event that two plugins are getting initialized at the
* same time.
*/
std::mutex current_bridge_instance_mutex;
intptr_t VST_CALL_CONV intptr_t VST_CALL_CONV
host_callback_proxy(AEffect*, int, int, intptr_t, void*, float); host_callback_proxy(AEffect*, int, int, intptr_t, void*, float);
@@ -52,8 +57,6 @@ Vst2Bridge& get_bridge_instance(const AEffect* plugin) {
// This is needed during the initialization of the plugin since we can only // This is needed during the initialization of the plugin since we can only
// add our own pointer after it's done initializing // add our own pointer after it's done initializing
if (current_bridge_instance != nullptr) { if (current_bridge_instance != nullptr) {
// This should only be used during initialization
assert(plugin == nullptr || plugin->ptr1 == nullptr);
return *current_bridge_instance; return *current_bridge_instance;
} }
@@ -106,16 +109,19 @@ Vst2Bridge::Vst2Bridge(std::string plugin_dll_path,
// We'll try to do the same `get_bridge_isntance` trick as in // We'll try to do the same `get_bridge_isntance` trick as in
// `plugin/plugin.cpp`, but since the plugin will probably call the host // `plugin/plugin.cpp`, but since the plugin will probably call the host
// callback while it's initializing we sadly have to use a global here. // callback while it's initializing we sadly have to use a global here.
current_bridge_instance = this; {
plugin = vst_entry_point(host_callback_proxy); std::lock_guard lock(current_bridge_instance_mutex);
if (plugin == nullptr) { current_bridge_instance = this;
throw std::runtime_error("VST plugin at '" + plugin_dll_path + plugin = vst_entry_point(host_callback_proxy);
"' failed to initialize."); if (plugin == nullptr) {
} throw std::runtime_error("VST plugin at '" + plugin_dll_path +
"' failed to initialize.");
}
// We only needed this little hack during initialization // We only needed this little hack during initialization
current_bridge_instance = nullptr; current_bridge_instance = nullptr;
plugin->ptr1 = this; plugin->ptr1 = this;
}
// Send the plugin's information to the Linux VST plugin. This is done over // Send the plugin's information to the Linux VST plugin. This is done over
// the `dispatch()` socket since this has to be done only once during // the `dispatch()` socket since this has to be done only once during