From 5599cdb911a9bbbd3f3f82a5d71ac7a850cb2d08 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Thu, 25 Oct 2018 02:00:08 +0200 Subject: [PATCH] Fix race-condition/deadlock, plugin-copy while rolling lili93's session (#ardour) triggered this w/jackd 512fpp: Drag/Drop copy a latent plugin from one track to another while rolling. The GUI-thread as well as the auto-connect thread concurrently call jack_recompute_total_latencies(). The auto-connect thread holds a process lock while doing so. The GUI does not use any mutexes. This randomly deadlocks in libjack. backtrace: https://pastebin.com/6m3KGhWS --- libs/ardour/ardour/session.h | 2 ++ libs/ardour/session.cc | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index c18b76a984..b5997a3a83 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -1540,6 +1540,8 @@ private: ChanCount output_offset; }; + Glib::Threads::Mutex _update_latency_lock; + typedef std::queue AutoConnectQueue; Glib::Threads::Mutex _auto_connect_queue_lock; AutoConnectQueue _auto_connect_queue; diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 228c52ef08..da4421d4a2 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -6944,6 +6944,17 @@ Session::update_latency_compensation (bool force_whole_graph) if (_state_of_the_state & (InitialConnecting|Deletion)) { return; } + /* this lock is not usually contended, but under certain conditions, + * update_latency_compensation may be called concurrently. + * e.g. drag/drop copy a latent plugin while rolling. + * GUI thread (via route_processors_changed) and + * auto_connect_thread_run may race. + */ + Glib::Threads::Mutex::Lock lx (_update_latency_lock, Glib::Threads::TRY_LOCK); + if (!lx.locked()) { + /* no need to do this twice */ + return; + } bool some_track_latency_changed = update_route_latency (false, false);