Give the _sends member of InternalReturn its own mutex,
authorCarl Hetherington <carl@carlh.net>
Sun, 25 Mar 2012 20:30:26 +0000 (20:30 +0000)
committerCarl Hetherington <carl@carlh.net>
Sun, 25 Mar 2012 20:30:26 +0000 (20:30 +0000)
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
libs/ardour/internal_return.cc
libs/ardour/route.cc

index 1dff465cba09ed62d1455718d75dca607036fa2e..291b51896ca2434cc5e32dba604f5296561e5be2 100644 (file)
@@ -47,6 +47,8 @@ class InternalReturn : public Return
   private:
        /** sends that we are receiving data from */
        std::list<InternalSend*> _sends;
+       /** mutex to protect _sends */
+       Glib::Mutex _sends_mutex;
 };
 
 } // namespace ARDOUR
index 3c75c7957da016265101a6755ddd1ffb1a8d6118..6a3d20e5c9a17d94490345e4315620169c9be27d 100644 (file)
@@ -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<InternalSend*>::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<InternalSend*>::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);
 }
 
index f5bd4dc636a259113d72f832dbad066590d8c819..3cb71fad84fb07f6626acd9aab53080fed2372af 100644 (file)
@@ -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) {