mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-04 13:29:59 -05:00
alsa: Better error handling in mixer rtpoll callback
This improves the error handling in the mixer rtpoll callback. It avoids a crash if an error occurs (the rtpoll_item is freed but still referenced), and specifically makes sure we don't continue trying to poll the device if the card is disconnected.
This commit is contained in:
parent
4e5943b6ba
commit
867170afa7
1 changed files with 23 additions and 7 deletions
|
|
@ -271,7 +271,7 @@ static int rtpoll_work_cb(pa_rtpoll_item *i) {
|
||||||
struct pollfd *p;
|
struct pollfd *p;
|
||||||
unsigned n_fds;
|
unsigned n_fds;
|
||||||
unsigned short revents = 0;
|
unsigned short revents = 0;
|
||||||
int err;
|
int err, ret = 0;
|
||||||
|
|
||||||
pd = pa_rtpoll_item_get_userdata(i);
|
pd = pa_rtpoll_item_get_userdata(i);
|
||||||
pa_assert_fp(pd);
|
pa_assert_fp(pd);
|
||||||
|
|
@ -281,17 +281,33 @@ static int rtpoll_work_cb(pa_rtpoll_item *i) {
|
||||||
|
|
||||||
if ((err = snd_mixer_poll_descriptors_revents(pd->mixer, p, n_fds, &revents)) < 0) {
|
if ((err = snd_mixer_poll_descriptors_revents(pd->mixer, p, n_fds, &revents)) < 0) {
|
||||||
pa_log_error("Unable to get poll revent: %s", pa_alsa_strerror(err));
|
pa_log_error("Unable to get poll revent: %s", pa_alsa_strerror(err));
|
||||||
pa_rtpoll_item_free(i);
|
ret = -1;
|
||||||
return -1;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (revents) {
|
if (revents) {
|
||||||
snd_mixer_handle_events(pd->mixer);
|
err = snd_mixer_handle_events(pd->mixer);
|
||||||
pa_rtpoll_item_free(i);
|
|
||||||
pa_alsa_set_mixer_rtpoll(pd, pd->mixer, pd->rtpoll);
|
if (PA_UNLIKELY(err == -ENODEV)) {
|
||||||
|
/* The card has been disconnected, stop polling */
|
||||||
|
goto fail;
|
||||||
|
} else {
|
||||||
|
/* Success, or at least an error we're likely to recover from */
|
||||||
|
pa_rtpoll_item_free(i);
|
||||||
|
pa_alsa_set_mixer_rtpoll(pd, pd->mixer, pd->rtpoll);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
pa_rtpoll_item_free(i);
|
||||||
|
|
||||||
|
pd->poll_item = NULL;
|
||||||
|
pd->rtpoll = NULL;
|
||||||
|
pd->mixer = NULL;
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pa_alsa_set_mixer_rtpoll(struct pa_alsa_mixer_pdata *pd, snd_mixer_t *mixer, pa_rtpoll *rtp) {
|
int pa_alsa_set_mixer_rtpoll(struct pa_alsa_mixer_pdata *pd, snd_mixer_t *mixer, pa_rtpoll *rtp) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue