mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-11-09 13:30:03 -05:00
Do not abort in snd_xxx_close() functions
Remove several memory leaks by not aborting prematurely from a snd_xxx_close() function when some operation fails. This can happen when a USB device was unplugged.
This commit is contained in:
parent
f9c7321670
commit
45850439b3
11 changed files with 33 additions and 33 deletions
|
|
@ -668,13 +668,13 @@ snd_pcm_stream_t snd_pcm_stream(snd_pcm_t *pcm)
|
|||
*/
|
||||
int snd_pcm_close(snd_pcm_t *pcm)
|
||||
{
|
||||
int err;
|
||||
int res = 0, err;
|
||||
assert(pcm);
|
||||
if (pcm->setup && !pcm->donot_close) {
|
||||
snd_pcm_drop(pcm);
|
||||
err = snd_pcm_hw_free(pcm);
|
||||
if (err < 0)
|
||||
return err;
|
||||
res = err;
|
||||
}
|
||||
if (pcm->mmap_channels)
|
||||
snd_pcm_munmap(pcm);
|
||||
|
|
@ -684,8 +684,11 @@ int snd_pcm_close(snd_pcm_t *pcm)
|
|||
}
|
||||
err = pcm->ops->close(pcm->op_arg);
|
||||
if (err < 0)
|
||||
return err;
|
||||
return snd_pcm_free(pcm);
|
||||
res = err;
|
||||
err = snd_pcm_free(pcm);
|
||||
if (err < 0)
|
||||
res = err;
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -55,13 +55,13 @@ static int snd_pcm_hooks_close(snd_pcm_t *pcm)
|
|||
snd_pcm_hooks_t *h = pcm->private_data;
|
||||
struct list_head *pos, *next;
|
||||
unsigned int k;
|
||||
int err;
|
||||
int res = 0, err;
|
||||
|
||||
list_for_each_safe(pos, next, &h->hooks[SND_PCM_HOOK_TYPE_CLOSE]) {
|
||||
snd_pcm_hook_t *hook = list_entry(pos, snd_pcm_hook_t, list);
|
||||
err = hook->func(hook);
|
||||
if (err < 0)
|
||||
return err;
|
||||
res = err;
|
||||
}
|
||||
for (k = 0; k <= SND_PCM_HOOK_TYPE_LAST; ++k) {
|
||||
struct list_head *hooks = &h->hooks[k];
|
||||
|
|
@ -72,7 +72,10 @@ static int snd_pcm_hooks_close(snd_pcm_t *pcm)
|
|||
snd_pcm_hook_remove(hook);
|
||||
}
|
||||
}
|
||||
return snd_pcm_generic_close(pcm);
|
||||
err = snd_pcm_generic_close(pcm);
|
||||
if (err < 0)
|
||||
res = err;
|
||||
return res;
|
||||
}
|
||||
|
||||
static int snd_pcm_hooks_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
|
||||
|
|
|
|||
|
|
@ -889,16 +889,15 @@ static int snd_pcm_hw_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
|
|||
static int snd_pcm_hw_close(snd_pcm_t *pcm)
|
||||
{
|
||||
snd_pcm_hw_t *hw = pcm->private_data;
|
||||
int err;
|
||||
int err = 0;
|
||||
if (close(hw->fd)) {
|
||||
err = -errno;
|
||||
SYSMSG("close failed\n");
|
||||
return err;
|
||||
}
|
||||
snd_pcm_hw_munmap_status(pcm);
|
||||
snd_pcm_hw_munmap_control(pcm);
|
||||
free(hw);
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static snd_pcm_sframes_t snd_pcm_hw_mmap_commit(snd_pcm_t *pcm,
|
||||
|
|
|
|||
|
|
@ -64,10 +64,7 @@ static int snd_pcm_plug_close(snd_pcm_t *pcm)
|
|||
int err, result = 0;
|
||||
if (plug->ttable)
|
||||
free(plug->ttable);
|
||||
if (plug->gen.slave != plug->req_slave) {
|
||||
SNDERR("plug slaves mismatch");
|
||||
return -EINVAL;
|
||||
}
|
||||
assert(plug->gen.slave == plug->req_slave);
|
||||
if (plug->gen.close_slave) {
|
||||
snd_pcm_unlink_hw_ptr(pcm, plug->req_slave);
|
||||
snd_pcm_unlink_appl_ptr(pcm, plug->req_slave);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue