]> git.alsa-project.org Git - alsa-lib.git/commitdiff
pcm: direct: Protect from freeing semaphore when already in use
authorJoshua Frkuska <joshua_frkuska@mentor.com>
Fri, 25 Nov 2016 10:13:40 +0000 (15:43 +0530)
committerTakashi Iwai <tiwai@suse.de>
Mon, 28 Nov 2016 19:13:36 +0000 (20:13 +0100)
In the case of dshare, dsnoop, and dmix when a device is opened twice
and fails the second time, the semaphore is completely discarded. This
creates dangling semaphore data.

This patch removes the possibility for the semaphore to be destroyed during
a typical open failure by first checking if the shared memory can be destroyed
or not. If the shared memory cannot be released it means both it and the
semaphore are still in use and therefore the semaphore is just released.

Signed-off-by: Joshua Frkuska <joshua_frkuska@mentor.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
src/pcm/pcm_dmix.c
src/pcm/pcm_dshare.c
src/pcm/pcm_dsnoop.c

index 2714fb93c758499ea3453fdc87dfe76b0d93280e..2fedb1c14a3b5d4c253f8e99c12cd2c922882b5e 100644 (file)
@@ -1154,9 +1154,10 @@ int snd_pcm_dmix_open(snd_pcm_t **pcmp, const char *name,
                snd_pcm_close(spcm);
        if (dmix->u.dmix.shmid_sum >= 0)
                shm_sum_discard(dmix);
-       if (dmix->shmid >= 0)
-               snd_pcm_direct_shm_discard(dmix);
-       if (snd_pcm_direct_semaphore_discard(dmix) < 0)
+       if ((dmix->shmid >= 0) && (snd_pcm_direct_shm_discard(dmix))) {
+               if (snd_pcm_direct_semaphore_discard(dmix))
+                       snd_pcm_direct_semaphore_final(dmix, DIRECT_IPC_SEM_CLIENT);
+       } else
                snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
  _err_nosem:
        if (dmix) {
index 9b478a7144686c08572472647ef5f11d159af211..01f5eed8f97a1f020a298ac789018f4c1bc49e9d 100644 (file)
@@ -846,9 +846,10 @@ int snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
                snd_pcm_direct_client_discard(dshare);
        if (spcm)
                snd_pcm_close(spcm);
-       if (dshare->shmid >= 0)
-               snd_pcm_direct_shm_discard(dshare);
-       if (snd_pcm_direct_semaphore_discard(dshare) < 0)
+       if ((dshare->shmid >= 0) && (snd_pcm_direct_shm_discard(dshare))) {
+               if (snd_pcm_direct_semaphore_discard(dshare))
+                       snd_pcm_direct_semaphore_final(dshare, DIRECT_IPC_SEM_CLIENT);
+       } else
                snd_pcm_direct_semaphore_up(dshare, DIRECT_IPC_SEM_CLIENT);
  _err_nosem:
        if (dshare) {
index 4efbc53d177eae2498e892f43ed9f59ab9b93035..1aedf3cb73d229eb3b695ebbe6de9e3c148e719f 100644 (file)
@@ -719,10 +719,12 @@ int snd_pcm_dsnoop_open(snd_pcm_t **pcmp, const char *name,
                snd_pcm_direct_client_discard(dsnoop);
        if (spcm)
                snd_pcm_close(spcm);
-       if (dsnoop->shmid >= 0)
-               snd_pcm_direct_shm_discard(dsnoop);
-       if (snd_pcm_direct_semaphore_discard(dsnoop) < 0)
+       if ((dsnoop->shmid >= 0) && (snd_pcm_direct_shm_discard(dsnoop))) {
+               if (snd_pcm_direct_semaphore_discard(dsnoop))
+                       snd_pcm_direct_semaphore_final(dsnoop, DIRECT_IPC_SEM_CLIENT);
+       } else
                snd_pcm_direct_semaphore_up(dsnoop, DIRECT_IPC_SEM_CLIENT);
+
  _err_nosem:
        if (dsnoop) {
                free(dsnoop->bindings);