alsa: Make mixer error handling more robust still

Instead of relying on the snd_mixer_* functions failing, we check for
POLLERR and POLLNVAL first. After this, any errors in handling the mixer
events are deemed fatal (that is we cause the ALSA source/sink thread to
terminate).

The case where POLLERR is set but POLLNVAL is not does not actually
occur, but we're making this a soft failure (stop polling the mixer, but
don't kill the I/O thread). If other conditions where POLLERR occurs
turn up, we need to handle them explicitly.

Thanks to Linus Torvalds for helping get this right.
This commit is contained in:
Arun Raghavan 2011-10-05 00:58:52 +05:30
parent 8754e0c779
commit 2c30c0751f

View file

@ -286,15 +286,24 @@ static int rtpoll_work_cb(pa_rtpoll_item *i) {
}
if (revents) {
if (revents & (POLLNVAL | POLLERR)) {
pa_log_debug("Device disconnected, stopping poll on mixer");
goto fail;
} else if (revents & POLLERR) {
/* This shouldn't happen. */
pa_log_error("Got a POLLERR (revents = %04x), stopping poll on mixer", revents);
goto fail;
}
err = snd_mixer_handle_events(pd->mixer);
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 */
if (PA_LIKELY(err >= 0)) {
pa_rtpoll_item_free(i);
pa_alsa_set_mixer_rtpoll(pd, pd->mixer, pd->rtpoll);
} else {
pa_log_error("Error handling mixer event: %s", pa_alsa_strerror(err));
ret = -1;
goto fail;
}
}