[vlc-commits] PulseAudio: flush or drain at end, not both

Rémi Denis-Courmont git at videolan.org
Wed Jul 20 21:18:00 CEST 2011


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Mon Jul 18 18:56:36 2011 +0300| [41eac2593c1ae27cafbeb351c158293689b9375d] | committer: Rémi Denis-Courmont

PulseAudio: flush or drain at end, not both

Draining after flushing makes no sense. By the way, we should probably
wait for draining to complete. But there seems to be a race condition
in libpulse and this causes a deadlock.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=41eac2593c1ae27cafbeb351c158293689b9375d
---

 modules/audio_output/pulse.c |   28 +++++++++++++++++++++++-----
 1 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/modules/audio_output/pulse.c b/modules/audio_output/pulse.c
index 07632c9..a2931f5 100644
--- a/modules/audio_output/pulse.c
+++ b/modules/audio_output/pulse.c
@@ -188,6 +188,16 @@ static int stream_wait(pa_stream *stream)
     return 0;
 }
 
+#ifdef LIBPULSE_GETS_A_CLUE
+static void stream_success_cb(pa_stream *s, int success, void *userdata)
+{
+    vlc_pa_signal(0);
+    (void) s; (void) success; (void) userdata;
+}
+#else
+# define stream_success_cb NULL
+#endif
+
 /* Memory free callback. The block_t address is in front of the data. */
 static void data_free(void *data)
 {
@@ -591,12 +601,20 @@ static void Close (vlc_object_t *obj)
     if (s != NULL) {
         pa_operation *op;
 
-        op = pa_stream_flush(s, NULL, NULL);
-        if (op != NULL)
-            pa_operation_unref(op);
-        op = pa_stream_drain(s, NULL, NULL);
-        if (op != NULL)
+        if (pa_stream_is_corked(s) > 0)
+            /* Stream paused: discard all buffers */
+            op = pa_stream_flush(s, stream_success_cb, NULL);
+        else
+            /* Stream playing: wait until buffers are played */
+            op = pa_stream_drain(s, stream_success_cb, NULL);
+        if (likely(op != NULL)) {
+#ifdef LIBPULSE_GETS_A_CLUE
+            while (pa_operation_get_state(op) == PA_OPERATION_RUNNING)
+                vlc_pa_wait();
+#endif
             pa_operation_unref(op);
+        }
+
         pa_stream_disconnect(s);
         pa_stream_unref(s);
     }



More information about the vlc-commits mailing list