static int do_read(struct userdata *u) { pa_assert(u); if (!pa_iochannel_is_readable(u->io)) return 0; if (u->state == STATE_AUTH || u->state == STATE_LATENCY) { ssize_t r; if (!u->read_data) return 0; pa_assert(u->read_index < u->read_length); if ((r = pa_iochannel_read(u->io, (uint8_t*) u->read_data + u->read_index, u->read_length - u->read_index)) <= 0) { pa_log("read() failed: %s", r < 0 ? pa_cstrerror(errno) : "EOF"); return -1; } u->read_index += (size_t) r; pa_assert(u->read_index <= u->read_length); if (u->read_index == u->read_length) return handle_response(u); } return 0; }
static void do_work(connection *c) { connection_assert_ref(c); if (c->dead) return; if (pa_iochannel_is_readable(c->io)) if (do_read(c) < 0) goto fail; if (!c->sink_input && pa_iochannel_is_hungup(c->io)) goto fail; if (pa_iochannel_is_writable(c->io)) if (do_write(c) < 0) goto fail; return; fail: if (c->sink_input) { /* If there is a sink input, we first drain what we already have read before shutting down the connection */ c->dead = TRUE; pa_iochannel_free(c->io); c->io = NULL; pa_asyncmsgq_post(c->sink_input->sink->asyncmsgq, PA_MSGOBJECT(c->sink_input), SINK_INPUT_MESSAGE_DISABLE_PREBUF, NULL, 0, NULL, NULL); } else connection_unlink(c); }