]> git.ipfire.org Git - thirdparty/shairport-sync.git/commit
avoid recursive mutex acquisition in sndio backend 1362/head
authorAnton Lindqvist <anton@basename.se>
Fri, 3 Dec 2021 19:45:51 +0000 (20:45 +0100)
committerAnton Lindqvist <anton@basename.se>
Sun, 5 Dec 2021 08:08:01 +0000 (09:08 +0100)
commit57af5f3c10c54947cf160fe46a580cf40669d412
tree306b23c1694bf160dd88d1bd90815a48cd6adb6d
parenta05db62100b9d4dcd2b81d66f16f367135e4c390
avoid recursive mutex acquisition in sndio backend

Ending a RTSP session while running on OpenBSD using sndio backend causes the
following crash:

#0  thrkill ()
#1  0x000005208224403e in _libc_abort
#2  0x00000520821b77be in _rthread_mutex_trylock
#3  _rthread_mutex_timedlock
#4  0x0000051e0d54e2c0 in stop ()
#5  0x0000051e0d544e85 in player_thread_cleanup_handler
#6  0x0000052082243126 in _libc_pthread_exit
#7  0x000005209a158700 in sigthr_handler
#8  <signal handler called>
#9  _thread_sys_poll ()
#10 0x000005208223533e in _libc_poll_cancel
#11 0x00000520df54c9a0 in sio_psleep
#12 0x00000520df54cc1f in sio_write
#13 0x0000051e0d54e27a in play
#14 0x0000051e0d547fc0 in player_thread_func
#15 0x000005209a158cc1 in _rthread_start
#16 0x000005208223565a in __tfork_thread

The player thread is blocking inside sio_write() -> poll(2) while the thread is
being terminated. The stop routine tied to the same backend is invoked through
player_thread_cleanup_handler() which tries to acquire the mutex which it
already acquired before invoking sio_write(). Avoiding blocking writes would
require switching to async I/O which is quite an undertaking.

The fact that there's only one `struct sio_hdl *' instance in the compilation
unit sort of implies there can only be one player thread at a time. Therefore
fix the crash by only trying to acquire the mutex and continue as usual if it's
already acquired.
audio_sndio.c