diff options
Diffstat (limited to 'meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa/0004-Fixed-the-SIGSEGV-at-PCM-close.patch')
-rw-r--r-- | meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa/0004-Fixed-the-SIGSEGV-at-PCM-close.patch | 180 |
1 files changed, 0 insertions, 180 deletions
diff --git a/meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa/0004-Fixed-the-SIGSEGV-at-PCM-close.patch b/meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa/0004-Fixed-the-SIGSEGV-at-PCM-close.patch deleted file mode 100644 index 52dbf773..00000000 --- a/meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa/0004-Fixed-the-SIGSEGV-at-PCM-close.patch +++ /dev/null @@ -1,180 +0,0 @@ -From 23a1f554565c0cb9fade1a8f86ab9a09bf3d04e7 Mon Sep 17 00:00:00 2001 -From: Thierry Bultel <thierry.bultel@iot.bzh> -Date: Wed, 26 Dec 2018 10:06:38 +0100 -Subject: [PATCH] Fixed the SIGSEGV at PCM close - -There is a (still not identified) race condition at PCM -close, producing a SIGSEGV when pthread_cancel is called. -Instead of proposing a trick with pthread_setcancelstate, -this fix introduces a cancellation pipe, on which the io_thread -polls. This guaranties a better, safer, exit path. - -Signed-off-by: Thierry Bultel <thierry.bultel@iot.bzh> ---- - src/asound/bluealsa-pcm.c | 82 +++++++++++++++++++++++++++++++++++++++++------ - 1 file changed, 72 insertions(+), 10 deletions(-) - -diff --git a/src/asound/bluealsa-pcm.c b/src/asound/bluealsa-pcm.c -index 2136964..013aebb 100644 ---- a/src/asound/bluealsa-pcm.c -+++ b/src/asound/bluealsa-pcm.c -@@ -67,6 +67,8 @@ struct bluealsa_pcm { - snd_pcm_uframes_t io_hw_boundary; - snd_pcm_uframes_t io_hw_ptr; - -+ int cancelPipe[2]; -+ - }; - - -@@ -107,7 +109,9 @@ static void *io_thread(void *arg) { - struct asrsync asrs; - asrsync_init(&asrs, io->rate); - -- debug("Starting IO loop"); -+ const char * type = io->stream== SND_PCM_STREAM_CAPTURE?"CAPTURE":"PLAYBACK"; -+ -+ debug("------------ Starting IO loop (%s)-----------------------", type); - for (;;) { - - int tmp; -@@ -124,6 +128,11 @@ static void *io_thread(void *arg) { - debug("IO thread resumed: %d", io->state); - } - -+ if (pcm->io_started == false) { -+ debug("io_thread not started -> exit"); -+ goto final; -+ } -+ - snd_pcm_uframes_t io_ptr = pcm->io_ptr; - snd_pcm_uframes_t io_buffer_size = io->buffer_size; - snd_pcm_uframes_t io_hw_ptr = pcm->io_hw_ptr; -@@ -152,21 +161,44 @@ static void *io_thread(void *arg) { - if (io_hw_ptr >= io_hw_boundary) - io_hw_ptr -= io_hw_boundary; - -+ struct pollfd fds[2]; -+ -+ fds[0].fd = pcm->pcm_fd; -+ fds[1].fd = pcm->cancelPipe[0]; -+ -+ if (io->stream == SND_PCM_STREAM_CAPTURE) -+ fds[0].events |= POLLIN; -+ else -+ fds[0].events |= POLLOUT; -+ -+ fds[1].events = POLLIN | POLLHUP; -+ - if (io->stream == SND_PCM_STREAM_CAPTURE) { - - /* Read the whole period "atomically". This will assure, that frames - * are not fragmented, so the pointer can be correctly updated. */ -- while (len != 0 && (ret = read(pcm->pcm_fd, head, len)) != 0) { -+ while (len != 0 && -+ pcm->io_started) { -+ -+ int pollres = poll(fds, 2, -1); -+ -+ if ((fds[1].revents & POLLIN) != 0) { -+ debug("io_thread: CANCELLED"); -+ goto final; -+ } -+ -+ ret = read(pcm->pcm_fd, head, len); - if (ret == -1) { -- if (errno == EINTR) -- continue; -+ if (errno == EINTR) { -+ break; -+ } - SNDERR("PCM FIFO read error: %s", strerror(errno)); - goto final; - } - head += ret; - len -= ret; -- } - -+ } - if (ret == 0) - goto final; - -@@ -182,9 +214,18 @@ static void *io_thread(void *arg) { - - /* Perform atomic write - see the explanation above. */ - do { -+ -+ int pollres = poll(fds, 2, -1); -+ -+ if ((fds[1].revents & POLLIN) != 0) { -+ debug("io_thread: CANCELLED"); -+ goto final; -+ } -+ - if ((ret = write(pcm->pcm_fd, head, len)) == -1) { -- if (errno == EINTR) -- continue; -+ if (errno == EINTR) { -+ break; -+ } - SNDERR("PCM FIFO write error: %s", strerror(errno)); - goto final; - } -@@ -251,12 +292,24 @@ static int bluealsa_start(snd_pcm_ioplug_t *io) { - - static int bluealsa_stop(snd_pcm_ioplug_t *io) { - struct bluealsa_pcm *pcm = io->private_data; -- debug("Stopping"); -+ debug("Stopping %p", pcm); -+ if (!pcm) { -+ debug("PCM ALREADY CLOSED !"); -+ return 0; -+ } - if (pcm->io_started) { - pcm->io_started = false; -- pthread_cancel(pcm->io_thread); -+ -+ char dummy = 0; -+ -+ if (write(pcm->cancelPipe[1], &dummy, sizeof(dummy)) < 0) -+ debug("Failed to write to the cancellation pipe"); -+ - pthread_join(pcm->io_thread, NULL); - } -+done: -+ debug("Stop done"); -+ - return 0; - } - -@@ -269,10 +322,14 @@ static snd_pcm_sframes_t bluealsa_pointer(snd_pcm_ioplug_t *io) { - - static int bluealsa_close(snd_pcm_ioplug_t *io) { - struct bluealsa_pcm *pcm = io->private_data; -- debug("Closing plugin"); -+ debug("Closing plugin %p", pcm); - close(pcm->fd); - close(pcm->event_fd); -+ close(pcm->cancelPipe[0]); -+ close(pcm->cancelPipe[1]); - free(pcm); -+ io->private_data = NULL; -+ debug("PCM closed"); - return 0; - } - -@@ -649,6 +706,11 @@ SND_PCM_PLUGIN_DEFINE_FUNC(bluealsa) { - pcm->pcm_fd = -1; - pcm->delay_ex = delay; - -+ if (pipe(pcm->cancelPipe) == -1) { -+ SNDERR("BlueALSA failed to create cancellation pipe: %s", strerror(errno)); -+ ret = -errno; -+ } -+ - if ((pcm->fd = bluealsa_open(interface)) == -1) { - SNDERR("BlueALSA connection failed: %s", strerror(errno)); - ret = -errno; --- -2.16.4 - |