[pulseaudio-commits] src/modules

Arun Raghavan arun at kemper.freedesktop.org
Tue Oct 4 01:24:27 PDT 2011


 src/modules/alsa/alsa-mixer.c |   30 +++++++++++++++++++++++-------
 1 file changed, 23 insertions(+), 7 deletions(-)

New commits:
commit d086f15c91e1919127b4ba62841de77235e003dd
Author: Arun Raghavan <arun.raghavan at collabora.co.uk>
Date:   Tue Oct 4 10:29:03 2011 +0530

    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.

diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index ec69efc..ebb3b0f 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -271,7 +271,7 @@ static int rtpoll_work_cb(pa_rtpoll_item *i) {
     struct pollfd *p;
     unsigned n_fds;
     unsigned short revents = 0;
-    int err;
+    int err, ret = 0;
 
     pd = pa_rtpoll_item_get_userdata(i);
     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) {
         pa_log_error("Unable to get poll revent: %s", pa_alsa_strerror(err));
-        pa_rtpoll_item_free(i);
-        return -1;
+        ret = -1;
+        goto fail;
     }
 
     if (revents) {
-        snd_mixer_handle_events(pd->mixer);
-        pa_rtpoll_item_free(i);
-        pa_alsa_set_mixer_rtpoll(pd, pd->mixer, pd->rtpoll);
+        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 */
+            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) {



More information about the pulseaudio-commits mailing list