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).
This commit is contained in:
Robin Gareus 2021-04-30 03:40:32 +02:00
parent 58557e88c9
commit 6a82aa392c
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
2 changed files with 13 additions and 1 deletions

View File

@ -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<ARDOUR::Region>, 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 ()
{

View File

@ -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<ARDOUR::Region>, PBD::PropertyChange const&);
void start_updating ();
void stop_updating ();