VST3: fix deadlock when recalling program changes latency

The GUI thread may call set_program() which can triggers
the plugin directly calling restartComponent from the same
thread.
This commit is contained in:
Robin Gareus 2024-08-24 11:26:49 +02:00
parent 09bddcad10
commit c92c8c8fa2
No known key found for this signature in database
GPG key ID: A090BCE02CF57F04
2 changed files with 6 additions and 3 deletions

View file

@ -167,6 +167,8 @@ public:
Vst::ParamID index_to_id (uint32_t) const; Vst::ParamID index_to_id (uint32_t) const;
Glib::Threads::Mutex& process_lock () { return _process_lock; } Glib::Threads::Mutex& process_lock () { return _process_lock; }
bool& component_is_synced () { return _restart_component_is_synced; }
enum ParameterChange { BeginGesture, enum ParameterChange { BeginGesture,
EndGesture, EndGesture,

View file

@ -1025,9 +1025,10 @@ VST3Plugin::load_preset (PresetRecord r)
return false; return false;
} }
Glib::Threads::Mutex::Lock lx (_plug->process_lock ());
if (tmp[0] == "VST3-P") { if (tmp[0] == "VST3-P") {
Glib::Threads::Mutex::Lock lx (_plug->process_lock ());
PBD::Unwinder<bool> uw (_plug->component_is_synced (), true);
int program = PBD::atoi (tmp[2]); int program = PBD::atoi (tmp[2]);
assert (!r.user); assert (!r.user);
if (!_plug->set_program (program, 0)) { if (!_plug->set_program (program, 0)) {
@ -1044,14 +1045,14 @@ VST3Plugin::load_preset (PresetRecord r)
std::string const& fn = _preset_uri_map[r.uri]; std::string const& fn = _preset_uri_map[r.uri];
if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) { if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) {
Glib::Threads::Mutex::Lock lx (_plug->process_lock ());
PBD::Unwinder<bool> uw (_plug->component_is_synced (), true);
RAMStream stream (fn); RAMStream stream (fn);
ok = _plug->load_state (stream); ok = _plug->load_state (stream);
DEBUG_TRACE (DEBUG::VST3Config, string_compose ("VST3Plugin::load_preset: file %1 status %2\n", fn, ok ? "OK" : "error")); DEBUG_TRACE (DEBUG::VST3Config, string_compose ("VST3Plugin::load_preset: file %1 status %2\n", fn, ok ? "OK" : "error"));
} }
} }
lx.release ();
if (ok) { if (ok) {
Plugin::load_preset (r); Plugin::load_preset (r);
} }