mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-06 23:05:04 +01:00
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
3 changed files with 14 additions and 3 deletions
|
|
@ -40,6 +40,10 @@ public:
|
||||||
|
|
||||||
Steinberg::IPluginFactory* factory ();
|
Steinberg::IPluginFactory* factory ();
|
||||||
|
|
||||||
|
bool has_symbol (const char* name) const {
|
||||||
|
return NULL != fn_ptr (name);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void release_factory ();
|
void release_factory ();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -358,6 +358,8 @@ private:
|
||||||
|
|
||||||
/* work around UADx plugin crash */
|
/* work around UADx plugin crash */
|
||||||
bool _no_kMono;
|
bool _no_kMono;
|
||||||
|
/* work around yabridge threading */
|
||||||
|
bool _restart_component_is_synced;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Steinberg
|
} // namespace Steinberg
|
||||||
|
|
|
||||||
|
|
@ -1173,6 +1173,7 @@ VST3PI::VST3PI (std::shared_ptr<ARDOUR::VST3PluginModule> m, std::string unique_
|
||||||
, _block_rpc (0)
|
, _block_rpc (0)
|
||||||
, _rpc_queue (RouteProcessorChange::NoProcessorChange, false)
|
, _rpc_queue (RouteProcessorChange::NoProcessorChange, false)
|
||||||
, _no_kMono (false)
|
, _no_kMono (false)
|
||||||
|
, _restart_component_is_synced (false)
|
||||||
{
|
{
|
||||||
using namespace std;
|
using namespace std;
|
||||||
IPluginFactory* factory = m->factory ();
|
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
|
#ifndef NDEBUG
|
||||||
if (DEBUG_ENABLED (DEBUG::VST3Config)) {
|
if (DEBUG_ENABLED (DEBUG::VST3Config)) {
|
||||||
char fuid[33];
|
char fuid[33];
|
||||||
|
|
@ -1505,7 +1510,7 @@ VST3PI::restartComponent (int32 flags)
|
||||||
|
|
||||||
if (flags & Vst::kReloadComponent) {
|
if (flags & Vst::kReloadComponent) {
|
||||||
Glib::Threads::Mutex::Lock pl (_process_lock, Glib::Threads::NOT_LOCK);
|
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 ();
|
pl.acquire ();
|
||||||
} else {
|
} else {
|
||||||
assert (0); // a plugin should not call this while processing
|
assert (0); // a plugin should not call this while processing
|
||||||
|
|
@ -1523,7 +1528,7 @@ VST3PI::restartComponent (int32 flags)
|
||||||
}
|
}
|
||||||
if (flags & Vst::kParamValuesChanged) {
|
if (flags & Vst::kParamValuesChanged) {
|
||||||
Glib::Threads::Mutex::Lock pl (_process_lock, Glib::Threads::NOT_LOCK);
|
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 ();
|
pl.acquire ();
|
||||||
}
|
}
|
||||||
update_shadow_data ();
|
update_shadow_data ();
|
||||||
|
|
@ -1538,7 +1543,7 @@ VST3PI::restartComponent (int32 flags)
|
||||||
* changes are automatically picked up.
|
* changes are automatically picked up.
|
||||||
*/
|
*/
|
||||||
Glib::Threads::Mutex::Lock pl (_process_lock, Glib::Threads::NOT_LOCK);
|
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,
|
/* Some plugins (e.g BlendEQ) call this from the process,
|
||||||
* IPlugProcessor::ProcessBuffers. In that case taking the
|
* IPlugProcessor::ProcessBuffers. In that case taking the
|
||||||
* _process_lock would deadlock.
|
* _process_lock would deadlock.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue