From: Lukas Rusak Date: Thu, 23 Jun 2022 17:52:03 +0000 (-0700) Subject: audio_pw.c: use pw_thread_loop_timed_wait_full to avoid lockups X-Git-Tag: 4.1-rc1~24^2~120^2~3^2 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F1489%2Fhead;p=thirdparty%2Fshairport-sync.git audio_pw.c: use pw_thread_loop_timed_wait_full to avoid lockups --- diff --git a/audio_pw.c b/audio_pw.c index b9315cff..016df41d 100644 --- a/audio_pw.c +++ b/audio_pw.c @@ -35,6 +35,10 @@ #include +#define PW_TIMEOUT_S 5 +#define SECONDS_TO_NANOSECONDS 1000000000L +#define PW_TIMEOUT_NS (PW_TIMEOUT_S * SECONDS_TO_NANOSECONDS) + struct pw_data { struct pw_thread_loop *mainloop; struct pw_context *context; @@ -412,7 +416,15 @@ static void start(int sample_rate, int sample_format) { if (stream_state == PW_STREAM_STATE_PAUSED) break; - pw_thread_loop_wait(data.mainloop); + struct timespec abstime; + + pw_thread_loop_get_time(data.mainloop, &abstime, PW_TIMEOUT_NS); + + ret = pw_thread_loop_timed_wait_full(data.mainloop, &abstime); + if (ret == -ETIMEDOUT) { + deinit(); + die("pw: pw_thread_loop_timed_wait_full timed out: %s", strerror(ret)); + } } pw_thread_loop_unlock(data.mainloop); @@ -444,6 +456,7 @@ static int play(void *buf, int samples) { struct pw_buffer *pw_buffer; struct spa_buffer *spa_buffer; struct spa_data *spa_data; + int ret; pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); pw_thread_loop_lock(data.mainloop); @@ -456,7 +469,16 @@ static int play(void *buf, int samples) { if (pw_buffer) break; - pw_thread_loop_wait(data.mainloop); + struct timespec abstime; + + pw_thread_loop_get_time(data.mainloop, &abstime, PW_TIMEOUT_NS); + + ret = pw_thread_loop_timed_wait_full(data.mainloop, &abstime); + if (ret == -ETIMEDOUT) { + pw_thread_loop_unlock(data.mainloop); + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + return ret; + } } spa_buffer = pw_buffer->buffer;