Fix callback order of port-dis/connections

Previously the port-engine was a LIFO. Changes were pushed back
and then popped-back. This causes issues when re-connecting
Transport Masters.

The GUI does the following when changing connections:
1. disconnect all
2. connect to new port

which lead to TransportMaster::connection_handler being called
in reverse order: connect, disconnect, and the transport
master was assumed to not be connected.

--

Now connections queue is a FIFO and code was consolidated.

(Note, we cannot use a std::deque because it does not support
memory pre-allocation with ::reserve)
This commit is contained in:
Robin Gareus 2023-12-02 23:34:58 +01:00
parent 1386b3b73f
commit dacf488c86
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
7 changed files with 18 additions and 31 deletions

View File

@ -27,7 +27,6 @@
#include <string>
#include <vector>
#include "pbd/natsort.h"
#include "pbd/rcu.h"
@ -203,6 +202,8 @@ protected:
pthread_mutex_unlock (&_port_callback_mutex);
}
void process_connection_queue_locked (PortManager& mgr);
void port_connect_add_remove_callback () {
_port_change_flag.store (1);
}

View File

@ -23,6 +23,7 @@
#include "pbd/error.h"
#include "ardour/port_engine_shared.h"
#include "ardour/port_manager.h"
#include "pbd/i18n.h"
@ -828,6 +829,16 @@ PortEngineSharedImpl::update_system_port_latencies ()
}
}
void
PortEngineSharedImpl::process_connection_queue_locked (PortManager& mgr)
{
for (auto& c : _port_connection_queue) {
mgr.connect_callback (c->a, c->b, c->c);
delete c;
}
_port_connection_queue.clear ();
}
#ifndef NDEBUG
void
PortEngineSharedImpl::list_ports () const

View File

@ -2092,12 +2092,7 @@ AlsaAudioBackend::main_process_thread ()
if (!_port_connection_queue.empty ()) {
connections_changed = true;
}
while (!_port_connection_queue.empty ()) {
PortConnectData* c = _port_connection_queue.back ();
manager.connect_callback (c->a, c->b, c->c);
_port_connection_queue.pop_back ();
delete c;
}
process_connection_queue_locked (manager);
pthread_mutex_unlock (&_port_callback_mutex);
}
if (ports_changed) {

View File

@ -1282,12 +1282,7 @@ CoreAudioBackend::pre_process ()
if (!_port_connection_queue.empty ()) {
connections_changed = true;
}
while (!_port_connection_queue.empty ()) {
PortConnectData *c = _port_connection_queue.back ();
manager.connect_callback (c->a, c->b, c->c);
_port_connection_queue.pop_back ();
delete c;
}
process_connection_queue_locked (manager);
pthread_mutex_unlock (&_port_callback_mutex);
}
if (ports_changed) {

View File

@ -1029,12 +1029,7 @@ DummyAudioBackend::main_process_thread ()
if (!_port_connection_queue.empty ()) {
connections_changed = true;
}
while (!_port_connection_queue.empty ()) {
PortConnectData *c = _port_connection_queue.back ();
manager.connect_callback (c->a, c->b, c->c);
_port_connection_queue.pop_back ();
delete c;
}
process_connection_queue_locked (manager);
pthread_mutex_unlock (&_port_callback_mutex);
}
if (ports_changed) {

View File

@ -1827,12 +1827,7 @@ PortAudioBackend::process_port_connection_changes ()
if (!_port_connection_queue.empty ()) {
connections_changed = true;
}
while (!_port_connection_queue.empty ()) {
PortConnectData *c = _port_connection_queue.back ();
manager.connect_callback (c->a, c->b, c->c);
_port_connection_queue.pop_back ();
delete c;
}
process_connection_queue_locked (manager);
pthread_mutex_unlock (&_port_callback_mutex);
}
if (ports_changed) {

View File

@ -1098,12 +1098,7 @@ PulseAudioBackend::main_process_thread ()
if (!_port_connection_queue.empty ()) {
connections_changed = true;
}
while (!_port_connection_queue.empty ()) {
PortConnectData* c = _port_connection_queue.back ();
manager.connect_callback (c->a, c->b, c->c);
_port_connection_queue.pop_back ();
delete c;
}
process_connection_queue_locked (manager);
pthread_mutex_unlock (&_port_callback_mutex);
}
if (ports_changed) {