From 32a0c6a3ff7286b2b78efed64d1438d85142df31 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Thu, 22 Oct 2020 07:37:07 +0200 Subject: [PATCH] Drop TMM ports when closing session, or backend goes away TMM ports cannot exist without a backend. This fixes crashes where the PortEngine is re-initialized (backend change): Previously, TMM ports were only dropped (and recreated) in TMM::restart() called from ARDOUR::init_post_engine(). When starting a new backend the old one is already destroyed, but TM still held reference to Ports owned by that backend. Calling the port's d'tor caused a memory corruption trying to acquire the backend's port_callback_mutex: e.g. When creating new session with a different backend from a running instance, or unit-test after call to AudioEngine::destroy(): https://pastebin.com/4D6pLA5s --- libs/ardour/audioengine.cc | 1 + libs/ardour/transport_master.cc | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc index f48f4761cf..b3fed5113b 100644 --- a/libs/ardour/audioengine.cc +++ b/libs/ardour/audioengine.cc @@ -942,6 +942,7 @@ AudioEngine::drop_backend () Port::PortDrop (); /* EMIT SIGNAL */ TransportMasterManager& tmm (TransportMasterManager::instance()); tmm.engine_stopped (); + tmm.set_session (0); // unregister TMM ports /* Stopped is needed for Graph to explicitly terminate threads */ Stopped (); /* EMIT SIGNAL */ diff --git a/libs/ardour/transport_master.cc b/libs/ardour/transport_master.cc index e76fd5eb66..a9debe974e 100644 --- a/libs/ardour/transport_master.cc +++ b/libs/ardour/transport_master.cc @@ -74,7 +74,7 @@ TransportMaster::TransportMaster (SyncSource t, std::string const & name) , _sclock_synced (Properties::sclock_synced, false) , _collect (Properties::collect, true) , _connected (Properties::connected, false) - , port_node (X_("")) + , port_node (X_("Port")) { register_properties (); @@ -243,6 +243,9 @@ void TransportMaster::set_session (Session* s) { _session = s; + if (!_session) { + unregister_port (); + } } int @@ -325,7 +328,10 @@ TransportMaster::get_state () } } + port_node = *pnode; node->add_child_nocopy (*pnode); + } else if (port_node.children (). size() > 0) { + node->add_child_copy (port_node); } return *node;