summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa/0004-Fixed-the-SIGSEGV-at-PCM-close.patch180
-rw-r--r--meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa_git.bbappend3
2 files changed, 181 insertions, 2 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
new file mode 100644
index 00000000..52dbf773
--- /dev/null
+++ b/meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa/0004-Fixed-the-SIGSEGV-at-PCM-close.patch
@@ -0,0 +1,180 @@
+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
+
diff --git a/meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa_git.bbappend b/meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa_git.bbappend
index 43e4632f..8c67037f 100644
--- a/meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa_git.bbappend
+++ b/meta-audio-4a-framework/recipes-connectivity/bluez-alsa/bluez-alsa_git.bbappend
@@ -7,5 +7,4 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
SRC_URI += "file://0001-build-and-link-with-a-shared-library.patch"
SRC_URI += "file://0002-log-add-calling-function-name.patch"
SRC_URI += "file://0003-increased-the-number-of-connexions-to-16.patch"
-
-
+SRC_URI += "file://0004-Fixed-the-SIGSEGV-at-PCM-close.patch"
='n390' href='#n390'>390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486