diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2019-10-28 17:23:54 -0600 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2019-10-28 17:23:54 -0600 |
commit | 7d3c2a4feee924ed4e12cd2048ae01a7db2e92a9 (patch) | |
tree | 2dd8542906ae6ae3637274550e9b3da64f310c3b /libs | |
parent | 706a9ab59f070024b50d4f504113eb57fc49d316 (diff) |
provide a mechanism to decide if Session::update_latency_compensation() is being called as part of a callback from the backend.
If it is, do not call AudioEngine::update_latencies() to avoid JACK1-style deadlock
Diffstat (limited to 'libs')
-rw-r--r-- | libs/ardour/ardour/session.h | 4 | ||||
-rw-r--r-- | libs/ardour/route.cc | 6 | ||||
-rw-r--r-- | libs/ardour/session.cc | 28 | ||||
-rw-r--r-- | libs/ardour/session_process.cc | 2 | ||||
-rw-r--r-- | libs/ardour/session_state.cc | 2 | ||||
-rw-r--r-- | libs/ardour/session_transport.cc | 4 |
6 files changed, 28 insertions, 18 deletions
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index cb2e781ecf..2b56a1dccd 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -1238,7 +1238,7 @@ protected: void set_sample_rate (samplecnt_t nframes); friend class Route; - void update_latency_compensation (bool force = false); + void update_latency_compensation (bool force, bool called_from_backend); /* transport API */ @@ -1401,7 +1401,7 @@ private: boost::scoped_ptr<SessionDirectory> _session_dir; void hookup_io (); - void graph_reordered (); + void graph_reordered (bool called_from_backend); /** current snapshot name, without the .ardour suffix */ void set_snapshot_name (const std::string &); diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 19c8718d18..ae81a31147 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -1145,7 +1145,7 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor> (*i)->activate (); } - (*i)->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false)); + (*i)->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false, false)); boost::shared_ptr<Send> send; if ((send = boost::dynamic_pointer_cast<Send> (*i))) { @@ -1612,7 +1612,7 @@ Route::replace_processor (boost::shared_ptr<Processor> old, boost::shared_ptr<Pr sub->enable (true); } - sub->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false)); + sub->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false, false)); } reset_instrument_info (); @@ -3024,7 +3024,7 @@ Route::set_processor_state (const XMLNode& node) for (ProcessorList::const_iterator i = _processors.begin(); i != _processors.end(); ++i) { (*i)->set_owner (this); - (*i)->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false)); + (*i)->ActiveChanged.connect_same_thread (*this, boost::bind (&Session::update_latency_compensation, &_session, false, false)); boost::shared_ptr<PluginInsert> pi; diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 44646aa7f9..c180c96fdc 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -1343,7 +1343,7 @@ Session::hookup_io () graph reorder event. */ - graph_reordered (); + graph_reordered (false); /* update the full solo state, which can't be correctly determined on a per-route basis, but @@ -3023,7 +3023,7 @@ Session::add_routes (RouteList& new_routes, bool input_auto_connect, bool output * that the addition is done, call it explicitly. */ - graph_reordered (); + graph_reordered (false); set_dirty(); @@ -3251,7 +3251,7 @@ Session::add_internal_send (boost::shared_ptr<Route> dest, boost::shared_ptr<Pro sender->add_aux_send (dest, before); - graph_reordered (); + graph_reordered (false); } void @@ -3341,7 +3341,7 @@ Session::remove_routes (boost::shared_ptr<RouteList> routes_to_remove) } update_route_solo_state (); - update_latency_compensation (); + update_latency_compensation (false, false); set_dirty(); /* Re-sort routes to remove the graph's current references to the one that is @@ -5213,7 +5213,7 @@ Session::is_auditioning () const } void -Session::graph_reordered () +Session::graph_reordered (bool called_from_backend) { /* don't do this stuff if we are setting up connections from a set_state() call or creating new tracks. Ditto for deletion. @@ -5228,7 +5228,7 @@ Session::graph_reordered () /* force all diskstreams to update their capture offset values to * reflect any changes in latencies within the graph. */ - update_latency_compensation (true); + update_latency_compensation (true, called_from_backend); } /** @return Number of samples that there is disk space available to write, @@ -6491,7 +6491,7 @@ Session::set_worst_input_latency () } void -Session::update_latency_compensation (bool force_whole_graph) +Session::update_latency_compensation (bool force_whole_graph, bool called_from_backend) { /* Called to update Ardour's internal latency values and compensation * planning. Typically case is from within ::graph_reordered() @@ -6519,8 +6519,11 @@ Session::update_latency_compensation (bool force_whole_graph) if (some_track_latency_changed || force_whole_graph) { DEBUG_TRACE (DEBUG::LatencyCompensation, "update_latency_compensation: delegate to engine\n"); + /* cannot hold lock while engine initiates a full latency callback */ + lx.release (); + /* next call will ask the backend up update its latencies. * * The semantics of how the backend does this are not well @@ -6533,10 +6536,17 @@ Session::update_latency_compensation (bool force_whole_graph) * this call. Others (JACK1) will do so synchronously, and in * those cases this call will return until the backend latency * callback is complete. + * + * Further, if this is called as part of a backend callback, + * then we have to follow the JACK1 rule that we cannot call + * back into the backend during such a callback (otherwise + * deadlock ensues). */ - if (!AudioEngine::instance()->in_process_thread()) { + + if (!called_from_backend) { _engine.update_latencies (); } + } else { DEBUG_TRACE (DEBUG::LatencyCompensation, "update_latency_compensation: directly apply to routes\n"); boost::shared_ptr<RouteList> r = routes.reader (); @@ -6825,7 +6835,7 @@ Session::auto_connect_thread_run () */ while (g_atomic_int_and (&_latency_recompute_pending, 0)) { Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); - update_latency_compensation (); + update_latency_compensation (false, false); } } diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc index 7633266d5a..13acece3db 100644 --- a/libs/ardour/session_process.cc +++ b/libs/ardour/session_process.cc @@ -536,7 +536,7 @@ Session::process_with_events (pframes_t nframes) if (this_event && this_event->action_sample <= end_sample && this_event->action_sample >= _transport_sample) { /* this isn't quite right for reverse play */ samples_moved = (samplecnt_t) (this_event->action_sample - _transport_sample); - DEBUG_TRACE (DEBUG::Transport, string_compose ("sub-loop2 plan to move transport by %1 (%2 @ %3)\n", samples_moved, nframes, _transport_speed)); + DEBUG_TRACE (DEBUG::Transport, string_compose ("sub-loop2 (for %4)plan to move transport by %1 (%2 @ %3)\n", samples_moved, nframes, _transport_speed, enum_2_string (this_event->type))); this_nframes = abs (floor(samples_moved / _transport_speed)); } diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index dacda4d9ae..7dde0047da 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -280,7 +280,7 @@ Session::post_engine_init () /* crossfades require sample rate knowledge */ SndFileSource::setup_standard_crossfades (*this, sample_rate()); - _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this)); + _engine.GraphReordered.connect_same_thread (*this, boost::bind (&Session::graph_reordered, this, false)); _engine.MidiSelectionPortsChanged.connect_same_thread (*this, boost::bind (&Session::rewire_midi_selection_ports, this)); DiskReader::allocate_working_buffers(); diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index 6062b20518..317304eb11 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -1535,7 +1535,7 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished) (*i)->non_realtime_transport_stop (_transport_sample, !(ptw & PostTransportLocate)); } - update_latency_compensation (); + update_latency_compensation (false, false); } /* If we are not synced to a "true" external master, and we're not @@ -1920,7 +1920,7 @@ Session::route_processors_changed (RouteProcessorChange c) } resort_routes (); - update_latency_compensation (); + update_latency_compensation (false, false); set_dirty (); } |