From 6a82aa392c6dd0f4057f5ae37095cf1fd4478626 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Fri, 30 Apr 2021 03:40:32 +0200 Subject: [PATCH] Fix deadlock when duplicating regions w/ripple This is an initial work-around for signal emission with Playlist:region_lock held: Playlist::duplicate() takes RegionWriteLock() and then calls RegionFactory::create(). The newly created region does NOT have property-changes suspended, and the RegionFactory can change region-properties which results in signal-emission. This in turn can lead to a call Editor::session_gui_extents() -> ARDOUR::Playlist::get_extent() -> Playlist::RegionReadLock which deadlocks: https://pastebin.com/84rSbsA3 Eventually we need a mechanism to create regions with ->suspend_property_changes() and add it to the playlist's thawlist (pass a thawlist to the region-factory). --- gtk2_ardour/recorder_ui.cc | 13 ++++++++++++- gtk2_ardour/recorder_ui.h | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/gtk2_ardour/recorder_ui.cc b/gtk2_ardour/recorder_ui.cc index c66823d6f5..874b64bf72 100644 --- a/gtk2_ardour/recorder_ui.cc +++ b/gtk2_ardour/recorder_ui.cc @@ -393,7 +393,7 @@ RecorderUI::set_session (Session* s) _session->config.ParameterChanged.connect (_session_connections, invalidator (*this), boost::bind (&RecorderUI::parameter_changed, this, _1), gui_context ()); - Region::RegionPropertyChanged.connect (*this, invalidator (*this), boost::bind (&RecorderUI::gui_extents_changed, this), gui_context()); + Region::RegionPropertyChanged.connect (*this, invalidator (*this), boost::bind (&RecorderUI::region_changed, this, _1, _2), gui_context()); _session->StartTimeChanged.connect (_session_connections, invalidator (*this), boost::bind (&RecorderUI::gui_extents_changed, this), gui_context()); _session->EndTimeChanged.connect (_session_connections, invalidator (*this), boost::bind (&RecorderUI::gui_extents_changed, this), gui_context()); _session->RecordStateChanged.connect (_session_connections, invalidator (*this), boost::bind (&RecorderUI::update_sensitivity, this), gui_context()); @@ -794,6 +794,17 @@ RecorderUI::port_pretty_name_changed (string pn) } } +void +RecorderUI::region_changed (boost::shared_ptr, PBD::PropertyChange const& what_changed) +{ + PBD::PropertyChange interests; + interests.add (ARDOUR::Properties::position); + interests.add (ARDOUR::Properties::length); + if (what_changed.contains (interests)) { + gui_extents_changed (); + } +} + void RecorderUI::gui_extents_changed () { diff --git a/gtk2_ardour/recorder_ui.h b/gtk2_ardour/recorder_ui.h index 3d24438666..3cea3425bd 100644 --- a/gtk2_ardour/recorder_ui.h +++ b/gtk2_ardour/recorder_ui.h @@ -80,6 +80,7 @@ private: void parameter_changed (std::string const&); void presentation_info_changed (PBD::PropertyChange const&); void gui_extents_changed (); + void region_changed (boost::shared_ptr, PBD::PropertyChange const&); void start_updating (); void stop_updating ();