aboutsummaryrefslogtreecommitdiffstats
path: root/meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa/0004-Fixed-the-SIGSEGV-at-PCM-close.patch
diff options
context:
space:
mode:
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.patch180
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
-