deadlock: JACK port-registration blocks on graph-order callback - Ardour hangs
Summary: Pipewire's threading does not match JACKs, leading to deadlocks in JACK clients.
Pipewire: 0.3.70
When a JACK client registers a port, pipewire does not return, but blocks
Thread 1:
#0 0x00007ffff0e8f05e in __futex_abstimed_wait_common () from /lib64/libc.so.6
#1 0x00007ffff0e91da0 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libc.so.6
#2 0x00007ffff27a9396 in pw_thread_loop_wait () from /lib64/libpipewire-0.3.so.0
#3 0x00007ffff38ccf8a in do_sync.lto_priv () from /usr/lib64/pipewire-0.3/jack/libjack.so.0
#4 0x00007ffff38d6f5e in jack_port_register () from /usr/lib64/pipewire-0.3/jack/libjack.so.0
...
# Ardour takes IO's Threads::RWLock::WriterLock
...
Apparently pipewire waits on the graph-order callback emitted from a different thread:
Thread 22:
# Ardour requires IO Threads::RWLock::ReaderLock -- deadlock
...
#17 0x00007ffff38dfc2b in registry_event_global.part.0.lto_priv () from /usr/lib64/pipewire-0.3/jack/libjack.so.0
#18 0x00007ffff0bdd1c2 in registry_demarshal_global.lto_priv () from /usr/lib64/pipewire-0.3/libpipewire-module-protocol-native.so
#19 0x00007ffff0bca369 in process_remote () from /usr/lib64/pipewire-0.3/libpipewire-module-protocol-native.so
#20 0x00007ffff0bca9e0 in on_remote_data () from /usr/lib64/pipewire-0.3/libpipewire-module-protocol-native.so
#21 0x00007ffff4040e4e in loop_iterate () from /usr/lib64/spa-0.2/support/libspa-support.so
#22 0x00007ffff27aa9f2 in do_loop () from /lib64/libpipewire-0.3.so.0
#23 0x00007ffff0e92ab4 in start_thread () from /lib64/libc.so.6
#24 0x00007ffff0f19b60 in clone3 () from /lib64/libc.so.6
In case of Ardour this results in a deadlock:
The graph-order callback needs to iterate over registered Ports (requires a Threads::RWLock::ReaderLock
)
but since port-registration is still in progress that mutex cannot be acquired.
This indicates a bug in pipewire's JACK implementation: port-registration must not wait.
Complete backtrace (Arodur 7.4): https://pastebin.com/MWze9z0i
PS. Older versions of Ardour were not affected (but randomly crashed since iterators could be modified while iterating). This was solved by adding RWLocks: https://github.com/Ardour/ardour/commit/197157ecf88d5 which is fine with JACK1 and JACK2. But it is not just Ardour that is affected.