mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-09 00:04:56 +01:00
Prevent deadlock when disconnecting
The backend holds `_port_callback_mutex` while disconnecting ports. In some cases disconnecting a port can drop the last reference resulting in a port-deletion from the connection handler. This in turn will eventually aquire the `_port_callback_mutex` and deadlock. This is now circumvented by using atomic operations instead of taking a lock to set the `_port_change_flag`. The flag is also used to trigger a latency update in some cases, atomic is preferable to taking a lock to set this flag. -- Full bt: https://paste.debian.net/1184056/ Short: #1 in pthread_mutex_lock () #2 in ARDOUR::PortEngineSharedImpl::port_connect_add_remove_callback() #3 in ARDOUR::BackendPort::~BackendPort() #4 in ARDOUR::DummyPort::~DummyPort() #6 in ARDOUR::DummyAudioPort::~DummyAudioPort() #7 in boost::checked_delete<ARDOUR::BackendPort>(ARDOUR::BackendPort*) #12 in boost::shared_ptr<ARDOUR::ProtoPort>::reset() #13 in ARDOUR::Port::drop() #14 in ARDOUR::Port::~Port() #15 in ARDOUR::AudioPort::~AudioPort() #17 in ARDOUR::AudioEngine::add_pending_port_deletion(ARDOUR::Port*) #20 in boost::detail::sp_counted_base::release() #37 in ARDOUR::PortManager::connect_callback() at libs/ardour/port_manager.cc:788 #38 in ARDOUR::DummyAudioBackend::main_process_thread() at libs/backends/dummy/dummy_audiobackend.cc:1018
This commit is contained in:
parent
30da8c00b5
commit
634d325e5d
7 changed files with 21 additions and 29 deletions
|
|
@ -625,7 +625,7 @@ PulseAudioBackend::_start (bool /*for_latency_measurement*/)
|
|||
engine.reconnect_ports ();
|
||||
|
||||
_run = true;
|
||||
_port_change_flag = false;
|
||||
g_atomic_int_set (&_port_change_flag, 0);
|
||||
|
||||
if (pbd_realtime_pthread_create (PBD_SCHED_FIFO, PBD_RT_PRI_MAIN, PBD_RT_STACKSIZE_PROC,
|
||||
&_main_thread, pthread_process, this)) {
|
||||
|
|
@ -1104,9 +1104,8 @@ PulseAudioBackend::main_process_thread ()
|
|||
bool connections_changed = false;
|
||||
bool ports_changed = false;
|
||||
if (!pthread_mutex_trylock (&_port_callback_mutex)) {
|
||||
if (_port_change_flag) {
|
||||
ports_changed = true;
|
||||
_port_change_flag = false;
|
||||
if (g_atomic_int_compare_and_exchange (&_port_change_flag, 1, 0)) {
|
||||
ports_changed = true;
|
||||
}
|
||||
if (!_port_connection_queue.empty ()) {
|
||||
connections_changed = true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue