Stop auto-connect thread before terminating ctrl surfaces

This works around a race-condition, calling d'tors from
two threads concurrently.

The GUI thread destroys ctrl surfaces. ~~MIDIControllable()
calls ::drop_external_control() -> ::midi_forget()
This unsubscribes from signals (notably MIDI::Parser events)
by calling ScopedConnection::disconnect(), Connection::disconnect().

At the same time auto_connect_thread can call
PortManager::clear_pending_port_deletions() which removes
the MIDI port and destorys the MIDI::Parser.

~Parser() calls Connection::signal_going_away() to invalidate
connected signals.

This can deadlock if it is called concurrently with
Connection::disconnect() on the same signal.

see also
https://discourse.ardour.org/t/ardour-session-close-hangs/106523/10
This commit is contained in:
Robin Gareus 2021-11-19 23:36:13 +01:00
parent 0837449749
commit ee8e8da614
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04

View File

@ -614,14 +614,14 @@ Session::destroy ()
Port::PortSignalDrop (); /* EMIT SIGNAL */
drop_connections ();
/* stop auto dis/connecting */
auto_connect_thread_terminate ();
/* shutdown control surface protocols while we still have ports
* and the engine to move data to any devices.
*/
ControlProtocolManager::instance().drop_protocols ();
/* stop auto dis/connecting */
auto_connect_thread_terminate ();
_engine.remove_session ();
/* deregister all ports - there will be no process or any other