From b8551eed7ef7ef691e274e7e7e3602a59c0b0c14 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Fri, 27 Oct 2023 00:39:03 +0200 Subject: [PATCH] Properly unload VST3 plugins The InstrumentSelector keeps a PluginPtr reference to all instruments. By default Ardour does not destroy the editor at exit, So 3 instances of Instrument Selector can remain * TriggerClipPicker in the editor sidebar (owned by _editor) * TriggerClipPicker on the TriggerPage (owned by trigger_page) * SoundFileOmega (sfbrowser owned by Editor) If a shared_ptr reference is retained, VST3 Module is not unloaded at exit. This leads to issues with various plugins. eg. Reason Rack does not terminate, Ardour hangs at exit. --- gtk2_ardour/ardour_ui.cc | 3 +++ gtk2_ardour/instrument_selector.cc | 11 +++++++++++ gtk2_ardour/instrument_selector.h | 3 +++ 3 files changed, 17 insertions(+) diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 3713af741c..bac5f11826 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -146,6 +146,7 @@ #include "gui_object.h" #include "gui_thread.h" #include "idleometer.h" +#include "instrument_selector.h" #include "io_plugin_window.h" #include "keyboard.h" #include "keyeditor.h" @@ -868,6 +869,8 @@ ARDOUR_UI::~ARDOUR_UI () recorder->cleanup (); } + InstrumentSelector::DropPluginInfoPtr (); + if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) { // don't bother at 'real' exit. the OS cleans up for us. delete big_clock; big_clock = 0; diff --git a/gtk2_ardour/instrument_selector.cc b/gtk2_ardour/instrument_selector.cc index e5ef5fc912..3c06ba3ad9 100644 --- a/gtk2_ardour/instrument_selector.cc +++ b/gtk2_ardour/instrument_selector.cc @@ -29,6 +29,8 @@ using namespace Gtk; using namespace ARDOUR; +sigc::signal InstrumentSelector::DropPluginInfoPtr; + InstrumentSelector::InstrumentSelector (InstrumentListDisposition disp) : _reasonable_synth_id (0) , _gmsynth_id (UINT32_MAX) @@ -37,6 +39,15 @@ InstrumentSelector::InstrumentSelector (InstrumentListDisposition disp) refill (); PluginManager::instance ().PluginListChanged.connect (_update_connection, invalidator (*this), boost::bind (&InstrumentSelector::refill, this), gui_context()); + DropPluginInfoPtr.connect (sigc::mem_fun (*this, &InstrumentSelector::drop_plugin_ptr)); +} + +void +InstrumentSelector::drop_plugin_ptr() +{ + unset_model (); + clear (); + _instrument_list->clear (); } void diff --git a/gtk2_ardour/instrument_selector.h b/gtk2_ardour/instrument_selector.h index d2e180c614..687b40b681 100644 --- a/gtk2_ardour/instrument_selector.h +++ b/gtk2_ardour/instrument_selector.h @@ -50,6 +50,8 @@ public: ARDOUR::PluginInfoPtr selected_instrument () const; std::string selected_instrument_name () const; + static sigc::signal DropPluginInfoPtr; + private: struct InstrumentListColumns : public Gtk::TreeModel::ColumnRecord { InstrumentListColumns() { @@ -62,6 +64,7 @@ private: void build_instrument_list(); void refill(); + void drop_plugin_ptr(); std::string _longest_instrument_name;