rpms/alsa-plugins/devel 0002-pulse-get-rid-of-a-number-of-assert-s.patch, NONE, 1.1 0003-pulse-use-PA_CONTEXT_IS_GOOD-where-applicable.patch, NONE, 1.1 0004-pulse-unify-destruction-of-snd_pulse_t.patch, NONE, 1.1 0005-pulse-call-pa_threaded_mainloop_wait-to-handle-spuri.patch, NONE, 1.1 0006-pulse-replace-manual-mainloop-by-pa_mainloop_iterate.patch, NONE, 1.1 0007-pulse-move-a-couple-of-PCM-related-functions-from-pu.patch, NONE, 1.1 0008-pulse-get-rid-of-redundant-state-variable.patch, NONE, 1.1 0009-pulse-unify-stream-context-state-checks.patch, NONE, 1.1 0010-pulse-rework-object-destruction-paths-a-bit.patch, NONE, 1.1 0011-pulse-immediately-trigger-EIO-when-connection-is-dro.patch, NONE, 1.1 alsa-plugins.spec, 1.25, 1.26 0001-alsa-get-rid-of-a-number-of-assert-s.patch, 1.1, NONE 0001-alsa-plugins-pulse-Implement-pause.patch, 1.1, NONE 0002-pulse-use-PA_CONTEXT_IS_GOOD-where-applicable.patch, 1.1, NONE 0003-pulse-unify-destruction-of-snd_pulse_t.patch, 1.1, NONE 0004-pulse-call-pa_threaded_mainloop_wait-to-handle-spuri.patch, 1.1, NONE

Lennart Poettering lennart at fedoraproject.org
Tue Aug 4 22:15:25 UTC 2009


Author: lennart

Update of /cvs/pkgs/rpms/alsa-plugins/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv18582

Modified Files:
	alsa-plugins.spec 
Added Files:
	0002-pulse-get-rid-of-a-number-of-assert-s.patch 
	0003-pulse-use-PA_CONTEXT_IS_GOOD-where-applicable.patch 
	0004-pulse-unify-destruction-of-snd_pulse_t.patch 
	0005-pulse-call-pa_threaded_mainloop_wait-to-handle-spuri.patch 
	0006-pulse-replace-manual-mainloop-by-pa_mainloop_iterate.patch 
	0007-pulse-move-a-couple-of-PCM-related-functions-from-pu.patch 
	0008-pulse-get-rid-of-redundant-state-variable.patch 
	0009-pulse-unify-stream-context-state-checks.patch 
	0010-pulse-rework-object-destruction-paths-a-bit.patch 
	0011-pulse-immediately-trigger-EIO-when-connection-is-dro.patch 
Removed Files:
	0001-alsa-get-rid-of-a-number-of-assert-s.patch 
	0001-alsa-plugins-pulse-Implement-pause.patch 
	0002-pulse-use-PA_CONTEXT_IS_GOOD-where-applicable.patch 
	0003-pulse-unify-destruction-of-snd_pulse_t.patch 
	0004-pulse-call-pa_threaded_mainloop_wait-to-handle-spuri.patch 
Log Message:
Add a couple of more clean up patches for the pulse plugin

0002-pulse-get-rid-of-a-number-of-assert-s.patch:
 ctl_pulse.c |   35 ++++++++++++++++++++------
 pcm_pulse.c |   79 ++++++++++++++++++++++++++++++++++++++++++++++--------------
 pulse.c     |   35 ++++++++++++++++++--------
 3 files changed, 112 insertions(+), 37 deletions(-)

--- NEW FILE 0002-pulse-get-rid-of-a-number-of-assert-s.patch ---
>From be8799947bac41c50460111b0ac20ff8176b6b47 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart at poettering.net>
Date: Fri, 31 Jul 2009 15:25:44 +0200
Subject: [PATCH 02/11] pulse: get rid of a number of assert()s

Instead of hitting an assert when any of the plugin functions is called
in an invalid context we should return a clean error to make sure
programs are not unnecessarily aborted.

This should fix issues such as http://pulseaudio.org/ticket/595

Signed-off-by: Takashi Iwai <tiwai at suse.de>
---
 pulse/ctl_pulse.c |   35 ++++++++++++++++++-----
 pulse/pcm_pulse.c |   79 +++++++++++++++++++++++++++++++++++++++++------------
 pulse/pulse.c     |   34 ++++++++++++++++-------
 3 files changed, 112 insertions(+), 36 deletions(-)

diff --git a/pulse/ctl_pulse.c b/pulse/ctl_pulse.c
index c6cf9e2..2caa29b 100644
--- a/pulse/ctl_pulse.c
+++ b/pulse/ctl_pulse.c
@@ -125,8 +125,9 @@ static void event_cb(pa_context * c, pa_subscription_event_type_t t,
 	pa_operation *o;
 
 	assert(ctl);
-	assert(ctl->p);
-	assert(ctl->p->context);
+
+	if (!ctl->p || !ctl->p->mainloop || !ctl->p->context)
+		return;
 
 	o = pa_context_get_sink_info_by_name(ctl->p->context, ctl->sink,
 					     sink_info_cb, ctl);
@@ -148,8 +149,9 @@ static int pulse_update_volume(snd_ctl_pulse_t * ctl)
 	pa_operation *o;
 
 	assert(ctl);
-	assert(ctl->p);
-	assert(ctl->p->context);
+
+	if (!ctl->p || !ctl->p->mainloop || !ctl->p->context)
+		return -EBADFD;
 
 	o = pa_context_get_sink_info_by_name(ctl->p->context, ctl->sink,
 					     sink_info_cb, ctl);
@@ -203,6 +205,9 @@ static int pulse_elem_list(snd_ctl_ext_t * ext, unsigned int offset,
 
 	assert(ctl);
 
+	if (!ctl->p || !ctl->p->mainloop || !ctl->p->context)
+		return -EBADFD;
+
 	snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
 
 	pa_threaded_mainloop_lock(ctl->p->mainloop);
@@ -260,7 +265,9 @@ static int pulse_get_attribute(snd_ctl_ext_t * ext, snd_ctl_ext_key_t key,
 		return -EINVAL;
 
 	assert(ctl);
-	assert(ctl->p);
+
+	if (!ctl->p || !ctl->p->mainloop || !ctl->p->context)
+		return -EBADFD;
 
 	pa_threaded_mainloop_lock(ctl->p->mainloop);
 
@@ -311,7 +318,9 @@ static int pulse_read_integer(snd_ctl_ext_t * ext, snd_ctl_ext_key_t key,
 	pa_cvolume *vol = NULL;
 
 	assert(ctl);
-	assert(ctl->p);
+
+	if (!ctl->p || !ctl->p->mainloop || !ctl->p->context)
+		return -EBADFD;
 
 	pa_threaded_mainloop_lock(ctl->p->mainloop);
 
@@ -361,7 +370,9 @@ static int pulse_write_integer(snd_ctl_ext_t * ext, snd_ctl_ext_key_t key,
 	pa_cvolume *vol = NULL;
 
 	assert(ctl);
-	assert(ctl->p && ctl->p->context);
+
+	if (!ctl->p || !ctl->p->mainloop || !ctl->p->context)
+		return -EBADFD;
 
 	pa_threaded_mainloop_lock(ctl->p->mainloop);
 
@@ -465,6 +476,9 @@ static void pulse_subscribe_events(snd_ctl_ext_t * ext, int subscribe)
 
 	assert(ctl);
 
+	if (!ctl->p || !ctl->p->mainloop || !ctl->p->context)
+		return;
+
 	pa_threaded_mainloop_lock(ctl->p->mainloop);
 
 	ctl->subscribed = !!(subscribe & SND_CTL_EVENT_MASK_VALUE);
@@ -481,6 +495,9 @@ static int pulse_read_event(snd_ctl_ext_t * ext, snd_ctl_elem_id_t * id,
 
 	assert(ctl);
 
+	if (!ctl->p || !ctl->p->mainloop || !ctl->p->context)
+		return -EBADFD;
+
 	pa_threaded_mainloop_lock(ctl->p->mainloop);
 
 	if (!ctl->updated || !ctl->subscribed)
@@ -526,7 +543,9 @@ static int pulse_ctl_poll_revents(snd_ctl_ext_t * ext, struct pollfd *pfd,
 	int err = 0;
 
 	assert(ctl);
-	assert(ctl->p);
+
+	if (!ctl->p || !ctl->p->mainloop || !ctl->p->context)
+		return -EBADFD;
 
 	pa_threaded_mainloop_lock(ctl->p->mainloop);
 
diff --git a/pulse/pcm_pulse.c b/pulse/pcm_pulse.c
index c276839..24347f9 100644
--- a/pulse/pcm_pulse.c
+++ b/pulse/pcm_pulse.c
@@ -106,6 +106,9 @@ static int update_active(snd_pcm_pulse_t *pcm) {
 
 	assert(pcm);
 
+	if (!pcm->p)
+		return -EBADFD;
+
 	ret = check_active(pcm);
 	if (ret < 0)
 		return ret;
@@ -125,7 +128,9 @@ static int pulse_start(snd_pcm_ioplug_t * io)
 	int err = 0, err_o = 0, err_u = 0;
 
 	assert(pcm);
-	assert(pcm->p);
+
+	if (!pcm->p)
+		return -EBADFD;
 
 	pa_threaded_mainloop_lock(pcm->p->mainloop);
 
@@ -174,7 +179,9 @@ static int pulse_stop(snd_pcm_ioplug_t * io)
 	int err = 0, err_o = 0, err_u = 0;
 
 	assert(pcm);
-	assert(pcm->p);
+
+	if (!pcm->p)
+		return -EBADFD;
 
 	pa_threaded_mainloop_lock(pcm->p->mainloop);
 
@@ -224,7 +231,9 @@ static int pulse_drain(snd_pcm_ioplug_t * io)
 	int err = 0;
 
 	assert(pcm);
-	assert(pcm->p);
+
+	if (!pcm->p)
+		return -EBADFD;
 
 	pa_threaded_mainloop_lock(pcm->p->mainloop);
 
@@ -259,7 +268,9 @@ static snd_pcm_sframes_t pulse_pointer(snd_pcm_ioplug_t * io)
 	snd_pcm_sframes_t ret = 0;
 
 	assert(pcm);
-	assert(pcm->p);
+
+	if (!pcm->p)
+		return -EBADFD;
 
 	if (io->state == SND_PCM_STATE_XRUN)
 		return -EPIPE;
@@ -269,7 +280,10 @@ static snd_pcm_sframes_t pulse_pointer(snd_pcm_ioplug_t * io)
 
 	pa_threaded_mainloop_lock(pcm->p->mainloop);
 
-	assert(pcm->stream);
+	if (!pcm->stream) {
+		ret = -EBADFD;
+		goto finish;
+	}
 
 	ret = pulse_check_connection(pcm->p);
 	if (ret < 0)
@@ -305,11 +319,16 @@ static int pulse_delay(snd_pcm_ioplug_t * io, snd_pcm_sframes_t * delayp)
 	pa_usec_t lat = 0;
 
 	assert(pcm);
-	assert(pcm->p);
+
+	if (!pcm->p)
+		return -EBADFD;
 
 	pa_threaded_mainloop_lock(pcm->p->mainloop);
 
-	assert(pcm->stream);
+	if (!pcm->stream) {
+		err = -EBADFD;
+		goto finish;
+	}
 
 	for (;;) {
 		err = pulse_check_connection(pcm->p);
@@ -354,11 +373,16 @@ static snd_pcm_sframes_t pulse_write(snd_pcm_ioplug_t * io,
 	snd_pcm_sframes_t ret = 0;
 
 	assert(pcm);
-	assert(pcm->p);
+
+	if (!pcm->p)
+		return -EBADFD;
 
 	pa_threaded_mainloop_lock(pcm->p->mainloop);
 
-	assert(pcm->stream);
+	if (!pcm->stream) {
+		ret = -EBADFD;
+		goto finish;
+	}
 
 	ret = pulse_check_connection(pcm->p);
 	if (ret < 0)
@@ -409,11 +433,16 @@ static snd_pcm_sframes_t pulse_read(snd_pcm_ioplug_t * io,
 	snd_pcm_sframes_t ret = 0;
 
 	assert(pcm);
-	assert(pcm->p);
+
+	if (!pcm->p)
+		return -EBADFD;
 
 	pa_threaded_mainloop_lock(pcm->p->mainloop);
 
-	assert(pcm->stream);
+	if (!pcm->stream) {
+		ret = -EBADFD;
+		goto finish;
+	}
 
 	ret = pulse_check_connection(pcm->p);
 	if (ret < 0)
@@ -480,7 +509,9 @@ static void stream_request_cb(pa_stream * p, size_t length, void *userdata)
 	snd_pcm_pulse_t *pcm = userdata;
 
 	assert(pcm);
-	assert(pcm->p);
+
+	if (!pcm->p)
+		return;
 
 	update_active(pcm);
 }
@@ -490,7 +521,9 @@ static void stream_underrun_cb(pa_stream * p, void *userdata)
 	snd_pcm_pulse_t *pcm = userdata;
 
 	assert(pcm);
-	assert(pcm->p);
+
+	if (!pcm->p)
+		return;
 
 	pcm->underrun = 1;
 }
@@ -499,7 +532,9 @@ static void stream_latency_cb(pa_stream *p, void *userdata) {
 	snd_pcm_pulse_t *pcm = userdata;
 
 	assert(pcm);
-	assert(pcm->p);
+
+	if (!pcm->p)
+		return;
 
 	pa_threaded_mainloop_signal(pcm->p->mainloop, 0);
 }
@@ -512,7 +547,9 @@ static int pulse_pcm_poll_revents(snd_pcm_ioplug_t * io,
 	snd_pcm_pulse_t *pcm = io->private_data;
 
 	assert(pcm);
-	assert(pcm->p);
+
+	if (!pcm->p)
+		return -EBADFD;
 
 	pa_threaded_mainloop_lock(pcm->p->mainloop);
 
@@ -541,7 +578,9 @@ static int pulse_prepare(snd_pcm_ioplug_t * io)
 	unsigned c, d;
 
 	assert(pcm);
-	assert(pcm->p);
+
+	if (!pcm->p)
+		return -EBADFD;
 
 	pa_threaded_mainloop_lock(pcm->p->mainloop);
 
@@ -645,7 +684,9 @@ static int pulse_hw_params(snd_pcm_ioplug_t * io,
 	int err = 0;
 
 	assert(pcm);
-	assert(pcm->p);
+
+	if (!pcm->p)
+		return -EBADFD;
 
 	pa_threaded_mainloop_lock(pcm->p->mainloop);
 
@@ -745,7 +786,9 @@ static int pulse_pause(snd_pcm_ioplug_t * io, int enable)
 	int err = 0;
 
 	assert (pcm);
-	assert (pcm->p);
+
+	if (!pcm->p)
+		return -EBADFD;
 
 	pa_threaded_mainloop_lock(pcm->p->mainloop);
 
diff --git a/pulse/pulse.c b/pulse/pulse.c
index 3940238..95d8dde 100644
--- a/pulse/pulse.c
+++ b/pulse/pulse.c
@@ -32,8 +32,9 @@ int pulse_check_connection(snd_pulse_t * p)
 	pa_context_state_t state;
 
 	assert(p);
-	assert(p->context);
-	assert(p->mainloop);
+
+	if (!p->context || !p->mainloop)
+		return -EBADFD;
 
 	state = pa_context_get_state(p->context);
 
@@ -77,8 +78,12 @@ int pulse_wait_operation(snd_pulse_t * p, pa_operation * o)
 {
 	assert(p);
 	assert(o);
-	assert(p->state == PULSE_STATE_READY);
-	assert(p->mainloop);
+
+	if (p->state != PULSE_STATE_READY)
+		return -EBADFD;
+
+	if (!p->mainloop)
+		return -EBADFD;
 
 	for (;;) {
 		int err;
@@ -103,8 +108,12 @@ int pulse_wait_stream_state(snd_pulse_t * p, pa_stream * stream,
 
 	assert(p);
 	assert(stream);
-	assert(p->state == PULSE_STATE_READY);
-	assert(p->mainloop);
+
+	if (p->state != PULSE_STATE_READY)
+		return -EBADFD;
+
+	if (!p->mainloop)
+		return -EBADFD;
 
 	for (;;) {
 		int err;
@@ -197,7 +206,9 @@ snd_pulse_t *pulse_new(void)
 
 	p->context =
 	    pa_context_new(pa_threaded_mainloop_get_api(p->mainloop), buf);
-	assert(p->context);
+
+	if (!p->context)
+		goto fail;
 
 	pa_context_set_state_callback(p->context, context_state_cb, p);
 
@@ -246,9 +257,12 @@ int pulse_connect(snd_pulse_t * p, const char *server)
 	int err;
 
 	assert(p);
-	assert(p->context);
-	assert(p->mainloop);
-	assert(p->state == PULSE_STATE_INIT);
+
+	if (!p->context || !p->mainloop)
+		return -EBADFD;
+
+	if (p->state != PULSE_STATE_INIT)
+		return -EBADFD;
 
 	pa_threaded_mainloop_lock(p->mainloop);
 
-- 
1.6.4


0003-pulse-use-PA_CONTEXT_IS_GOOD-where-applicable.patch:
 pulse.c |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

--- NEW FILE 0003-pulse-use-PA_CONTEXT_IS_GOOD-where-applicable.patch ---
>From d2ea09f162f114480516a9d993d3d71bf357c835 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <mznyfn at 0pointer.de>
Date: Fri, 31 Jul 2009 16:01:52 +0200
Subject: [PATCH 03/11] pulse: use PA_CONTEXT_IS_GOOD where applicable

PA_CONTEXT_IS_GOOD is a safer way to check whether a context is still
valid.

This patch also bumps the version requirement of libpulse to 0.9.11.

Signed-off-by: Takashi Iwai <tiwai at suse.de>
---
 pulse/pulse.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/pulse/pulse.c b/pulse/pulse.c
index 95d8dde..dd17384 100644
--- a/pulse/pulse.c
+++ b/pulse/pulse.c
@@ -38,7 +38,7 @@ int pulse_check_connection(snd_pulse_t * p)
 
 	state = pa_context_get_state(p->context);
 
-	if (state != PA_CONTEXT_READY)
+	if (!PA_CONTEXT_IS_GOOD(state))
 		return -EIO;
 
 	return 0;
@@ -127,8 +127,7 @@ int pulse_wait_stream_state(snd_pulse_t * p, pa_stream * stream,
 		if (state == target)
 			break;
 
-		if (state == PA_STREAM_FAILED ||
-		    state == PA_STREAM_TERMINATED)
+		if (!PA_STREAM_IS_GOOD(state))
 			return -EIO;
 
 		pa_threaded_mainloop_wait(p->mainloop);
-- 
1.6.4


0004-pulse-unify-destruction-of-snd_pulse_t.patch:
 pulse.c |   32 ++++++++++++--------------------
 1 file changed, 12 insertions(+), 20 deletions(-)

--- NEW FILE 0004-pulse-unify-destruction-of-snd_pulse_t.patch ---
>From 422958fa4b8101af842220a67e77c8090ad34a8b Mon Sep 17 00:00:00 2001
From: Lennart Poettering <mznyfn at 0pointer.de>
Date: Fri, 31 Jul 2009 16:02:05 +0200
Subject: [PATCH 04/11] pulse: unify destruction of snd_pulse_t

Signed-off-by: Takashi Iwai <tiwai at suse.de>
---
 pulse/pulse.c |   31 ++++++++++++-------------------
 1 files changed, 12 insertions(+), 19 deletions(-)

diff --git a/pulse/pulse.c b/pulse/pulse.c
index dd17384..ae66b0c 100644
--- a/pulse/pulse.c
+++ b/pulse/pulse.c
@@ -217,36 +217,29 @@ snd_pulse_t *pulse_new(void)
 	return p;
 
 fail:
+	pulse_free(p);
+
+	return NULL;
+}
+
+void pulse_free(snd_pulse_t * p)
+{
 	if (p->mainloop)
 		pa_threaded_mainloop_stop(p->mainloop);
 
-	if (p->context)
+	if (p->context) {
+		pa_context_disconnect(p->context);
 		pa_context_unref(p->context);
+	}
 
 	if (p->mainloop)
 		pa_threaded_mainloop_free(p->mainloop);
 
-	if (p->main_fd >= 0)
-		close(p->main_fd);
-
 	if (p->thread_fd >= 0)
 		close(p->thread_fd);
 
-	free(p);
-
-	return NULL;
-}
-
-void pulse_free(snd_pulse_t * p)
-{
-	pa_threaded_mainloop_stop(p->mainloop);
-
-	pa_context_disconnect(p->context);
-	pa_context_unref(p->context);
-	pa_threaded_mainloop_free(p->mainloop);
-
-	close(p->thread_fd);
-	close(p->main_fd);
+	if (p->main_fd >= 0)
+		close(p->main_fd);
 
 	free(p);
 }
-- 
1.6.4


0005-pulse-call-pa_threaded_mainloop_wait-to-handle-spuri.patch:
 pulse.c |   14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

--- NEW FILE 0005-pulse-call-pa_threaded_mainloop_wait-to-handle-spuri.patch ---
>From 16f837ec71a254a6bff7d26faf55237c4df5749c Mon Sep 17 00:00:00 2001
From: Lennart Poettering <mznyfn at 0pointer.de>
Date: Fri, 31 Jul 2009 16:02:21 +0200
Subject: [PATCH 05/11] pulse: call pa_threaded_mainloop_wait() to handle spurious wakeups

pa_threaded_mainloop_wait() can wake up for no reason, according to the
specs of the underlying POSIX ptrhead_cond_wait() docs, so we need to
call it in a loop here which should be cleaner anyway.

Signed-off-by: Takashi Iwai <tiwai at suse.de>
---
 pulse/pulse.c |   13 ++++++++++---
 1 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/pulse/pulse.c b/pulse/pulse.c
index ae66b0c..6f58a7e 100644
--- a/pulse/pulse.c
+++ b/pulse/pulse.c
@@ -262,10 +262,17 @@ int pulse_connect(snd_pulse_t * p, const char *server)
 	if (err < 0)
 		goto error;
 
-	pa_threaded_mainloop_wait(p->mainloop);
+	for (;;) {
+		pa_context_state_t state = pa_context_get_state(p->context);
 
-	if (pa_context_get_state(p->context) != PA_CONTEXT_READY)
-		goto error;
+		if (!PA_CONTEXT_IS_GOOD(state))
+			goto error;
+
+		if (state == PA_CONTEXT_READY)
+			break;
+
+		pa_threaded_mainloop_wait(p->mainloop);
+	}
 
 	pa_threaded_mainloop_unlock(p->mainloop);
 
-- 
1.6.4


0006-pulse-replace-manual-mainloop-by-pa_mainloop_iterate.patch:
 conf_pulse.c |   11 +----------
 1 file changed, 1 insertion(+), 10 deletions(-)

--- NEW FILE 0006-pulse-replace-manual-mainloop-by-pa_mainloop_iterate.patch ---
>From 76d34749c05ba77614f648128ad7045681f547ae Mon Sep 17 00:00:00 2001
From: Lennart Poettering <mznyfn at 0pointer.de>
Date: Tue, 4 Aug 2009 23:53:51 +0200
Subject: [PATCH 06/11] pulse: replace manual mainloop by pa_mainloop_iterate()

The pa_mainloop_prepare()/_poll()/_dispatch() can be simplified by
simply calling pa_mainloop_iterate() which does all this in one call.

Signed-off-by: Takashi Iwai <tiwai at suse.de>
---
 pulse/conf_pulse.c |   10 +---------
 1 files changed, 1 insertions(+), 9 deletions(-)

diff --git a/pulse/conf_pulse.c b/pulse/conf_pulse.c
index 3f9e071..35dd383 100644
--- a/pulse/conf_pulse.c
+++ b/pulse/conf_pulse.c
@@ -61,15 +61,7 @@ conf_pulse_hook_load_if_running(snd_config_t * root, snd_config_t * config,
 		goto out;
 
 	do {
-		err = pa_mainloop_prepare(loop, -1);
-		if (err < 0)
-			goto out;
-
-		err = pa_mainloop_poll(loop);
-		if (err < 0)
-			goto out;
-
-		err = pa_mainloop_dispatch(loop);
+		err = pa_mainloop_iterate(loop, 1, NULL);
 		if (err < 0)
 			goto out;
 
-- 
1.6.4


0007-pulse-move-a-couple-of-PCM-related-functions-from-pu.patch:
 pcm_pulse.c |  118 ++++++++++++++++++++++++++++++++++++++++++++++++------------
 pulse.c     |   55 ---------------------------
 pulse.h     |    5 --
 3 files changed, 95 insertions(+), 83 deletions(-)

--- NEW FILE 0007-pulse-move-a-couple-of-PCM-related-functions-from-pu.patch ---
>From f74878bc610bccc4656f8194f29176cf9c956de9 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <mznyfn at 0pointer.de>
Date: Tue, 4 Aug 2009 23:54:24 +0200
Subject: [PATCH 07/11] pulse: move a couple of PCM related functions from pulse.c to pcm_pulse.c

A number of functions in pulse.c are only relevant for the PCM handling,
so let's move them to pcm_pulse.c. This allows us to simplify their
argument lists a bit.

Signed-off-by: Takashi Iwai <tiwai at suse.de>
---
 pulse/pcm_pulse.c |  118 ++++++++++++++++++++++++++++++++++++++++++----------
 pulse/pulse.c     |   55 -------------------------
 pulse/pulse.h     |    4 --
 3 files changed, 95 insertions(+), 82 deletions(-)

diff --git a/pulse/pcm_pulse.c b/pulse/pcm_pulse.c
index 24347f9..a625f55 100644
--- a/pulse/pcm_pulse.c
+++ b/pulse/pcm_pulse.c
@@ -49,6 +49,32 @@ typedef struct snd_pcm_pulse {
 	pa_buffer_attr buffer_attr;
 } snd_pcm_pulse_t;
 
+static int check_stream(snd_pcm_pulse_t *pcm)
+{
+	int err;
+	pa_stream_state_t state;
+
+	assert(pcm);
+
+	if (!pcm->p)
+		return -EBADFD;
+
+	err = pulse_check_connection(pcm->p);
+	if (err < 0)
+		return err;
+
+	if (!pcm->stream)
+		return -EBADFD;
+
+	state = pa_stream_get_state(pcm->stream);
+	if (!PA_STREAM_IS_GOOD(state))
+		return -EIO;
+
+	err = 0;
+
+	return err;
+}
+
 static int update_ptr(snd_pcm_pulse_t *pcm)
 {
 	size_t size;
@@ -118,9 +144,53 @@ static int update_active(snd_pcm_pulse_t *pcm) {
 	else
 		pulse_poll_deactivate(pcm->p);
 
+	return ret;
+}
+
+static int wait_stream_state(snd_pcm_pulse_t *pcm, pa_stream_state_t target)
+{
+	pa_stream_state_t state;
+
+	assert(pcm);
+
+	if (!pcm->p)
+		return -EBADFD;
+
+	for (;;) {
+		int err;
+
+		err = pulse_check_connection(pcm->p);
+		if (err < 0)
+			return err;
+
+		if (!pcm->stream)
+			return -EBADFD;
+
+		state = pa_stream_get_state(pcm->stream);
+		if (state == target)
+			break;
+
+		if (!PA_STREAM_IS_GOOD(state))
+			return -EIO;
+
+		pa_threaded_mainloop_wait(pcm->p->mainloop);
+	}
+
 	return 0;
 }
 
+static void stream_success_cb(pa_stream * p, int success, void *userdata)
+{
+	snd_pcm_pulse_t *pcm = userdata;
+
+	assert(pcm);
+
+	if (!pcm->p)
+		return;
+
+	pa_threaded_mainloop_signal(pcm->p->mainloop, 0);
+}
+
 static int pulse_start(snd_pcm_ioplug_t * io)
 {
 	snd_pcm_pulse_t *pcm = io->private_data;
@@ -138,18 +208,13 @@ static int pulse_start(snd_pcm_ioplug_t * io)
 	if (err < 0)
 		goto finish;
 
-	if (pcm->stream == NULL)
-		goto finish;
-
-	o = pa_stream_cork(pcm->stream, 0, pulse_stream_success_cb,
-			   pcm->p);
+	o = pa_stream_cork(pcm->stream, 0, stream_success_cb, pcm);
 	if (!o) {
 		err = -EIO;
 		goto finish;
 	}
 
-	u = pa_stream_trigger(pcm->stream, pulse_stream_success_cb,
-			      pcm->p);
+	u = pa_stream_trigger(pcm->stream, stream_success_cb, pcm);
 
 	pcm->underrun = 0;
 	err_o = pulse_wait_operation(pcm->p, o);
@@ -165,7 +230,6 @@ static int pulse_start(snd_pcm_ioplug_t * io)
 		goto finish;
 	}
 
-
 finish:
 	pa_threaded_mainloop_unlock(pcm->p->mainloop);
 
@@ -189,18 +253,13 @@ static int pulse_stop(snd_pcm_ioplug_t * io)
 	if (err < 0)
 		goto finish;
 
-	if (pcm->stream == NULL)
-		goto finish;
-
-	o = pa_stream_cork(pcm->stream, 1, pulse_stream_success_cb,
-			   pcm->p);
+	o = pa_stream_cork(pcm->stream, 1, stream_success_cb, pcm);
 	if (!o) {
 		err = -EIO;
 		goto finish;
 	}
 
-	u = pa_stream_flush(pcm->stream, pulse_stream_success_cb,
-			    pcm->p);
+	u = pa_stream_flush(pcm->stream, stream_success_cb, pcm);
 	if (!u) {
 		pa_operation_unref(o);
 		err = -EIO;
@@ -241,7 +300,7 @@ static int pulse_drain(snd_pcm_ioplug_t * io)
 	if (err < 0)
 		goto finish;
 
-	o = pa_stream_drain(pcm->stream, pulse_stream_success_cb, pcm->p);
+	o = pa_stream_drain(pcm->stream, stream_success_cb, pcm);
 	if (!o) {
 		err = -EIO;
 		goto finish;
@@ -504,6 +563,23 @@ finish:
 	return ret;
 }
 
+static void stream_state_cb(pa_stream * p, void *userdata)
+{
+	snd_pcm_pulse_t *pcm = userdata;
+	pa_stream_state_t state;
+
+	assert(pcm);
+
+	if (!pcm->p)
+		return;
+
+	state = pa_stream_get_state(p);
+	if (!PA_STREAM_IS_GOOD(state))
+		pulse_poll_activate(pcm->p);
+
+	pa_threaded_mainloop_signal(pcm->p->mainloop, 0);
+}
+
 static void stream_request_cb(pa_stream * p, size_t length, void *userdata)
 {
 	snd_pcm_pulse_t *pcm = userdata;
@@ -586,8 +662,7 @@ static int pulse_prepare(snd_pcm_ioplug_t * io)
 
 	if (pcm->stream) {
 		pa_stream_disconnect(pcm->stream);
-		pulse_wait_stream_state(pcm->p, pcm->stream,
-					PA_STREAM_TERMINATED);
+		wait_stream_state(pcm, PA_STREAM_TERMINATED);
 		pa_stream_unref(pcm->stream);
 		pcm->stream = NULL;
 	}
@@ -620,9 +695,7 @@ static int pulse_prepare(snd_pcm_ioplug_t * io)
 		goto finish;
 	}
 
-	pa_stream_set_state_callback(pcm->stream, pulse_stream_state_cb,
-				     pcm->p);
-
+	pa_stream_set_state_callback(pcm->stream, stream_state_cb, pcm);
 	pa_stream_set_latency_update_callback(pcm->stream, stream_latency_cb, pcm);
 
 	if (io->stream == SND_PCM_STREAM_PLAYBACK) {
@@ -659,8 +732,7 @@ static int pulse_prepare(snd_pcm_ioplug_t * io)
 		goto finish;
 	}
 
-	err =
-	    pulse_wait_stream_state(pcm->p, pcm->stream, PA_STREAM_READY);
+	err = wait_stream_state(pcm, PA_STREAM_READY);
 	if (err < 0) {
 		SNDERR("PulseAudio: Unable to create stream: %s\n", pa_strerror(pa_context_errno(pcm->p->context)));
 		pa_stream_unref(pcm->stream);
diff --git a/pulse/pulse.c b/pulse/pulse.c
index 6f58a7e..c313182 100644
--- a/pulse/pulse.c
+++ b/pulse/pulse.c
@@ -44,26 +44,6 @@ int pulse_check_connection(snd_pulse_t * p)
 	return 0;
 }
 
-void pulse_stream_state_cb(pa_stream * s, void *userdata)
-{
-	snd_pulse_t *p = userdata;
-
-	assert(s);
-	assert(p);
-
-	pa_threaded_mainloop_signal(p->mainloop, 0);
-}
-
-void pulse_stream_success_cb(pa_stream * s, int success, void *userdata)
-{
-	snd_pulse_t *p = userdata;
-
-	assert(s);
-	assert(p);
-
-	pa_threaded_mainloop_signal(p->mainloop, 0);
-}
-
 void pulse_context_success_cb(pa_context * c, int success, void *userdata)
 {
 	snd_pulse_t *p = userdata;
@@ -101,41 +81,6 @@ int pulse_wait_operation(snd_pulse_t * p, pa_operation * o)
 	return 0;
 }
 
-int pulse_wait_stream_state(snd_pulse_t * p, pa_stream * stream,
-			    pa_stream_state_t target)
-{
-	pa_stream_state_t state;
-
-	assert(p);
-	assert(stream);
-
-	if (p->state != PULSE_STATE_READY)
-		return -EBADFD;
-
-	if (!p->mainloop)
-		return -EBADFD;
-
-	for (;;) {
-		int err;
-
-		err = pulse_check_connection(p);
-		if (err < 0)
-			return err;
-
-		state = pa_stream_get_state(stream);
-
-		if (state == target)
-			break;
-
-		if (!PA_STREAM_IS_GOOD(state))
-			return -EIO;
-
-		pa_threaded_mainloop_wait(p->mainloop);
-	}
-
-	return 0;
-}
-
 static void context_state_cb(pa_context * c, void *userdata)
 {
 	snd_pulse_t *p = userdata;
diff --git a/pulse/pulse.h b/pulse/pulse.h
index 7bf1a5b..51f9a11 100644
--- a/pulse/pulse.h
+++ b/pulse/pulse.h
@@ -41,13 +41,9 @@ typedef struct snd_pulse {
 
 int pulse_check_connection(snd_pulse_t * p);
 
-void pulse_stream_state_cb(pa_stream * s, void *userdata);
-void pulse_stream_success_cb(pa_stream * s, int success, void *userdata);
 void pulse_context_success_cb(pa_context * c, int success, void *userdata);
 
 int pulse_wait_operation(snd_pulse_t * p, pa_operation * o);
-int pulse_wait_stream_state(snd_pulse_t * p, pa_stream * stream,
-			    pa_stream_state_t target);
 
 snd_pulse_t *pulse_new(void);
 void pulse_free(snd_pulse_t * p);
-- 
1.6.4


0008-pulse-get-rid-of-redundant-state-variable.patch:
 pulse.c |   14 +++-----------
 pulse.h |    7 -------
 2 files changed, 3 insertions(+), 18 deletions(-)

--- NEW FILE 0008-pulse-get-rid-of-redundant-state-variable.patch ---
>From c3acf0f4df121fef0014bd165fa86ccb1060d669 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <mznyfn at 0pointer.de>
Date: Tue, 4 Aug 2009 23:54:42 +0200
Subject: [PATCH 08/11] pulse: get rid of redundant state variable

snd_pulse_t::state was mostly shadowing the state of
pa_context_get_state(snd_pulse_t::context), so get rid of it and use the
state of the context directly.

Signed-off-by: Takashi Iwai <tiwai at suse.de>
---
 pulse/pulse.c |   14 +++-----------
 pulse/pulse.h |    6 ------
 2 files changed, 3 insertions(+), 17 deletions(-)

diff --git a/pulse/pulse.c b/pulse/pulse.c
index c313182..9c05171 100644
--- a/pulse/pulse.c
+++ b/pulse/pulse.c
@@ -59,12 +59,6 @@ int pulse_wait_operation(snd_pulse_t * p, pa_operation * o)
 	assert(p);
 	assert(o);
 
-	if (p->state != PULSE_STATE_READY)
-		return -EBADFD;
-
-	if (!p->mainloop)
-		return -EBADFD;
-
 	for (;;) {
 		int err;
 
@@ -124,8 +118,6 @@ snd_pulse_t *pulse_new(void)
 	if (!p)
 		return NULL;
 
-	p->state = PULSE_STATE_INIT;
-
 	if (pipe(fd)) {
 		free(p);
 		return NULL;
@@ -192,13 +184,15 @@ void pulse_free(snd_pulse_t * p)
 int pulse_connect(snd_pulse_t * p, const char *server)
 {
 	int err;
+	pa_context_state_t state;
 
 	assert(p);
 
 	if (!p->context || !p->mainloop)
 		return -EBADFD;
 
-	if (p->state != PULSE_STATE_INIT)
+	state = pa_context_get_state(p->context);
+	if (state != PA_CONTEXT_UNCONNECTED)
 		return -EBADFD;
 
 	pa_threaded_mainloop_lock(p->mainloop);
@@ -221,8 +215,6 @@ int pulse_connect(snd_pulse_t * p, const char *server)
 
 	pa_threaded_mainloop_unlock(p->mainloop);
 
-	p->state = PULSE_STATE_READY;
-
 	return 0;
 
       error:
diff --git a/pulse/pulse.h b/pulse/pulse.h
index 51f9a11..e98124f 100644
--- a/pulse/pulse.h
+++ b/pulse/pulse.h
@@ -31,12 +31,6 @@ typedef struct snd_pulse {
 	pa_context *context;
 
 	int thread_fd, main_fd;
-
-	enum {
-		PULSE_STATE_INIT,
-		PULSE_STATE_READY,
-	} state;
-
 } snd_pulse_t;
 
 int pulse_check_connection(snd_pulse_t * p);
-- 
1.6.4


0009-pulse-unify-stream-context-state-checks.patch:
 ctl_pulse.c |   72 ++++++++++++++++++++++++++++++++++++-----------
 pcm_pulse.c |   91 ++++++++++++++++++++++++++----------------------------------
 2 files changed, 95 insertions(+), 68 deletions(-)

--- NEW FILE 0009-pulse-unify-stream-context-state-checks.patch ---
>From 59ccd2aca941b4653803f5415b4985ab35de0c35 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <mznyfn at 0pointer.de>
Date: Tue, 4 Aug 2009 23:55:05 +0200
Subject: [PATCH 09/11] pulse: unify stream/context state checks

Unify (and simplify) the paths that check for the validity of a
stream/context: always call into check_stream()/pulse_check_connection()
when applicable instead of rolling our own checks each time. Also check
for validity of mainloop before locking it.

Signed-off-by: Takashi Iwai <tiwai at suse.de>
---
 pulse/ctl_pulse.c |   72 ++++++++++++++++++++++++++++++++----------
 pulse/pcm_pulse.c |   90 +++++++++++++++++++++++-----------------------------
 2 files changed, 95 insertions(+), 67 deletions(-)

diff --git a/pulse/ctl_pulse.c b/pulse/ctl_pulse.c
index 2caa29b..879f260 100644
--- a/pulse/ctl_pulse.c
+++ b/pulse/ctl_pulse.c
@@ -150,9 +150,13 @@ static int pulse_update_volume(snd_ctl_pulse_t * ctl)
 
 	assert(ctl);
 
-	if (!ctl->p || !ctl->p->mainloop || !ctl->p->context)
+	if (!ctl->p)
 		return -EBADFD;
 
+	err = pulse_check_connection(ctl->p);
+	if (err < 0)
+		return err;
+
 	o = pa_context_get_sink_info_by_name(ctl->p->context, ctl->sink,
 					     sink_info_cb, ctl);
 	if (o) {
@@ -182,17 +186,27 @@ static int pulse_update_volume(snd_ctl_pulse_t * ctl)
 static int pulse_elem_count(snd_ctl_ext_t * ext)
 {
 	snd_ctl_pulse_t *ctl = ext->private_data;
-	int count = 0;
+	int count = 0, err;
 
 	assert(ctl);
 
+	if (!ctl->p || !ctl->p->mainloop)
+		return -EBADFD;
+
 	pa_threaded_mainloop_lock(ctl->p->mainloop);
 
+	err = pulse_check_connection(ctl->p);
+	if (err < 0) {
+		count = err;
+		goto finish;
+	}
+
 	if (ctl->source)
 		count += 2;
 	if (ctl->sink)
 		count += 2;
 
+finish:
 	pa_threaded_mainloop_unlock(ctl->p->mainloop);
 
 	return count;
@@ -202,16 +216,21 @@ static int pulse_elem_list(snd_ctl_ext_t * ext, unsigned int offset,
 			   snd_ctl_elem_id_t * id)
 {
 	snd_ctl_pulse_t *ctl = ext->private_data;
+	int err;
 
 	assert(ctl);
 
-	if (!ctl->p || !ctl->p->mainloop || !ctl->p->context)
+	if (!ctl->p || !ctl->p->mainloop)
 		return -EBADFD;
 
 	snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER);
 
 	pa_threaded_mainloop_lock(ctl->p->mainloop);
 
+	err = pulse_check_connection(ctl->p);
+	if (err < 0)
+		goto finish;
+
 	if (ctl->source) {
 		if (offset == 0)
 			snd_ctl_elem_id_set_name(id, SOURCE_VOL_NAME);
@@ -220,14 +239,19 @@ static int pulse_elem_list(snd_ctl_ext_t * ext, unsigned int offset,
 	} else
 		offset += 2;
 
+	err = 0;
+
+finish:
 	pa_threaded_mainloop_unlock(ctl->p->mainloop);
 
-	if (offset == 2)
-		snd_ctl_elem_id_set_name(id, SINK_VOL_NAME);
-	else if (offset == 3)
-		snd_ctl_elem_id_set_name(id, SINK_MUTE_NAME);
+	if (err >= 0) {
+		if (offset == 2)
+			snd_ctl_elem_id_set_name(id, SINK_VOL_NAME);
+		else if (offset == 3)
+			snd_ctl_elem_id_set_name(id, SINK_MUTE_NAME);
+	}
 
-	return 0;
+	return err;
 }
 
 static snd_ctl_ext_key_t pulse_find_elem(snd_ctl_ext_t * ext,
@@ -266,7 +290,7 @@ static int pulse_get_attribute(snd_ctl_ext_t * ext, snd_ctl_ext_key_t key,
 
 	assert(ctl);
 
-	if (!ctl->p || !ctl->p->mainloop || !ctl->p->context)
+	if (!ctl->p || !ctl->p->mainloop)
 		return -EBADFD;
 
 	pa_threaded_mainloop_lock(ctl->p->mainloop);
@@ -319,7 +343,7 @@ static int pulse_read_integer(snd_ctl_ext_t * ext, snd_ctl_ext_key_t key,
 
 	assert(ctl);
 
-	if (!ctl->p || !ctl->p->mainloop || !ctl->p->context)
+	if (!ctl->p || !ctl->p->mainloop)
 		return -EBADFD;
 
 	pa_threaded_mainloop_lock(ctl->p->mainloop);
@@ -371,7 +395,7 @@ static int pulse_write_integer(snd_ctl_ext_t * ext, snd_ctl_ext_key_t key,
 
 	assert(ctl);
 
-	if (!ctl->p || !ctl->p->mainloop || !ctl->p->context)
+	if (!ctl->p || !ctl->p->mainloop)
 		return -EBADFD;
 
 	pa_threaded_mainloop_lock(ctl->p->mainloop);
@@ -476,7 +500,7 @@ static void pulse_subscribe_events(snd_ctl_ext_t * ext, int subscribe)
 
 	assert(ctl);
 
-	if (!ctl->p || !ctl->p->mainloop || !ctl->p->context)
+	if (!ctl->p || !ctl->p->mainloop)
 		return;
 
 	pa_threaded_mainloop_lock(ctl->p->mainloop);
@@ -491,17 +515,23 @@ static int pulse_read_event(snd_ctl_ext_t * ext, snd_ctl_elem_id_t * id,
 {
 	snd_ctl_pulse_t *ctl = ext->private_data;
 	int offset;
-	int err = -EAGAIN;
+	int err;
 
 	assert(ctl);
 
-	if (!ctl->p || !ctl->p->mainloop || !ctl->p->context)
+	if (!ctl->p || !ctl->p->mainloop)
 		return -EBADFD;
 
 	pa_threaded_mainloop_lock(ctl->p->mainloop);
 
-	if (!ctl->updated || !ctl->subscribed)
+	err = pulse_check_connection(ctl->p);
+	if (err < 0)
+		goto finish;
+
+	if (!ctl->updated || !ctl->subscribed) {
+		err = -EAGAIN;
 		goto finish;
+	}
 
 	if (ctl->source)
 		offset = 2;
@@ -540,20 +570,28 @@ static int pulse_ctl_poll_revents(snd_ctl_ext_t * ext, struct pollfd *pfd,
 				  unsigned short *revents)
 {
 	snd_ctl_pulse_t *ctl = ext->private_data;
-	int err = 0;
+	int err;
 
 	assert(ctl);
 
-	if (!ctl->p || !ctl->p->mainloop || !ctl->p->context)
+	if (!ctl->p || !ctl->p->mainloop)
 		return -EBADFD;
 
 	pa_threaded_mainloop_lock(ctl->p->mainloop);
 
+	err = pulse_check_connection(ctl->p);
+	if (err < 0)
+		goto finish;
+
 	if (ctl->updated)
 		*revents = POLLIN;
 	else
 		*revents = 0;
 
+	err = 0;
+
+finish:
+
 	pa_threaded_mainloop_unlock(ctl->p->mainloop);
 
 	return err;
diff --git a/pulse/pcm_pulse.c b/pulse/pcm_pulse.c
index a625f55..98983f8 100644
--- a/pulse/pcm_pulse.c
+++ b/pulse/pcm_pulse.c
@@ -135,11 +135,15 @@ static int update_active(snd_pcm_pulse_t *pcm) {
 	if (!pcm->p)
 		return -EBADFD;
 
-	ret = check_active(pcm);
+	ret = check_stream(pcm);
 	if (ret < 0)
-		return ret;
+		goto finish;
+
+	ret = check_active(pcm);
 
-	if (ret > 0)
+finish:
+
+	if (ret != 0) /* On error signal the caller, too */
 		pulse_poll_activate(pcm->p);
 	else
 		pulse_poll_deactivate(pcm->p);
@@ -199,12 +203,12 @@ static int pulse_start(snd_pcm_ioplug_t * io)
 
 	assert(pcm);
 
-	if (!pcm->p)
+	if (!pcm->p || !pcm->p->mainloop)
 		return -EBADFD;
 
 	pa_threaded_mainloop_lock(pcm->p->mainloop);
 
-	err = pulse_check_connection(pcm->p);
+	err = check_stream(pcm);
 	if (err < 0)
 		goto finish;
 
@@ -244,12 +248,12 @@ static int pulse_stop(snd_pcm_ioplug_t * io)
 
 	assert(pcm);
 
-	if (!pcm->p)
+	if (!pcm->p || !pcm->p->mainloop)
 		return -EBADFD;
 
 	pa_threaded_mainloop_lock(pcm->p->mainloop);
 
-	err = pulse_check_connection(pcm->p);
+	err = check_stream(pcm);
 	if (err < 0)
 		goto finish;
 
@@ -291,12 +295,12 @@ static int pulse_drain(snd_pcm_ioplug_t * io)
 
 	assert(pcm);
 
-	if (!pcm->p)
+	if (!pcm->p || !pcm->p->mainloop)
 		return -EBADFD;
 
 	pa_threaded_mainloop_lock(pcm->p->mainloop);
 
-	err = pulse_check_connection(pcm->p);
+	err = check_stream(pcm);
 	if (err < 0)
 		goto finish;
 
@@ -328,7 +332,7 @@ static snd_pcm_sframes_t pulse_pointer(snd_pcm_ioplug_t * io)
 
 	assert(pcm);
 
-	if (!pcm->p)
+	if (!pcm->p || !pcm->p->mainloop)
 		return -EBADFD;
 
 	if (io->state == SND_PCM_STATE_XRUN)
@@ -339,12 +343,7 @@ static snd_pcm_sframes_t pulse_pointer(snd_pcm_ioplug_t * io)
 
 	pa_threaded_mainloop_lock(pcm->p->mainloop);
 
-	if (!pcm->stream) {
-		ret = -EBADFD;
-		goto finish;
-	}
-
-	ret = pulse_check_connection(pcm->p);
+	ret = check_stream(pcm);
 	if (ret < 0)
 		goto finish;
 
@@ -379,18 +378,13 @@ static int pulse_delay(snd_pcm_ioplug_t * io, snd_pcm_sframes_t * delayp)
 
 	assert(pcm);
 
-	if (!pcm->p)
+	if (!pcm->p || !pcm->p->mainloop)
 		return -EBADFD;
 
 	pa_threaded_mainloop_lock(pcm->p->mainloop);
 
-	if (!pcm->stream) {
-		err = -EBADFD;
-		goto finish;
-	}
-
 	for (;;) {
-		err = pulse_check_connection(pcm->p);
+		err = check_stream(pcm);
 		if (err < 0)
 			goto finish;
 
@@ -433,17 +427,12 @@ static snd_pcm_sframes_t pulse_write(snd_pcm_ioplug_t * io,
 
 	assert(pcm);
 
-	if (!pcm->p)
+	if (!pcm->p || !pcm->p->mainloop)
 		return -EBADFD;
 
 	pa_threaded_mainloop_lock(pcm->p->mainloop);
 
-	if (!pcm->stream) {
-		ret = -EBADFD;
-		goto finish;
-	}
-
-	ret = pulse_check_connection(pcm->p);
+	ret = check_stream(pcm);
 	if (ret < 0)
 		goto finish;
 
@@ -493,17 +482,12 @@ static snd_pcm_sframes_t pulse_read(snd_pcm_ioplug_t * io,
 
 	assert(pcm);
 
-	if (!pcm->p)
+	if (!pcm->p || !pcm->p->mainloop)
 		return -EBADFD;
 
 	pa_threaded_mainloop_lock(pcm->p->mainloop);
 
-	if (!pcm->stream) {
-		ret = -EBADFD;
-		goto finish;
-	}
-
-	ret = pulse_check_connection(pcm->p);
+	ret = check_stream(pcm);
 	if (ret < 0)
 		goto finish;
 
@@ -624,13 +608,16 @@ static int pulse_pcm_poll_revents(snd_pcm_ioplug_t * io,
 
 	assert(pcm);
 
-	if (!pcm->p)
+	if (!pcm->p || !pcm->p->mainloop)
 		return -EBADFD;
 
 	pa_threaded_mainloop_lock(pcm->p->mainloop);
 
-	err = check_active(pcm);
+	err = check_stream(pcm);
+	if (err < 0)
+		goto finish;
 
+	err = check_active(pcm);
 	if (err < 0)
 		goto finish;
 
@@ -655,7 +642,7 @@ static int pulse_prepare(snd_pcm_ioplug_t * io)
 
 	assert(pcm);
 
-	if (!pcm->p)
+	if (!pcm->p || !pcm->p->mainloop)
 		return -EBADFD;
 
 	pa_threaded_mainloop_lock(pcm->p->mainloop);
@@ -757,7 +744,7 @@ static int pulse_hw_params(snd_pcm_ioplug_t * io,
 
 	assert(pcm);
 
-	if (!pcm->p)
+	if (!pcm->p || !pcm->p->mainloop)
 		return -EBADFD;
 
 	pa_threaded_mainloop_lock(pcm->p->mainloop);
@@ -856,23 +843,26 @@ static int pulse_pause(snd_pcm_ioplug_t * io, int enable)
 {
 	snd_pcm_pulse_t *pcm = io->private_data;
 	int err = 0;
+	pa_operation *o;
 
 	assert (pcm);
 
-	if (!pcm->p)
+	if (!pcm->p || !pcm->p->mainloop)
 		return -EBADFD;
 
 	pa_threaded_mainloop_lock(pcm->p->mainloop);
 
-	if (pcm->stream) {
-		pa_operation *o;
-		o = pa_stream_cork(pcm->stream, enable, NULL, NULL);
-		if (o)
-			pa_operation_unref(o);
-		else
-			err = -EIO;
-	}
+	err = check_stream(pcm);
+	if (err < 0)
+		goto finish;
+
+	o = pa_stream_cork(pcm->stream, enable, NULL, NULL);
+	if (o)
+		pa_operation_unref(o);
+	else
+		err = -EIO;
 
+finish:
 	pa_threaded_mainloop_unlock(pcm->p->mainloop);
 
 	return err;
-- 
1.6.4


0010-pulse-rework-object-destruction-paths-a-bit.patch:
 ctl_pulse.c |    7 ++-----
 pcm_pulse.c |   20 ++++++++++----------
 2 files changed, 12 insertions(+), 15 deletions(-)

--- NEW FILE 0010-pulse-rework-object-destruction-paths-a-bit.patch ---
>From 50562a9d5d54270ab67f183013204d24cdbeff21 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <mznyfn at 0pointer.de>
Date: Tue, 4 Aug 2009 23:55:28 +0200
Subject: [PATCH 10/11] pulse: rework object destruction paths a bit

Make sure we deal better with partially initialized structs.

Don't check for pointer state before calling free() since free() does
that anyway.

Signed-off-by: Takashi Iwai <tiwai at suse.de>
---
 pulse/ctl_pulse.c |    7 ++-----
 pulse/pcm_pulse.c |   19 ++++++++++---------
 2 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/pulse/ctl_pulse.c b/pulse/ctl_pulse.c
index 879f260..85863ed 100644
--- a/pulse/ctl_pulse.c
+++ b/pulse/ctl_pulse.c
@@ -606,11 +606,8 @@ static void pulse_close(snd_ctl_ext_t * ext)
 	if (ctl->p)
 		pulse_free(ctl->p);
 
-	if (ctl->source)
-		free(ctl->source);
-	if (ctl->sink)
-		free(ctl->sink);
-
+	free(ctl->source);
+	free(ctl->sink);
 	free(ctl);
 }
 
diff --git a/pulse/pcm_pulse.c b/pulse/pcm_pulse.c
index 98983f8..02a837e 100644
--- a/pulse/pcm_pulse.c
+++ b/pulse/pcm_pulse.c
@@ -819,21 +819,22 @@ static int pulse_close(snd_pcm_ioplug_t * io)
 
 	assert(pcm);
 
-	pa_threaded_mainloop_lock(pcm->p->mainloop);
+	if (pcm->p && pcm->p->mainloop) {
 
-	if (pcm->stream) {
-		pa_stream_disconnect(pcm->stream);
-		pa_stream_unref(pcm->stream);
-	}
+		pa_threaded_mainloop_lock(pcm->p->mainloop);
 
-	pa_threaded_mainloop_unlock(pcm->p->mainloop);
+		if (pcm->stream) {
+			pa_stream_disconnect(pcm->stream);
+			pa_stream_unref(pcm->stream);
+		}
+
+		pa_threaded_mainloop_unlock(pcm->p->mainloop);
+	}
 
 	if (pcm->p)
 		pulse_free(pcm->p);
 
-	if (pcm->device)
-		free(pcm->device);
-
+	free(pcm->device);
 	free(pcm);
 
 	return 0;
-- 
1.6.4


0011-pulse-immediately-trigger-EIO-when-connection-is-dro.patch:
 pulse.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

--- NEW FILE 0011-pulse-immediately-trigger-EIO-when-connection-is-dro.patch ---
>From 4c71fdd22dbfaf7b5fb7de62bbc9dd4002e788db Mon Sep 17 00:00:00 2001
From: Lennart Poettering <mznyfn at 0pointer.de>
Date: Tue, 4 Aug 2009 23:56:00 +0200
Subject: [PATCH 11/11] pulse: immediately trigger EIO when connection is dropped

When the connection is dropped notify the application immediately
instead of waiting until the applications calls into us the next time.

This makes "aplay" handle connections shutdown similar to hardware
unplugs: an immediate EIO is thrown.

Signed-off-by: Takashi Iwai <tiwai at suse.de>
---
 pulse/pulse.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/pulse/pulse.c b/pulse/pulse.c
index 9c05171..f26363a 100644
--- a/pulse/pulse.c
+++ b/pulse/pulse.c
@@ -77,10 +77,17 @@ int pulse_wait_operation(snd_pulse_t * p, pa_operation * o)
 
 static void context_state_cb(pa_context * c, void *userdata)
 {
+	pa_context_state_t state;
 	snd_pulse_t *p = userdata;
 	assert(c);
 
-	switch (pa_context_get_state(c)) {
+	state = pa_context_get_state(c);
+
+	/* When we get disconnected, tell the process */
+	if (!PA_CONTEXT_IS_GOOD(state))
+		pulse_poll_activate(p);
+
+	switch (state) {
 	case PA_CONTEXT_READY:
 	case PA_CONTEXT_TERMINATED:
 	case PA_CONTEXT_FAILED:
-- 
1.6.4



Index: alsa-plugins.spec
===================================================================
RCS file: /cvs/pkgs/rpms/alsa-plugins/devel/alsa-plugins.spec,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -p -r1.25 -r1.26
--- alsa-plugins.spec	31 Jul 2009 14:04:31 -0000	1.25
+++ alsa-plugins.spec	4 Aug 2009 22:15:24 -0000	1.26
@@ -1,6 +1,6 @@
 Name:           alsa-plugins
 Version:        1.0.20
-Release:        4%{?dist}
+Release:        5%{?dist}
 Summary:        The Advanced Linux Sound Architecture (ALSA) Plugins
 # All packages are LGPLv2+ with the exception of samplerate which is GPLv2+
 License:        GPLv2+ and LGPLv2+
@@ -16,11 +16,17 @@ Source6:        vdownmix.conf
 Source7:        pulse-default.conf
 Source8:        arcamav.conf
 BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
-Patch0:		0001-alsa-plugins-pulse-Implement-pause.patch
-Patch1:		0001-alsa-get-rid-of-a-number-of-assert-s.patch
-Patch2:		0002-pulse-use-PA_CONTEXT_IS_GOOD-where-applicable.patch
-Patch3:		0003-pulse-unify-destruction-of-snd_pulse_t.patch
-Patch4:		0004-pulse-call-pa_threaded_mainloop_wait-to-handle-spuri.patch
+Patch1:		0001-alsa-plugins-pulse-Implement-pause.patch
+Patch2:		0002-pulse-get-rid-of-a-number-of-assert-s.patch
+Patch3:		0003-pulse-use-PA_CONTEXT_IS_GOOD-where-applicable.patch
+Patch4:		0004-pulse-unify-destruction-of-snd_pulse_t.patch
+Patch5:		0005-pulse-call-pa_threaded_mainloop_wait-to-handle-spuri.patch
+Patch6:		0006-pulse-replace-manual-mainloop-by-pa_mainloop_iterate.patch
+Patch7:		0007-pulse-move-a-couple-of-PCM-related-functions-from-pu.patch
+Patch8:		0008-pulse-get-rid-of-redundant-state-variable.patch
+Patch9:		0009-pulse-unify-stream-context-state-checks.patch
+Patch10:	0010-pulse-rework-object-destruction-paths-a-bit.patch
+Patch11:	0011-pulse-immediately-trigger-EIO-when-connection-is-dro.patch
 
 BuildRequires:  alsa-lib-devel
 
@@ -128,11 +134,17 @@ pre-processing of a mono stream like den
 
 %prep
 %setup -q -n %{name}-%{version}%{?prever}
-%patch0 -p1
 %patch1 -p1 
 %patch2 -p1 
 %patch3 -p1 
 %patch4 -p1 
+%patch5 -p1
+%patch6 -p1
+%patch7 -p1
+%patch8 -p1
+%patch9 -p1
+%patch10 -p1
+%patch11 -p1
 
 %build
 %configure --disable-static \
@@ -235,6 +247,9 @@ rm -rf $RPM_BUILD_ROOT
 
 
 %changelog
+* Tue Aug 4 2009 Lennart Poettering <lpoetter at redhat.com> - 1.0.20-5
+- Add a couple of more clean up patches for the pulse plugin
+
 * Fri Jul 31 2009 Lennart Poettering <lpoetter at redhat.com> - 1.0.20-4
 - Add a couple of clean up patches for the pulse plugin
 


--- 0001-alsa-get-rid-of-a-number-of-assert-s.patch DELETED ---


--- 0001-alsa-plugins-pulse-Implement-pause.patch DELETED ---


--- 0002-pulse-use-PA_CONTEXT_IS_GOOD-where-applicable.patch DELETED ---


--- 0003-pulse-unify-destruction-of-snd_pulse_t.patch DELETED ---


--- 0004-pulse-call-pa_threaded_mainloop_wait-to-handle-spuri.patch DELETED ---




More information about the scm-commits mailing list