Fix restoring metronome connections (duplicate IO set_state)

When a session is loaded, click_io->set_state is called twice.
setup_click() is called when the engine re/starts, and
possibly again from Session::set_state.

During session construction, Port connections are not directly
made. Port::set_state just creates a list, which is later
applied by Port::reconnect from Session::hookup_io.

However, the second call to IO::set_state() calls IO::ensure_ports
again. Since the port already exists, this calls
Port::disconnect_all (while holding the process lock).

Even though the port is not connected at this point in time,
this triggers a ARDOUR::PortManager::connect_callback which
is emitted from the Audioengine when the process-lock is released.

While IO::set_state() continues to set Port::state, and fill
the Port::_[ext_]connections lists, this data is invalidated
moments later when the engine resumes and ::connect_callback
calls ARDOUR::Port::port_connected_or_disconnected.

The solution is to simply not call Port::disconnect_all
if the connection is not yet made (Session::InitialConnecting)
This commit is contained in:
Robin Gareus 2023-06-22 13:21:45 +02:00
parent 71a83ed199
commit 19c44fe814
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
1 changed files with 8 additions and 1 deletions

View File

@ -635,6 +635,13 @@ IO::set_state (const XMLNode& node, int version)
if (p) {
p->set_state (**i, version);
if (!_session.inital_connect_or_deletion_in_progress ()) {
/* re-apply connection if create_ports(), ensure_ports()
* disconnected the port
*/
p->reconnect ();
}
}
}
}
@ -864,7 +871,7 @@ IO::create_ports (const XMLNode& node, int version)
{
Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
if (ensure_ports (n, true, this)) {
if (ensure_ports (n, !_session.inital_connect_or_deletion_in_progress (), this)) {
error << string_compose(_("%1: cannot create I/O ports"), _name) << endmsg;
return -1;
}