[Summary] Moved RCU writer out of loop for remove tracks method

This commit is contained in:
GZharun 2014-09-17 17:40:23 +03:00
parent e2572a0933
commit 4062dafc8b

View file

@ -2953,17 +2953,18 @@ Session::add_internal_send (boost::shared_ptr<Route> dest, boost::shared_ptr<Pro
void
Session::remove_routes (boost::shared_ptr<RouteList> routes_to_remove)
{
for (RouteList::iterator iter = routes_to_remove->begin(); iter != routes_to_remove->end(); ++iter) {
{ //RCU Writer scope
RCUWriter<RouteList> writer (routes);
boost::shared_ptr<RouteList> rs = writer.get_copy ();
if (*iter == _master_out || *iter == _master_track) {
return;
}
(*iter)->set_solo (false, this);
{
RCUWriter<RouteList> writer (routes);
boost::shared_ptr<RouteList> rs = writer.get_copy ();
for (RouteList::iterator iter = routes_to_remove->begin(); iter != routes_to_remove->end(); ++iter) {
if (*iter == _master_out || *iter == _master_track) {
return;
}
(*iter)->set_solo (false, this);
rs->remove (*iter);
@ -2983,59 +2984,60 @@ Session::remove_routes (boost::shared_ptr<RouteList> routes_to_remove)
if (*iter == _master_track) {
_master_track.reset ();
}
update_route_solo_state ();
/* writer goes out of scope, forces route list update */
}
update_route_solo_state ();
// We need to disconnect the route's inputs and outputs
(*iter)->input()->disconnect (0);
(*iter)->output()->disconnect (0);
/* if the route had internal sends sending to it, remove them */
if ((*iter)->internal_return()) {
// We need to disconnect the route's inputs and outputs
boost::shared_ptr<RouteList> r = routes.reader ();
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
boost::shared_ptr<Send> s = (*i)->internal_send_for (*iter);
if (s) {
(*i)->remove_processor (s);
(*iter)->input()->disconnect (0);
(*iter)->output()->disconnect (0);
/* if the route had internal sends sending to it, remove them */
if ((*iter)->internal_return()) {
boost::shared_ptr<RouteList> r = routes.reader ();
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
boost::shared_ptr<Send> s = (*i)->internal_send_for (*iter);
if (s) {
(*i)->remove_processor (s);
}
}
}
}
/* if the monitoring section had a pointer to this route, remove it */
if (_monitor_out && !(*iter)->is_master() && !(*iter)->is_monitor()) {
Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
PBD::Unwinder<bool> uw (ignore_route_processor_changes, true);
(*iter)->remove_aux_or_listen (_monitor_out);
}
boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*iter);
if (mt && mt->step_editing()) {
if (_step_editors > 0) {
_step_editors--;
/* if the monitoring section had a pointer to this route, remove it */
if (_monitor_out && !(*iter)->is_master() && !(*iter)->is_monitor()) {
Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
PBD::Unwinder<bool> uw (ignore_route_processor_changes, true);
(*iter)->remove_aux_or_listen (_monitor_out);
}
}
/* try to cause everyone to drop their references
* and unregister ports from the backend
*/
for (size_t i = 0; i < (*iter)->input()->ports().num_ports(); ++i) {
_engine.unregister_port((*iter)->input()->ports().port(i));
PortEngine::PortHandle handle = (*iter)->input()->ports().port(i)->port_handle();
_engine.current_backend()->unregister_port(handle);
}
for (size_t i = 0; i < (*iter)->output()->ports().num_ports(); ++i) {
_engine.unregister_port((*iter)->output()->ports().port(i));
PortEngine::PortHandle handle = (*iter)->output()->ports().port(i)->port_handle();
_engine.current_backend()->unregister_port(handle);
}
(*iter)->drop_references ();
boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (*iter);
if (mt && mt->step_editing()) {
if (_step_editors > 0) {
_step_editors--;
}
}
/* try to cause everyone to drop their references
* and unregister ports from the backend
*/
for (size_t i = 0; i < (*iter)->input()->ports().num_ports(); ++i) {
_engine.unregister_port((*iter)->input()->ports().port(i));
PortEngine::PortHandle handle = (*iter)->input()->ports().port(i)->port_handle();
_engine.current_backend()->unregister_port(handle);
}
for (size_t i = 0; i < (*iter)->output()->ports().num_ports(); ++i) {
_engine.unregister_port((*iter)->output()->ports().port(i));
PortEngine::PortHandle handle = (*iter)->output()->ports().port(i)->port_handle();
_engine.current_backend()->unregister_port(handle);
}
(*iter)->drop_references ();
}
}
/* writer goes out of scope, forces route list update */
} // end of RCU Writer scope
update_latency_compensation ();
set_dirty();