From fec37c58bd3bff574af0baf5d10932b14feb8723 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sat, 14 Nov 2020 02:45:02 +0100 Subject: [PATCH] Flush plugins from rt-thread, prevent concurrent processing Route::realtime_handle_transport_stopped() does have insufficient information (PostTransportLocate), so "flush" is called from Route::non_realtime_transport_stop in the butler thread. However plugin de/activate() must not be called concurrently with processing. e.g. https://lv2plug.in/ns/lv2core explicitly states: "Hosts MUST guarantee that: An Instantiation function for an instance is never called concurrently with any other function for that instance." --- libs/ardour/ardour/plugin_insert.h | 2 ++ libs/ardour/plugin_insert.cc | 11 ++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/libs/ardour/ardour/plugin_insert.h b/libs/ardour/ardour/plugin_insert.h index d1fa7e951e..f15967640b 100644 --- a/libs/ardour/ardour/plugin_insert.h +++ b/libs/ardour/ardour/plugin_insert.h @@ -440,6 +440,8 @@ private: PBD::TimingStats _timing_stats; volatile gint _stat_reset; + + volatile gint _flush; }; } // namespace ARDOUR diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc index 9aab3e9f18..ebb777da2d 100644 --- a/libs/ardour/plugin_insert.cc +++ b/libs/ardour/plugin_insert.cc @@ -91,6 +91,7 @@ PluginInsert::PluginInsert (Session& s, boost::shared_ptr plug) , _bypass_port (UINT32_MAX) , _inverted_bypass_enable (false) , _stat_reset (0) + , _flush (0) { /* the first is the master */ @@ -714,9 +715,7 @@ PluginInsert::deactivate () void PluginInsert::flush () { - for (vector >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { - (*i)->flush (); - } + g_atomic_int_set (&_flush, 1); } void @@ -1269,6 +1268,12 @@ PluginInsert::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sa _timing_stats.reset (); } + if (g_atomic_int_compare_and_exchange (&_flush, 1, 0)) { + for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) { + (*i)->flush (); + } + } + if (_pending_active) { #if defined MIXBUS && defined NDEBUG if (!is_channelstrip ()) {