From 5600b901b2b4c59eff7bdf507ee57b222142682e Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Tue, 4 Jun 2024 11:17:57 +0200 Subject: [PATCH] async: snd_async_del_handler - move clear signal using sigaction as last Improve the shutdown order for the asynchronous users. There may be unhandled signals, because the signal is reset before signal deactivation using fnctl (O_ASYNC). Closes: https://github.com/alsa-project/alsa-lib/issues/394 Signed-off-by: Jaroslav Kysela --- src/async.c | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/async.c b/src/async.c index 76c6fb9e0..a003e4417 100644 --- a/src/async.c +++ b/src/async.c @@ -149,12 +149,31 @@ int snd_async_add_handler(snd_async_handler_t **handler, int fd, */ int snd_async_del_handler(snd_async_handler_t *handler) { - int err = 0; - int was_empty = list_empty(&snd_async_handlers); + int err = 0, err2 = 0; + int was_empty; assert(handler); + if (handler->type != SND_ASYNC_HANDLER_GENERIC) { + if (!list_empty(&handler->hlist)) + list_del(&handler->hlist); + if (!list_empty(&handler->hlist)) + goto _glist; + switch (handler->type) { +#ifdef BUILD_PCM + case SND_ASYNC_HANDLER_PCM: + err2 = snd_pcm_async(handler->u.pcm, -1, 1); + break; +#endif + case SND_ASYNC_HANDLER_CTL: + err2 = snd_ctl_async(handler->u.ctl, -1, 1); + break; + default: + assert(0); + } + } + _glist: + was_empty = list_empty(&snd_async_handlers); list_del(&handler->glist); - if (!was_empty - && list_empty(&snd_async_handlers)) { + if (!was_empty && list_empty(&snd_async_handlers)) { err = sigaction(snd_async_signo, &previous_action, NULL); if (err < 0) { SYSERR("sigaction"); @@ -162,27 +181,8 @@ int snd_async_del_handler(snd_async_handler_t *handler) } memset(&previous_action, 0, sizeof(previous_action)); } - if (handler->type == SND_ASYNC_HANDLER_GENERIC) - goto _end; - if (!list_empty(&handler->hlist)) - list_del(&handler->hlist); - if (!list_empty(&handler->hlist)) - goto _end; - switch (handler->type) { -#ifdef BUILD_PCM - case SND_ASYNC_HANDLER_PCM: - err = snd_pcm_async(handler->u.pcm, -1, 1); - break; -#endif - case SND_ASYNC_HANDLER_CTL: - err = snd_ctl_async(handler->u.ctl, -1, 1); - break; - default: - assert(0); - } - _end: free(handler); - return err; + return err ? err : err2; } /**