added RCU handling of Session route list, and major use of shared_ptr<T> everywhere...
[ardour.git] / libs / ardour / route.cc
index 8d6ecf7eb5a0e8ea844eb3a3f669759770bc06cf..f3162f9131a7a80fa529b2f3e102abbfe7e0a34c 100644 (file)
@@ -756,7 +756,7 @@ Route::set_mute (bool yn, void *src)
 }
 
 int
-Route::add_redirect (Redirect *redirect, void *src, uint32_t* err_streams)
+Route::add_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_t* err_streams)
 {
        uint32_t old_rmo = redirect_max_outs;
 
@@ -767,12 +767,12 @@ Route::add_redirect (Redirect *redirect, void *src, uint32_t* err_streams)
        {
                Glib::RWLock::WriterLock lm (redirect_lock);
 
-               PluginInsert* pi;
-               PortInsert* porti;
+               boost::shared_ptr<PluginInsert> pi;
+               boost::shared_ptr<PortInsert> porti;
 
                uint32_t potential_max_streams = 0;
 
-               if ((pi = dynamic_cast<PluginInsert*>(redirect)) != 0) {
+               if ((pi = boost::dynamic_pointer_cast<PluginInsert>(redirect)) != 0) {
                        pi->set_count (1);
 
                        if (pi->input_streams() == 0) {
@@ -781,8 +781,8 @@ Route::add_redirect (Redirect *redirect, void *src, uint32_t* err_streams)
                        }
 
                        potential_max_streams = max(pi->input_streams(), pi->output_streams());
-
-               } else if ((porti = dynamic_cast<PortInsert*>(redirect)) != 0) {
+                       
+               } else if ((porti = boost::dynamic_pointer_cast<PortInsert>(redirect)) != 0) {
 
                        /* force new port inserts to start out with an i/o configuration
                           that matches this route's i/o configuration.
@@ -847,9 +847,9 @@ Route::add_redirects (const RedirectList& others, void *src, uint32_t* err_strea
 
                for (RedirectList::const_iterator i = others.begin(); i != others.end(); ++i) {
                        
-                       PluginInsert* pi;
+                       boost::shared_ptr<PluginInsert> pi;
                        
-                       if ((pi = dynamic_cast<PluginInsert*>(*i)) != 0) {
+                       if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
                                pi->set_count (1);
                                
                                uint32_t m = max(pi->input_streams(), pi->output_streams());
@@ -898,11 +898,6 @@ Route::clear_redirects (void *src)
 
        {
                Glib::RWLock::WriterLock lm (redirect_lock);
-
-               for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
-                       delete *i;
-               }
-
                _redirects.clear ();
        }
 
@@ -916,7 +911,7 @@ Route::clear_redirects (void *src)
 }
 
 int
-Route::remove_redirect (Redirect *redirect, void *src, uint32_t* err_streams)
+Route::remove_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_t* err_streams)
 {
        uint32_t old_rmo = redirect_max_outs;
 
@@ -948,13 +943,13 @@ Route::remove_redirect (Redirect *redirect, void *src, uint32_t* err_streams)
                                   run.
                                */
 
-                               Send* send;
-                               PortInsert* port_insert;
+                               boost::shared_ptr<Send> send;
+                               boost::shared_ptr<PortInsert> port_insert;
                                
-                               if ((send = dynamic_cast<Send*> (*i)) != 0) {
+                               if ((send = boost::dynamic_pointer_cast<Send> (*i)) != 0) {
                                        send->disconnect_inputs (this);
                                        send->disconnect_outputs (this);
-                               } else if ((port_insert = dynamic_cast<PortInsert*> (*i)) != 0) {
+                               } else if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (*i)) != 0) {
                                        port_insert->disconnect_inputs (this);
                                        port_insert->disconnect_outputs (this);
                                }
@@ -983,9 +978,9 @@ Route::remove_redirect (Redirect *redirect, void *src, uint32_t* err_streams)
                bool foo = false;
 
                for (i = _redirects.begin(); i != _redirects.end(); ++i) {
-                       PluginInsert* pi;
-
-                       if ((pi = dynamic_cast<PluginInsert*>(*i)) != 0) {
+                       boost::shared_ptr<PluginInsert> pi;
+                       
+                       if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
                                if (pi->is_generator()) {
                                        foo = true;
                                }
@@ -1032,7 +1027,7 @@ Route::_reset_plugin_counts (uint32_t* err_streams)
        
        for (r = _redirects.begin(); r != _redirects.end(); ++r) {
 
-               Insert *insert;
+               boost::shared_ptr<Insert> insert;
 
                /* do this here in case we bomb out before we get to the end of
                   this function.
@@ -1040,22 +1035,22 @@ Route::_reset_plugin_counts (uint32_t* err_streams)
 
                redirect_max_outs = max ((*r)->output_streams (), redirect_max_outs);
 
-               if ((insert = dynamic_cast<Insert*>(*r)) != 0) {
+               if ((insert = boost::dynamic_pointer_cast<Insert>(*r)) != 0) {
                        ++i_cnt;
-                       insert_map[insert->placement()].push_back (InsertCount (*insert));
+                       insert_map[insert->placement()].push_back (InsertCount (insert));
 
                        /* reset plugin counts back to one for now so
                           that we have a predictable, controlled
                           state to try to configure.
                        */
 
-                       PluginInsert* pi;
+                       boost::shared_ptr<PluginInsert> pi;
                
-                       if ((pi = dynamic_cast<PluginInsert*>(insert)) != 0) {
+                       if ((pi = boost::dynamic_pointer_cast<PluginInsert>(insert)) != 0) {
                                pi->set_count (1);
                        }
 
-               } else if (dynamic_cast<Send*> (*r) != 0) {
+               } else if (boost::dynamic_pointer_cast<Send> (*r) != 0) {
                        ++s_cnt;
                }
        }
@@ -1082,7 +1077,7 @@ Route::_reset_plugin_counts (uint32_t* err_streams)
 
        if (!insert_map[PreFader].empty()) {
                InsertCount& ic (insert_map[PreFader].back());
-               initial_streams = ic.insert.compute_output_streams (ic.cnt);
+               initial_streams = ic.insert->compute_output_streams (ic.cnt);
        } else {
                initial_streams = n_inputs ();
        }
@@ -1106,9 +1101,9 @@ Route::_reset_plugin_counts (uint32_t* err_streams)
        RedirectList::iterator prev = _redirects.end();
 
        for (r = _redirects.begin(); r != _redirects.end(); prev = r, ++r) {
-               Send* s;
+               boost::shared_ptr<Send> s;
 
-               if ((s = dynamic_cast<Send*> (*r)) != 0) {
+               if ((s = boost::dynamic_pointer_cast<Send> (*r)) != 0) {
                        if (r == _redirects.begin()) {
                                s->expect_inputs (n_inputs());
                        } else {
@@ -1131,11 +1126,11 @@ Route::apply_some_plugin_counts (list<InsertCount>& iclist)
 
        for (i = iclist.begin(); i != iclist.end(); ++i) {
                
-               if ((*i).insert.configure_io ((*i).cnt, (*i).in, (*i).out)) {
+               if ((*i).insert->configure_io ((*i).cnt, (*i).in, (*i).out)) {
                        return -1;
                }
                /* make sure that however many we have, they are all active */
-               (*i).insert.activate ();
+               (*i).insert->activate ();
        }
 
        return 0;
@@ -1148,7 +1143,7 @@ Route::check_some_plugin_counts (list<InsertCount>& iclist, int32_t required_inp
        
        for (i = iclist.begin(); i != iclist.end(); ++i) {
 
-               if (((*i).cnt = (*i).insert.can_support_input_configuration (required_inputs)) < 0) {
+               if (((*i).cnt = (*i).insert->can_support_input_configuration (required_inputs)) < 0) {
                        if (err_streams) {
                                *err_streams = required_inputs;
                        }
@@ -1156,7 +1151,7 @@ Route::check_some_plugin_counts (list<InsertCount>& iclist, int32_t required_inp
                }
                
                (*i).in = required_inputs;
-               (*i).out = (*i).insert.compute_output_streams ((*i).cnt);
+               (*i).out = (*i).insert->compute_output_streams ((*i).cnt);
 
                required_inputs = (*i).out;
        }
@@ -1200,7 +1195,7 @@ Route::copy_redirects (const Route& other, Placement placement, uint32_t* err_st
                
                for (RedirectList::const_iterator i = other._redirects.begin(); i != other._redirects.end(); ++i) {
                        if ((*i)->placement() == placement) {
-                               _redirects.push_back (Redirect::clone (**i));
+                               _redirects.push_back (Redirect::clone (*i));
                        }
                }
 
@@ -1218,7 +1213,6 @@ Route::copy_redirects (const Route& other, Placement placement, uint32_t* err_st
                                ++tmp;
 
                                if ((*i)->placement() == placement) {
-                                       delete *i;
                                        _redirects.erase (i);
                                }
                                
@@ -1237,10 +1231,7 @@ Route::copy_redirects (const Route& other, Placement placement, uint32_t* err_st
                } else {
                        
                        /* SUCCESSFUL COPY ATTEMPT: delete the redirects we removed pre-copy */
-
-                       for (RedirectList::iterator i = to_be_deleted.begin(); i != to_be_deleted.end(); ++i) {
-                               delete *i;
-                       }
+                       to_be_deleted.clear ();
                }
        }
 
@@ -1283,7 +1274,7 @@ Route::all_redirects_active (bool state)
 }
 
 struct RedirectSorter {
-    bool operator() (const Redirect *a, const Redirect *b) {
+    bool operator() (boost::shared_ptr<const Redirect> a, boost::shared_ptr<const Redirect> b) {
            return a->sort_key() < b->sort_key();
     }
 };
@@ -1442,13 +1433,13 @@ void
 Route::add_redirect_from_xml (const XMLNode& node)
 {
        const XMLProperty *prop;
-       Insert *insert = 0;
-       Send *send = 0;
 
        if (node.name() == "Send") {
                
+
                try {
-                       send = new Send (_session, node);
+                       boost::shared_ptr<Send> send (new Send (_session, node));
+                       add_redirect (send, this);
                } 
                
                catch (failed_constructor &err) {
@@ -1456,21 +1447,21 @@ Route::add_redirect_from_xml (const XMLNode& node)
                        return;
                }
                
-               add_redirect (send, this);
-               
        } else if (node.name() == "Insert") {
                
                try {
                        if ((prop = node.property ("type")) != 0) {
 
+                               boost::shared_ptr<Insert> insert;
+
                                if (prop->value() == "ladspa" || prop->value() == "Ladspa" || prop->value() == "vst") {
 
-                                       insert = new PluginInsert(_session, node);
+                                       insert.reset (new PluginInsert(_session, node));
                                        
                                } else if (prop->value() == "port") {
 
 
-                                       insert = new PortInsert (_session, node);
+                                       insert.reset (new PortInsert (_session, node));
 
                                } else {
 
@@ -1715,8 +1706,8 @@ Route::silence (jack_nframes_t nframes, jack_nframes_t offset)
                        
                        if (lm.locked()) {
                                for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
-                                       PluginInsert* pi;
-                                       if (!_active && (pi = dynamic_cast<PluginInsert*> (*i)) != 0) {
+                                       boost::shared_ptr<PluginInsert> pi;
+                                       if (!_active && (pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
                                                // skip plugins, they don't need anything when we're not active
                                                continue;
                                        }
@@ -1827,18 +1818,17 @@ Route::set_comment (string cmt, void *src)
 }
 
 bool
-Route::feeds (Route *o)
+Route::feeds (boost::shared_ptr<Route> other)
 {
        uint32_t i, j;
 
-       IO& other = *o;
        IO& self = *this;
        uint32_t no = self.n_outputs();
-       uint32_t ni = other.n_inputs ();
+       uint32_t ni = other->n_inputs ();
 
        for (i = 0; i < no; ++i) {
                for (j = 0; j < ni; ++j) {
-                       if (self.output(i)->connected_to (other.input(j)->name())) {
+                       if (self.output(i)->connected_to (other->input(j)->name())) {
                                return true;
                        }
                }
@@ -1852,7 +1842,7 @@ Route::feeds (Route *o)
 
                for (i = 0; i < no; ++i) {
                        for (j = 0; j < ni; ++j) {
-                               if ((*r)->output(i)->connected_to (other.input (j)->name())) {
+                               if ((*r)->output(i)->connected_to (other->input (j)->name())) {
                                        return true;
                                }
                        }
@@ -1867,7 +1857,7 @@ Route::feeds (Route *o)
                
                for (i = 0; i < no; ++i) {
                        for (j = 0; j < ni; ++j) {
-                               if (_control_outs->output(i)->connected_to (other.input (j)->name())) {
+                               if (_control_outs->output(i)->connected_to (other->input (j)->name())) {
                                        return true;
                                }
                        }
@@ -2118,10 +2108,10 @@ Route::toggle_monitor_input ()
 bool
 Route::has_external_redirects () const
 {
-       const PortInsert* pi;
+       boost::shared_ptr<const PortInsert> pi;
        
        for (RedirectList::const_iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
-               if ((pi = dynamic_cast<const PortInsert*>(*i)) != 0) {
+               if ((pi = boost::dynamic_pointer_cast<const PortInsert>(*i)) != 0) {
 
                        uint32_t no = pi->n_outputs();
 
@@ -2290,8 +2280,8 @@ Route::protect_automation ()
        }
        
        for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
-               PluginInsert* pi;
-               if ((pi = dynamic_cast<PluginInsert*> (*i)) != 0) {
+               boost::shared_ptr<PluginInsert> pi;
+               if ((pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
                        pi->protect_automation ();
                }
        }