]> git.alsa-project.org Git - alsa-plugins.git/commitdiff
Properly terminate stream in polypaudio plugin
authorPierre Ossman <ossman@cendio.se>
Wed, 8 Mar 2006 12:16:51 +0000 (12:16 +0000)
committerTakashi Iwai <tiwai@suse.de>
Wed, 8 Mar 2006 12:16:51 +0000 (12:16 +0000)
Some applications like to call prepare over and over again, recreating
the stream each time. Previously we just cleaned up the local end each
time, but this makes sure the server also releases its resources.

Signed-off-by: Pierre Ossman <ossman@cendio.se>
polyp/pcm_polyp.c
polyp/polyp.c
polyp/polyp.h

index 84e3c346d3d6c851902a8e572c914aa8371f3c26..96f0baf3f7550cc8f8747b8e0acfec073c6fbdc1 100644 (file)
@@ -335,6 +335,8 @@ static int polyp_prepare(snd_pcm_ioplug_t *io)
         return err;
 
     if (pcm->stream) {
+        pa_stream_disconnect(pcm->stream);
+        polyp_wait_stream_state(pcm->p, pcm->stream, PA_STREAM_TERMINATED);
         pa_stream_unref(pcm->stream);
         pcm->stream = NULL;
     }
@@ -356,18 +358,12 @@ static int polyp_prepare(snd_pcm_ioplug_t *io)
     else
         pa_stream_connect_record(pcm->stream, pcm->device, &pcm->buffer_attr, 0);
 
-    while (1) {
-        state = pa_stream_get_state(pcm->stream);
-
-        if (state == PA_STREAM_FAILED)
-            goto error;
-
-        if (state == PA_STREAM_READY)
-            break;
-
-        err = pa_mainloop_iterate(pcm->p->mainloop, 1, NULL);
-        if (err < 0)
-            return -EIO;
+    err = polyp_wait_stream_state(pcm->p, pcm->stream, PA_STREAM_READY);
+    if (err < 0) {
+        fprintf(stderr, "*** POLYPAUDIO: Unable to create stream.\n");
+        pa_stream_unref(pcm->stream);
+        pcm->stream = NULL;
+        return err;
     }
 
     pcm->last_size = 0;
@@ -375,12 +371,6 @@ static int polyp_prepare(snd_pcm_ioplug_t *io)
     pcm->offset = 0;
 
     return 0;
-
-error:
-    fprintf(stderr, "*** POLYPAUDIO: Unable to create stream.\n");
-    pa_stream_unref(pcm->stream);
-    pcm->stream = NULL;
-    return -EIO;
 }
 
 static int polyp_hw_params(snd_pcm_ioplug_t *io, snd_pcm_hw_params_t *params)
@@ -437,8 +427,11 @@ static int polyp_close(snd_pcm_ioplug_t *io)
 
     assert(pcm);
 
-    if (pcm->stream)
+    if (pcm->stream) {
+        pa_stream_disconnect(pcm->stream);
+        polyp_wait_stream_state(pcm->p, pcm->stream, PA_STREAM_TERMINATED);
         pa_stream_unref(pcm->stream);
+    }
 
     if (pcm->p)
         polyp_free(pcm->p);
index 0b25ae5461f6ffa3b9c2ceeb704aa7c5e8ef0632..c6bc5e1e7a74197e89381e16501d97c2c9a799bd 100644 (file)
@@ -182,6 +182,32 @@ int polyp_wait_operation(snd_polyp_t *p, pa_operation *o)
     return 0;
 }
 
+int polyp_wait_stream_state(snd_polyp_t *p, pa_stream *stream, pa_stream_state_t target)
+{
+    int err;
+    pa_stream_state_t state;
+
+    assert(p && stream && (p->state == POLYP_STATE_READY));
+
+    while (1) {
+        state = pa_stream_get_state(stream);
+
+        if (state == PA_STREAM_FAILED)
+            return -EIO;
+
+        if (state == target)
+            break;
+
+        p->state = POLYP_STATE_POLLING;
+        err = pa_mainloop_iterate(p->mainloop, 1, NULL);
+        p->state = POLYP_STATE_READY;
+        if (err < 0)
+            return -EIO;
+    }
+
+    return 0;
+}
+
 snd_polyp_t *polyp_new()
 {
     snd_polyp_t *p;
index 60cf872a95db3245b8fef9403914692f2ad1b2da..8c2ab95f33038b5bbdeb678949dd8455baa17755 100644 (file)
@@ -48,6 +48,7 @@ int polyp_finish_poll(snd_polyp_t *p);
 int polyp_check_connection(snd_polyp_t *p);
 
 int polyp_wait_operation(snd_polyp_t *p, pa_operation *o);
+int polyp_wait_stream_state(snd_polyp_t *p, pa_stream *stream, pa_stream_state_t target);
 
 snd_polyp_t *polyp_new();
 void polyp_free(snd_polyp_t *p);