clear activation_sets component of Graph, thus restoring full Route deletion
authorPaul Davis <paul@linuxaudiosystems.com>
Thu, 24 Jun 2010 16:20:32 +0000 (16:20 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Thu, 24 Jun 2010 16:20:32 +0000 (16:20 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@7298 d708f5d6-7413-0410-9779-e7cbd77b26cf

libs/ardour/ardour/graph.h
libs/ardour/graph.cc
libs/ardour/session.cc

index f38ef1272161393c5d8f1edebfba77118fba8b0f..a6863fc86be1420bec5a2aaf6bdc41b93263419c 100644 (file)
@@ -81,6 +81,8 @@ class Graph : public SessionHandleRef
 
        void process_one_route (Route * route);
 
+        void clear_other_chain ();
+
     protected:
         virtual void session_going_away ();
 
@@ -95,11 +97,10 @@ class Graph : public SessionHandleRef
        std::vector<GraphNode *> _trigger_queue;
        pthread_mutex_t _trigger_mutex;
 
-
        sem_t _execution_sem;
-
        sem_t _callback_start_sem;
        sem_t _callback_done_sem;
+       sem_t _cleanup_sem;
 
        volatile gint _execution_tokens;
        volatile gint _finished_refcount;
index 5b6a42437b12932b3ef16c77e0aa0b414fe7caa8..dd56cb98805a0fd70507d8bb0fea6ff100de6c7e 100644 (file)
@@ -17,7 +17,7 @@
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
 */
-
+#include <iostream>
 #include <stdio.h>
 #include <cmath>
 
@@ -38,6 +38,7 @@
 
 using namespace ARDOUR;
 using namespace PBD;
+using namespace std;
 
 
 Graph::Graph (Session & session) 
@@ -48,6 +49,7 @@ Graph::Graph (Session & session)
 
         sem_init( &_callback_start_sem, 0, 0 );
         sem_init( &_callback_done_sem,  0, 0 );
+        sem_init( &_cleanup_sem,  0, 0 );
 
         _execution_tokens = 0;
 
@@ -100,7 +102,7 @@ Graph::session_going_away()
 
         sem_post( &_callback_start_sem);
 
-        for (std::list<pthread_t>::iterator i = _thread_list.begin(); i != _thread_list.end(); i++) {
+        for (list<pthread_t>::iterator i = _thread_list.begin(); i != _thread_list.end(); i++) {
                 void* status;
                 pthread_join (*i, &status);
         }
@@ -113,6 +115,33 @@ Graph::session_going_away()
         _trigger_queue.clear();
 }
 
+void
+Graph::clear_other_chain ()
+{
+        while (1) {
+                pthread_mutex_lock (&_swap_mutex);
+                if (_setup_chain != _pending_chain) {
+
+                        for (node_list_t::iterator ni=_nodes_rt[_setup_chain].begin(); ni!=_nodes_rt[_setup_chain].end(); ni++) {
+                                (*ni)->_activation_set[_setup_chain].clear();
+                        }
+
+                        _nodes_rt[_setup_chain].clear ();
+                        _init_trigger_list[_setup_chain].clear ();
+                        pthread_mutex_unlock (&_swap_mutex);
+
+                        return;
+                }
+                pthread_mutex_unlock (&_swap_mutex);
+                /* setup chain == pending chain - we have
+                   to wait till this is no longer true.
+                */
+                cerr << "Wait for setup != pending (currently " << _setup_chain << '/' << _pending_chain << endl;
+                int ret = sem_wait (&_cleanup_sem);
+                cerr << " back from that wait, ret = " << ret << endl;
+        }
+}
+
 void
 Graph::prep()
 {
@@ -123,9 +152,11 @@ Graph::prep()
                 // we got the swap mutex.
                 if (_current_chain != _pending_chain)
                 {
-                        //printf ("chain swap ! %d -> %d\n", _current_chain, _pending_chain);
+                        printf ("chain swap ! %d -> %d\n", _current_chain, _pending_chain);
                         _setup_chain = _current_chain;
                         _current_chain = _pending_chain;
+                        printf ("\tNOW: setup %d current %d pending %d\n", _setup_chain, _current_chain, _pending_chain);
+                        sem_post (&_cleanup_sem);
                 }
                 pthread_mutex_unlock (&_swap_mutex);
         }
@@ -295,7 +326,7 @@ Graph::run_one()
                 to_run = 0;
         }
 
-        int wakeup = std::min ((int) _execution_tokens, (int) _trigger_queue.size());
+        int wakeup = min ((int) _execution_tokens, (int) _trigger_queue.size());
         _execution_tokens -= wakeup;
 
         for (int i=0; i<wakeup; i++ ) {
index 94945b95c27f9457839bdfdfde4b0cb4d0788b1e..7a4a4c4e9ff556d4b9fab81544b3c3a6a76c13be 100644 (file)
@@ -1317,9 +1317,7 @@ Session::resort_routes ()
                return;
        }
 
-
        {
-
                RCUWriter<RouteList> writer (routes);
                shared_ptr<RouteList> r = writer.get_copy ();
                resort_routes_using (r);
@@ -1381,7 +1379,7 @@ Session::resort_routes_using (shared_ptr<RouteList> r)
        RouteSorter cmp;
        r->sort (cmp);
 
-       route_graph->rechain( r );
+       route_graph->rechain (r);
 
 #ifndef NDEBUG
         DEBUG_TRACE (DEBUG::Graph, "Routes resorted, order follows:\n");
@@ -2081,7 +2079,7 @@ Session::remove_route (shared_ptr<Route> route)
 
                /* writer goes out of scope, forces route list update */
        }
-        
+
         update_route_solo_state ();
        update_session_range_location_marker ();
 
@@ -2105,6 +2103,11 @@ Session::remove_route (shared_ptr<Route> route)
        update_latency_compensation (false, false);
        set_dirty();
 
+        /* flush references out of the graph
+         */
+
+        route_graph->clear_other_chain ();
+
        /* get rid of it from the dead wood collection in the route list manager */
 
        /* XXX i think this is unsafe as it currently stands, but i am not sure. (pd, october 2nd, 2006) */