blob: b35609f6012442e6dc01687fb21b2dc469cba880 [file] [log] [blame]
diff -aruN alsa-lib-1.0.27.2/src/pcm/pcm_direct.c alsa-lib-1.0.27.2.N/src/pcm/pcm_direct.c
--- alsa-lib-1.0.27.2/src/pcm/pcm_direct.c 2013-07-08 05:31:36.000000000 -0700
+++ alsa-lib-1.0.27.2.N/src/pcm/pcm_direct.c 2017-07-13 13:18:48.424261391 -0700
@@ -91,13 +91,20 @@
int snd_pcm_direct_shm_create_or_connect(snd_pcm_direct_t *dmix)
{
struct shmid_ds buf;
- int tmpid, err;
+ int tmpid, err, first_instance = 0;
retryget:
dmix->shmid = shmget(dmix->ipc_key, sizeof(snd_pcm_direct_share_t),
- IPC_CREAT | dmix->ipc_perm);
+ dmix->ipc_perm);
+ if (dmix->shmid < 0 && errno == ENOENT) {
+ if ((dmix->shmid = shmget(dmix->ipc_key, sizeof(snd_pcm_direct_share_t),
+ IPC_CREAT | IPC_EXCL | dmix->ipc_perm)) != -1)
+ first_instance = 1;
+ else if (errno == EEXIST)
+ goto retryget;
+ }
err = -errno;
- if (dmix->shmid < 0){
+ if (dmix->shmid < 0) {
if (errno == EINVAL)
if ((tmpid = shmget(dmix->ipc_key, 0, dmix->ipc_perm)) != -1)
if (!shmctl(tmpid, IPC_STAT, &buf))
@@ -119,7 +126,7 @@
snd_pcm_direct_shm_discard(dmix);
return err;
}
- if (buf.shm_nattch == 1) { /* we're the first user, clear the segment */
+ if (first_instance) { /* we're the first user, clear the segment */
memset(dmix->shmptr, 0, sizeof(snd_pcm_direct_share_t));
if (dmix->ipc_gid >= 0) {
buf.shm_perm.gid = dmix->ipc_gid;
@@ -130,6 +137,7 @@
} else {
if (dmix->shmptr->magic != SND_PCM_DIRECT_MAGIC) {
snd_pcm_direct_shm_discard(dmix);
+ SNDERR("Error in second instance");
return -EINVAL;
}
}
diff -aruN alsa-lib-1.0.27.2/src/pcm/pcm_dmix.c alsa-lib-1.0.27.2.N/src/pcm/pcm_dmix.c
--- alsa-lib-1.0.27.2/src/pcm/pcm_dmix.c 2013-07-08 05:31:36.000000000 -0700
+++ alsa-lib-1.0.27.2.N/src/pcm/pcm_dmix.c 2017-07-13 13:15:33.874553985 -0700
@@ -1013,6 +1013,7 @@
dmix->max_periods = opts->max_periods;
dmix->sync_ptr = snd_pcm_dmix_sync_ptr;
+ retry:
if (first_instance) {
/* recursion is already checked in
snd_pcm_direct_get_slave_ipc_offset() */
@@ -1069,6 +1070,13 @@
SND_PCM_APPEND,
NULL);
if (ret < 0) {
+ /* all other streams have been closed;
+ * retry as the first instance
+ */
+ if (ret == -EBADFD) {
+ first_instance = 1;
+ goto retry;
+ }
SNDERR("unable to open slave");
goto _err;
}