From a64097ab1f3be781aae36f8e66a3ce03987629c3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 29 Apr 2009 04:14:23 +0200 Subject: ioline: add callback that can be called when the ioline object is fully drained --- src/pulsecore/ioline.c | 22 +++++++++++++++++++++- src/pulsecore/ioline.h | 4 ++++ 2 files changed, 25 insertions(+), 1 deletion(-) (limited to 'src/pulsecore') diff --git a/src/pulsecore/ioline.c b/src/pulsecore/ioline.c index 5c38d6e5..7f252bc4 100644 --- a/src/pulsecore/ioline.c +++ b/src/pulsecore/ioline.c @@ -57,6 +57,9 @@ struct pa_ioline { pa_ioline_cb_t callback; void *userdata; + pa_ioline_drain_cb_t drain_callback; + void *drain_userdata; + pa_bool_t dead:1; pa_bool_t defer_close:1; }; @@ -81,6 +84,9 @@ pa_ioline* pa_ioline_new(pa_iochannel *io) { l->callback = NULL; l->userdata = NULL; + l->drain_callback = NULL; + l->drain_userdata = NULL; + l->mainloop = pa_iochannel_get_mainloop_api(io); l->defer_event = l->mainloop->defer_new(l->mainloop, defer_callback, l); @@ -202,6 +208,17 @@ void pa_ioline_set_callback(pa_ioline*l, pa_ioline_cb_t callback, void *userdata l->userdata = userdata; } +void pa_ioline_set_drain_callback(pa_ioline*l, pa_ioline_drain_cb_t callback, void *userdata) { + pa_assert(l); + pa_assert(PA_REFCNT_VALUE(l) >= 1); + + if (l->dead) + return; + + l->drain_callback = callback; + l->drain_userdata = userdata; +} + static void failure(pa_ioline *l, pa_bool_t process_leftover) { pa_assert(l); pa_assert(PA_REFCNT_VALUE(l) >= 1); @@ -336,7 +353,7 @@ static int do_write(pa_ioline *l) { if ((r = pa_iochannel_write(l->io, l->wbuf+l->wbuf_index, l->wbuf_valid_length)) <= 0) { if (r < 0 && errno == EAGAIN) - return 0; + break; if (r < 0 && errno != EPIPE) pa_log("write(): %s", pa_cstrerror(errno)); @@ -354,6 +371,9 @@ static int do_write(pa_ioline *l) { l->wbuf_index = 0; } + if (l->wbuf_valid_length <= 0 && l->drain_callback) + l->drain_callback(l, l->drain_userdata); + return 0; } diff --git a/src/pulsecore/ioline.h b/src/pulsecore/ioline.h index 9f32d60f..26e2a22c 100644 --- a/src/pulsecore/ioline.h +++ b/src/pulsecore/ioline.h @@ -32,6 +32,7 @@ typedef struct pa_ioline pa_ioline; typedef void (*pa_ioline_cb_t)(pa_ioline*io, const char *s, void *userdata); +typedef void (*pa_ioline_drain_cb_t)(pa_ioline *io, void *userdata); pa_ioline* pa_ioline_new(pa_iochannel *io); void pa_ioline_unref(pa_ioline *l); @@ -47,6 +48,9 @@ void pa_ioline_printf(pa_ioline *s, const char *format, ...) PA_GCC_PRINTF_ATTR( /* Set the callback function that is called for every recieved line */ void pa_ioline_set_callback(pa_ioline*io, pa_ioline_cb_t callback, void *userdata); +/* Set the callback function that is called when everything has been written */ +void pa_ioline_set_drain_callback(pa_ioline*io, pa_ioline_drain_cb_t callback, void *userdata); + /* Make sure to close the ioline object as soon as the send buffer is emptied */ void pa_ioline_defer_close(pa_ioline *io); -- cgit