From ca1de500041e2739cf623bc94b090ff82ee6052c Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 25 Mar 2012 20:30:26 +0000 Subject: Give the _sends member of InternalReturn its own mutex, rather than using the process lock to protect it. Prevents a deadlock when removing an aux send causes it to remove itself from its return (#4712). git-svn-id: svn://localhost/ardour2/branches/3.0@11760 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/ardour/internal_return.h | 2 ++ libs/ardour/internal_return.cc | 20 +++++++++----------- libs/ardour/route.cc | 1 - 3 files changed, 11 insertions(+), 12 deletions(-) (limited to 'libs/ardour') diff --git a/libs/ardour/ardour/internal_return.h b/libs/ardour/ardour/internal_return.h index 1dff465cba..291b51896c 100644 --- a/libs/ardour/ardour/internal_return.h +++ b/libs/ardour/ardour/internal_return.h @@ -47,6 +47,8 @@ class InternalReturn : public Return private: /** sends that we are receiving data from */ std::list _sends; + /** mutex to protect _sends */ + Glib::Mutex _sends_mutex; }; } // namespace ARDOUR diff --git a/libs/ardour/internal_return.cc b/libs/ardour/internal_return.cc index 3c75c7957d..6a3d20e5c9 100644 --- a/libs/ardour/internal_return.cc +++ b/libs/ardour/internal_return.cc @@ -43,11 +43,13 @@ InternalReturn::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*e return; } - /* _sends is only modified with the process lock held, so this is ok, I think */ - - for (list::iterator i = _sends.begin(); i != _sends.end(); ++i) { - if ((*i)->active ()) { - bufs.merge_from ((*i)->get_buffers(), nframes); + Glib::Mutex::Lock lm (_sends_mutex, Glib::TRY_LOCK); + + if (lm.locked ()) { + for (list::iterator i = _sends.begin(); i != _sends.end(); ++i) { + if ((*i)->active ()) { + bufs.merge_from ((*i)->get_buffers(), nframes); + } } } @@ -57,18 +59,14 @@ InternalReturn::run (BufferSet& bufs, framepos_t /*start_frame*/, framepos_t /*e void InternalReturn::add_send (InternalSend* send) { - /* caller must hold process lock */ - assert (!AudioEngine::instance()->process_lock().trylock()); - + Glib::Mutex::Lock lm (_sends_mutex); _sends.push_back (send); } void InternalReturn::remove_send (InternalSend* send) { - /* caller must hold process lock */ - assert (!AudioEngine::instance()->process_lock().trylock()); - + Glib::Mutex::Lock lm (_sends_mutex); _sends.remove (send); } diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index f5bd4dc636..3cb71fad84 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -2606,7 +2606,6 @@ Route::add_send_to_internal_return (InternalSend* send) void Route::remove_send_from_internal_return (InternalSend* send) { - Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); Glib::RWLock::ReaderLock rm (_processor_lock); for (ProcessorList::const_iterator x = _processors.begin(); x != _processors.end(); ++x) { -- cgit v1.2.3