Add workaround for yabridge threading
* yabridge runs the plugin's process function in a dedicated bridged thread. Ardour's process thread is not (it just waits) * When a plugin calls `restartComponent` from the realtime thread. yabridge uses a host notification thread to perform the callback. Unlike other VST3 implementations that use a notification thread (eg. JUCE), yabridge blocks and waits for the notification to complete before the realtime thread can continue. This leads to a deadlock. However, we know that yabridge always synchronizes the callback and concurrent calls are prevented by yabridge's design. https://github.com/robbert-vdh/yabridge/issues/266
This commit is contained in:
parent
f191d8ba94
commit
4402e2a3a8
@ -40,6 +40,10 @@ public:
|
||||
|
||||
Steinberg::IPluginFactory* factory ();
|
||||
|
||||
bool has_symbol (const char* name) const {
|
||||
return NULL != fn_ptr (name);
|
||||
}
|
||||
|
||||
protected:
|
||||
void release_factory ();
|
||||
|
||||
|
@ -358,6 +358,8 @@ private:
|
||||
|
||||
/* work around UADx plugin crash */
|
||||
bool _no_kMono;
|
||||
/* work around yabridge threading */
|
||||
bool _restart_component_is_synced;
|
||||
};
|
||||
|
||||
} // namespace Steinberg
|
||||
|
@ -1173,6 +1173,7 @@ VST3PI::VST3PI (std::shared_ptr<ARDOUR::VST3PluginModule> m, std::string unique_
|
||||
, _block_rpc (0)
|
||||
, _rpc_queue (RouteProcessorChange::NoProcessorChange, false)
|
||||
, _no_kMono (false)
|
||||
, _restart_component_is_synced (false)
|
||||
{
|
||||
using namespace std;
|
||||
IPluginFactory* factory = m->factory ();
|
||||
@ -1195,6 +1196,10 @@ VST3PI::VST3PI (std::shared_ptr<ARDOUR::VST3PluginModule> m, std::string unique_
|
||||
}
|
||||
}
|
||||
|
||||
#if !(defined PLATFORM_WINDOWS || defined __APPLE__) /* Linux only */
|
||||
_restart_component_is_synced = m->has_symbol ("yabridge_version");
|
||||
#endif
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (DEBUG_ENABLED (DEBUG::VST3Config)) {
|
||||
char fuid[33];
|
||||
@ -1505,7 +1510,7 @@ VST3PI::restartComponent (int32 flags)
|
||||
|
||||
if (flags & Vst::kReloadComponent) {
|
||||
Glib::Threads::Mutex::Lock pl (_process_lock, Glib::Threads::NOT_LOCK);
|
||||
if (!AudioEngine::instance ()->in_process_thread () && !_is_loading_state) {
|
||||
if (!AudioEngine::instance ()->in_process_thread () && !_is_loading_state && !_restart_component_is_synced) {
|
||||
pl.acquire ();
|
||||
} else {
|
||||
assert (0); // a plugin should not call this while processing
|
||||
@ -1523,7 +1528,7 @@ VST3PI::restartComponent (int32 flags)
|
||||
}
|
||||
if (flags & Vst::kParamValuesChanged) {
|
||||
Glib::Threads::Mutex::Lock pl (_process_lock, Glib::Threads::NOT_LOCK);
|
||||
if (!AudioEngine::instance ()->in_process_thread () && !_is_loading_state) {
|
||||
if (!AudioEngine::instance ()->in_process_thread () && !_is_loading_state && !_restart_component_is_synced) {
|
||||
pl.acquire ();
|
||||
}
|
||||
update_shadow_data ();
|
||||
@ -1538,7 +1543,7 @@ VST3PI::restartComponent (int32 flags)
|
||||
* changes are automatically picked up.
|
||||
*/
|
||||
Glib::Threads::Mutex::Lock pl (_process_lock, Glib::Threads::NOT_LOCK);
|
||||
if (!AudioEngine::instance ()->in_process_thread () && !_is_loading_state) {
|
||||
if (!AudioEngine::instance ()->in_process_thread () && !_is_loading_state && !_restart_component_is_synced) {
|
||||
/* Some plugins (e.g BlendEQ) call this from the process,
|
||||
* IPlugProcessor::ProcessBuffers. In that case taking the
|
||||
* _process_lock would deadlock.
|
||||
|
Loading…
Reference in New Issue
Block a user