+ struct pa_operation *o;
+ assert(p && p->direction == PA_STREAM_PLAYBACK);
+
+ if (p->dead) {
+ if (perror)
+ *perror = pa_context_errno(p->context);
+
+ return -1;
+ }
+
+ o = pa_stream_drain(p->stream, drain_or_flush_complete, p);
+
+ while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) {
+ if (iterate(p, 1, perror) < 0) {
+ pa_operation_cancel(o);
+ pa_operation_unref(o);
+ return -1;
+ }
+ }
+
+ pa_operation_unref(o);
+
+ if (p->dead && perror)
+ *perror = pa_context_errno(p->context);
+
+ return p->dead ? -1 : 0;
+}
+
+static void latency_complete(struct pa_stream *s, const struct pa_latency_info *l, void *userdata) {
+ struct pa_simple *p = userdata;
+ assert(s && p);
+
+ if (!l)
+ p->dead = 1;
+ else {
+ int negative = 0;
+ p->latency = pa_stream_get_latency(s, l, &negative);
+ if (negative)
+ p->latency = 0;
+ }
+}
+
+pa_usec_t pa_simple_get_playback_latency(struct pa_simple *p, int *perror) {
+ struct pa_operation *o;
+ assert(p && p->direction == PA_STREAM_PLAYBACK);
+
+ if (p->dead) {
+ if (perror)
+ *perror = pa_context_errno(p->context);
+
+ return (pa_usec_t) -1;
+ }
+
+ p->latency = 0;
+ o = pa_stream_get_latency_info(p->stream, latency_complete, p);
+
+ while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) {
+
+ if (iterate(p, 1, perror) < 0) {
+ pa_operation_cancel(o);
+ pa_operation_unref(o);
+ return -1;
+ }
+ }
+
+ pa_operation_unref(o);
+
+ if (p->dead && perror)
+ *perror = pa_context_errno(p->context);
+
+ return p->dead ? (pa_usec_t) -1 : p->latency;
+}
+
+int pa_simple_flush(struct pa_simple *p, int *perror) {
+ struct pa_operation *o;