13
0

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."
This commit is contained in:
Robin Gareus 2020-11-14 02:45:02 +01:00
parent f41d752cb3
commit fec37c58bd
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
2 changed files with 10 additions and 3 deletions

View File

@ -440,6 +440,8 @@ private:
PBD::TimingStats _timing_stats;
volatile gint _stat_reset;
volatile gint _flush;
};
} // namespace ARDOUR

View File

@ -91,6 +91,7 @@ PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> 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<boost::shared_ptr<Plugin> >::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 ()) {