From a0bdf877206b64e7055e2392b9198c055d96038d Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Fri, 26 Jun 2020 17:46:34 +0200 Subject: [PATCH] Fix potential deadlock when adding sidechain port Previously add_remove_sidechain() released the process-lock (to create the I/O ports), while keeping a processor writer-lock. Meanwhile the auto-connect thread may be woken up to perform a latency update. This thread takes the process-lock and then stalls, waiting for a processor reader-lock. Then add_remove_sidechain() continues and tries to re-acquire the process-lock. --- libs/ardour/route.cc | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index b477f27a32..d716020309 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -2256,7 +2256,7 @@ Route::reorder_processors (const ProcessorList& new_order, ProcessorStreams* err bool Route::add_remove_sidechain (boost::shared_ptr proc, bool add) { - if (_session.actively_recording ()) { + if (_session.actively_recording () || _in_sidechain_setup) { return false; } @@ -2278,11 +2278,8 @@ Route::add_remove_sidechain (boost::shared_ptr proc, bool add) } { - Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ()); // take before Writerlock to avoid deadlock - Glib::Threads::RWLock::WriterLock lm (_processor_lock); PBD::Unwinder uw (_in_sidechain_setup, true); - lx.release (); // IO::add_port() and ~IO takes process lock - XXX check if this is safe if (add) { if (!pi->add_sidechain ()) { return false; @@ -2293,11 +2290,15 @@ Route::add_remove_sidechain (boost::shared_ptr proc, bool add) } } - lx.acquire (); + Glib::Threads::Mutex::Lock lx (AudioEngine::instance()->process_lock ()); // take before Writerlock to avoid deadlock + Glib::Threads::RWLock::WriterLock lm (_processor_lock); + list > c = try_configure_processors_unlocked (n_inputs (), 0); - lx.release (); if (c.empty()) { + lm.release (); + lx.release (); + if (add) { pi->del_sidechain (); } else { @@ -2306,7 +2307,7 @@ Route::add_remove_sidechain (boost::shared_ptr proc, bool add) } return false; } - lx.acquire (); + configure_processors_unlocked (0, &lm); }