mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-11-07 13:30:07 -05:00
pcm: direct: Protect from freeing semaphore when already in use
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>
This commit is contained in:
parent
2ef7a53c31
commit
2dd78251ff
3 changed files with 13 additions and 9 deletions
|
|
@ -1154,9 +1154,10 @@ int snd_pcm_dmix_open(snd_pcm_t **pcmp, const char *name,
|
||||||
snd_pcm_close(spcm);
|
snd_pcm_close(spcm);
|
||||||
if (dmix->u.dmix.shmid_sum >= 0)
|
if (dmix->u.dmix.shmid_sum >= 0)
|
||||||
shm_sum_discard(dmix);
|
shm_sum_discard(dmix);
|
||||||
if (dmix->shmid >= 0)
|
if ((dmix->shmid >= 0) && (snd_pcm_direct_shm_discard(dmix))) {
|
||||||
snd_pcm_direct_shm_discard(dmix);
|
if (snd_pcm_direct_semaphore_discard(dmix))
|
||||||
if (snd_pcm_direct_semaphore_discard(dmix) < 0)
|
snd_pcm_direct_semaphore_final(dmix, DIRECT_IPC_SEM_CLIENT);
|
||||||
|
} else
|
||||||
snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
|
snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
|
||||||
_err_nosem:
|
_err_nosem:
|
||||||
if (dmix) {
|
if (dmix) {
|
||||||
|
|
|
||||||
|
|
@ -846,9 +846,10 @@ int snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
|
||||||
snd_pcm_direct_client_discard(dshare);
|
snd_pcm_direct_client_discard(dshare);
|
||||||
if (spcm)
|
if (spcm)
|
||||||
snd_pcm_close(spcm);
|
snd_pcm_close(spcm);
|
||||||
if (dshare->shmid >= 0)
|
if ((dshare->shmid >= 0) && (snd_pcm_direct_shm_discard(dshare))) {
|
||||||
snd_pcm_direct_shm_discard(dshare);
|
if (snd_pcm_direct_semaphore_discard(dshare))
|
||||||
if (snd_pcm_direct_semaphore_discard(dshare) < 0)
|
snd_pcm_direct_semaphore_final(dshare, DIRECT_IPC_SEM_CLIENT);
|
||||||
|
} else
|
||||||
snd_pcm_direct_semaphore_up(dshare, DIRECT_IPC_SEM_CLIENT);
|
snd_pcm_direct_semaphore_up(dshare, DIRECT_IPC_SEM_CLIENT);
|
||||||
_err_nosem:
|
_err_nosem:
|
||||||
if (dshare) {
|
if (dshare) {
|
||||||
|
|
|
||||||
|
|
@ -719,10 +719,12 @@ int snd_pcm_dsnoop_open(snd_pcm_t **pcmp, const char *name,
|
||||||
snd_pcm_direct_client_discard(dsnoop);
|
snd_pcm_direct_client_discard(dsnoop);
|
||||||
if (spcm)
|
if (spcm)
|
||||||
snd_pcm_close(spcm);
|
snd_pcm_close(spcm);
|
||||||
if (dsnoop->shmid >= 0)
|
if ((dsnoop->shmid >= 0) && (snd_pcm_direct_shm_discard(dsnoop))) {
|
||||||
snd_pcm_direct_shm_discard(dsnoop);
|
if (snd_pcm_direct_semaphore_discard(dsnoop))
|
||||||
if (snd_pcm_direct_semaphore_discard(dsnoop) < 0)
|
snd_pcm_direct_semaphore_final(dsnoop, DIRECT_IPC_SEM_CLIENT);
|
||||||
|
} else
|
||||||
snd_pcm_direct_semaphore_up(dsnoop, DIRECT_IPC_SEM_CLIENT);
|
snd_pcm_direct_semaphore_up(dsnoop, DIRECT_IPC_SEM_CLIENT);
|
||||||
|
|
||||||
_err_nosem:
|
_err_nosem:
|
||||||
if (dsnoop) {
|
if (dsnoop) {
|
||||||
free(dsnoop->bindings);
|
free(dsnoop->bindings);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue