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;
 
diff --git a/pulse/ctl_pulse.c b/pulse/ctl_pulse.c
index c6cf9e2..85863ed 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,13 @@ 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)
+		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);
@@ -180,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;
@@ -200,13 +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)
+		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);
@@ -215,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,
@@ -260,7 +289,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)
+		return -EBADFD;
 
 	pa_threaded_mainloop_lock(ctl->p->mainloop);
 
@@ -311,7 +342,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)
+		return -EBADFD;
 
 	pa_threaded_mainloop_lock(ctl->p->mainloop);
 
@@ -361,7 +394,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)
+		return -EBADFD;
 
 	pa_threaded_mainloop_lock(ctl->p->mainloop);
 
@@ -465,6 +500,9 @@ static void pulse_subscribe_events(snd_ctl_ext_t * ext, int subscribe)
 
 	assert(ctl);
 
+	if (!ctl->p || !ctl->p->mainloop)
+		return;
+
 	pa_threaded_mainloop_lock(ctl->p->mainloop);
 
 	ctl->subscribed = !!(subscribe & SND_CTL_EVENT_MASK_VALUE);
@@ -477,14 +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)
+		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;
@@ -523,18 +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);
-	assert(ctl->p);
+
+	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;
@@ -549,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 db8d1e1..02a837e 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;
@@ -106,18 +132,69 @@ static int update_active(snd_pcm_pulse_t *pcm) {
 
 	assert(pcm);
 
-	ret = check_active(pcm);
+	if (!pcm->p)
+		return -EBADFD;
+
+	ret = check_stream(pcm);
 	if (ret < 0)
-		return ret;
+		goto finish;
+
+	ret = check_active(pcm);
+
+finish:
 
-	if (ret > 0)
+	if (ret != 0) /* On error signal the caller, too */
 		pulse_poll_activate(pcm->p);
 	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;
@@ -125,26 +202,23 @@ 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 || !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;
 
-	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);
@@ -160,7 +234,6 @@ static int pulse_start(snd_pcm_ioplug_t * io)
 		goto finish;
 	}
 
-
 finish:
 	pa_threaded_mainloop_unlock(pcm->p->mainloop);
 
@@ -174,26 +247,23 @@ 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 || !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;
 
-	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;
@@ -224,15 +294,17 @@ static int pulse_drain(snd_pcm_ioplug_t * io)
 	int err = 0;
 
 	assert(pcm);
-	assert(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;
 
-	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;
@@ -259,7 +331,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 || !pcm->p->mainloop)
+		return -EBADFD;
 
 	if (io->state == SND_PCM_STATE_XRUN)
 		return -EPIPE;
@@ -269,9 +343,7 @@ static snd_pcm_sframes_t pulse_pointer(snd_pcm_ioplug_t * io)
 
 	pa_threaded_mainloop_lock(pcm->p->mainloop);
 
-	assert(pcm->stream);
-
-	ret = pulse_check_connection(pcm->p);
+	ret = check_stream(pcm);
 	if (ret < 0)
 		goto finish;
 
@@ -305,14 +377,14 @@ static int pulse_delay(snd_pcm_ioplug_t * io, snd_pcm_sframes_t * delayp)
 	pa_usec_t lat = 0;
 
 	assert(pcm);
-	assert(pcm->p);
 
-	pa_threaded_mainloop_lock(pcm->p->mainloop);
+	if (!pcm->p || !pcm->p->mainloop)
+		return -EBADFD;
 
-	assert(pcm->stream);
+	pa_threaded_mainloop_lock(pcm->p->mainloop);
 
 	for (;;) {
-		err = pulse_check_connection(pcm->p);
+		err = check_stream(pcm);
 		if (err < 0)
 			goto finish;
 
@@ -354,13 +426,13 @@ static snd_pcm_sframes_t pulse_write(snd_pcm_ioplug_t * io,
 	snd_pcm_sframes_t ret = 0;
 
 	assert(pcm);
-	assert(pcm->p);
 
-	pa_threaded_mainloop_lock(pcm->p->mainloop);
+	if (!pcm->p || !pcm->p->mainloop)
+		return -EBADFD;
 
-	assert(pcm->stream);
+	pa_threaded_mainloop_lock(pcm->p->mainloop);
 
-	ret = pulse_check_connection(pcm->p);
+	ret = check_stream(pcm);
 	if (ret < 0)
 		goto finish;
 
@@ -409,13 +481,13 @@ static snd_pcm_sframes_t pulse_read(snd_pcm_ioplug_t * io,
 	snd_pcm_sframes_t ret = 0;
 
 	assert(pcm);
-	assert(pcm->p);
 
-	pa_threaded_mainloop_lock(pcm->p->mainloop);
+	if (!pcm->p || !pcm->p->mainloop)
+		return -EBADFD;
 
-	assert(pcm->stream);
+	pa_threaded_mainloop_lock(pcm->p->mainloop);
 
-	ret = pulse_check_connection(pcm->p);
+	ret = check_stream(pcm);
 	if (ret < 0)
 		goto finish;
 
@@ -475,12 +547,31 @@ 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;
 
 	assert(pcm);
-	assert(pcm->p);
+
+	if (!pcm->p)
+		return;
 
 	update_active(pcm);
 }
@@ -490,7 +581,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 +592,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,12 +607,17 @@ 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 || !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;
 
@@ -541,14 +641,15 @@ static int pulse_prepare(snd_pcm_ioplug_t * io)
 	unsigned c, d;
 
 	assert(pcm);
-	assert(pcm->p);
+
+	if (!pcm->p || !pcm->p->mainloop)
+		return -EBADFD;
 
 	pa_threaded_mainloop_lock(pcm->p->mainloop);
 
 	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;
 	}
@@ -581,9 +682,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) {
@@ -620,8 +719,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);
@@ -645,7 +743,9 @@ static int pulse_hw_params(snd_pcm_ioplug_t * io,
 	int err = 0;
 
 	assert(pcm);
-	assert(pcm->p);
+
+	if (!pcm->p || !pcm->p->mainloop)
+		return -EBADFD;
 
 	pa_threaded_mainloop_lock(pcm->p->mainloop);
 
@@ -719,26 +819,56 @@ 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;
 }
 
+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 || !pcm->p->mainloop)
+		return -EBADFD;
+
+	pa_threaded_mainloop_lock(pcm->p->mainloop);
+
+	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;
+}
+
 static const snd_pcm_ioplug_callback_t pulse_playback_callback = {
 	.start = pulse_start,
 	.stop = pulse_stop,
@@ -750,6 +880,7 @@ static const snd_pcm_ioplug_callback_t pulse_playback_callback = {
 	.prepare = pulse_prepare,
 	.hw_params = pulse_hw_params,
 	.close = pulse_close,
+	.pause = pulse_pause
 };
 
 
diff --git a/pulse/pulse.c b/pulse/pulse.c
index 3940238..f26363a 100644
--- a/pulse/pulse.c
+++ b/pulse/pulse.c
@@ -32,37 +32,18 @@ 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);
 
-	if (state != PA_CONTEXT_READY)
+	if (!PA_CONTEXT_IS_GOOD(state))
 		return -EIO;
 
 	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;
@@ -77,8 +58,6 @@ int pulse_wait_operation(snd_pulse_t * p, pa_operation * o)
 {
 	assert(p);
 	assert(o);
-	assert(p->state == PULSE_STATE_READY);
-	assert(p->mainloop);
 
 	for (;;) {
 		int err;
@@ -96,44 +75,19 @@ 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);
-	assert(p->state == PULSE_STATE_READY);
-	assert(p->mainloop);
-
-	for (;;) {
-		int err;
-
-		err = pulse_check_connection(p);
-		if (err < 0)
-			return err;
-
-		state = pa_stream_get_state(stream);
-
-		if (state == target)
-			break;
-
-		if (state == PA_STREAM_FAILED ||
-		    state == PA_STREAM_TERMINATED)
-			return -EIO;
-
-		pa_threaded_mainloop_wait(p->mainloop);
-	}
-
-	return 0;
-}
-
 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:
@@ -171,8 +125,6 @@ snd_pulse_t *pulse_new(void)
 	if (!p)
 		return NULL;
 
-	p->state = PULSE_STATE_INIT;
-
 	if (pipe(fd)) {
 		free(p);
 		return NULL;
@@ -197,7 +149,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);
 
@@ -207,36 +161,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);
 }
@@ -244,11 +191,16 @@ 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);
-	assert(p->context);
-	assert(p->mainloop);
-	assert(p->state == PULSE_STATE_INIT);
+
+	if (!p->context || !p->mainloop)
+		return -EBADFD;
+
+	state = pa_context_get_state(p->context);
+	if (state != PA_CONTEXT_UNCONNECTED)
+		return -EBADFD;
 
 	pa_threaded_mainloop_lock(p->mainloop);
 
@@ -256,14 +208,19 @@ 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;
 
-	pa_threaded_mainloop_unlock(p->mainloop);
+		if (state == PA_CONTEXT_READY)
+			break;
 
-	p->state = PULSE_STATE_READY;
+		pa_threaded_mainloop_wait(p->mainloop);
+	}
+
+	pa_threaded_mainloop_unlock(p->mainloop);
 
 	return 0;
 
diff --git a/pulse/pulse.h b/pulse/pulse.h
index 7bf1a5b..e98124f 100644
--- a/pulse/pulse.h
+++ b/pulse/pulse.h
@@ -31,23 +31,13 @@ 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);
 
-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);
