summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2019-10-28 17:23:54 -0600
committerPaul Davis <paul@linuxaudiosystems.com>2019-10-28 17:23:54 -0600
commit7d3c2a4feee924ed4e12cd2048ae01a7db2e92a9 (patch)
tree2dd8542906ae6ae3637274550e9b3da64f310c3b /libs
parent706a9ab59f070024b50d4f504113eb57fc49d316 (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.h4
-rw-r--r--libs/ardour/route.cc6
-rw-r--r--libs/ardour/session.cc28
-rw-r--r--libs/ardour/session_process.cc2
-rw-r--r--libs/ardour/session_state.cc2
-rw-r--r--libs/ardour/session_transport.cc4
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 ();
}