diff options
Diffstat (limited to 'src/pulsecore/ioline.c')
-rw-r--r-- | src/pulsecore/ioline.c | 48 |
1 files changed, 45 insertions, 3 deletions
diff --git a/src/pulsecore/ioline.c b/src/pulsecore/ioline.c index 5c38d6e5..7afdb08c 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); @@ -266,7 +283,7 @@ static int do_read(pa_ioline *l) { pa_assert(l); pa_assert(PA_REFCNT_VALUE(l) >= 1); - while (!l->dead && pa_iochannel_is_readable(l->io)) { + while (l->io && !l->dead && pa_iochannel_is_readable(l->io)) { ssize_t r; size_t len; @@ -331,12 +348,12 @@ static int do_write(pa_ioline *l) { pa_assert(l); pa_assert(PA_REFCNT_VALUE(l) >= 1); - while (!l->dead && pa_iochannel_is_writable(l->io) && l->wbuf_valid_length) { + while (l->io && !l->dead && pa_iochannel_is_writable(l->io) && l->wbuf_valid_length > 0) { 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; } @@ -423,3 +443,25 @@ void pa_ioline_printf(pa_ioline *l, const char *format, ...) { pa_ioline_puts(l, t); pa_xfree(t); } + +pa_iochannel* pa_ioline_detach_iochannel(pa_ioline *l) { + pa_iochannel *r; + + pa_assert(l); + + if (!l->io) + return NULL; + + r = l->io; + l->io = NULL; + + pa_iochannel_set_callback(r, NULL, NULL); + + return r; +} + +pa_bool_t pa_ioline_is_drained(pa_ioline *l) { + pa_assert(l); + + return l->wbuf_valid_length <= 0; +} |