static void v0_generic_handler(lcb_socket_t sock, short which, void *arg) { lcb_connection_t conn = arg; lcb_sockrw_status_t status; lcb_size_t oldnr, newnr; lcb_assert(sock != INVALID_SOCKET); if (which & LCB_WRITE_EVENT) { status = lcb_sockrw_v0_write(conn, conn->output); if (status == LCB_SOCKRW_WROTE) { if ((which & LCB_READ_EVENT) == 0) { lcb_sockrw_set_want(conn, LCB_READ_EVENT, 1); lcb_sockrw_apply_want(conn); } } else if (status == LCB_SOCKRW_WOULDBLOCK) { lcb_sockrw_set_want(conn, LCB_WRITE_EVENT, 0); lcb_sockrw_apply_want(conn); } else { conn->easy.error(conn); return; } } if ( (which & LCB_READ_EVENT) == 0) { return; } oldnr = conn->input->nbytes; status = lcb_sockrw_v0_slurp(conn, conn->input); newnr = conn->input->nbytes; if (status != LCB_SOCKRW_READ && status != LCB_SOCKRW_WOULDBLOCK && oldnr == newnr) { conn->easy.error(conn); } else { conn->easy.read(conn); } }
void lcb_server_v0_event_handler(lcb_socket_t sock, short which, void *arg) { lcb_server_t *c = arg; lcb_connection_t conn = &c->connection; (void)sock; if (which & LCB_WRITE_EVENT) { lcb_sockrw_status_t status; status = lcb_sockrw_v0_write(conn, conn->output); if (status != LCB_SOCKRW_WROTE && status != LCB_SOCKRW_WOULDBLOCK) { event_complete_common(c, LCB_NETWORK_ERROR); return; } } if (which & LCB_READ_EVENT || conn->input->nbytes) { if (do_read_data(c, which & LCB_READ_EVENT) != 0) { /* TODO stash error message somewhere * "Failed to read from connection to \"%s:%s\"", c->hostname, c->port */ event_complete_common(c, LCB_NETWORK_ERROR); return; } } /** * Because of the operations-per-call limit, we might still need to read * a bit more once the event loop calls us again. We can't assume a * non-blocking read if we don't expect any data, but we can usually rely * on a non-blocking write. */ if (conn->output->nbytes || conn->input->nbytes) { which = LCB_RW_EVENT; } else { which = LCB_READ_EVENT; } lcb_sockrw_set_want(conn, which, 1); event_complete_common(c, LCB_SUCCESS); }
/** * Callback from libevent when we read from the REST socket * @param sock the readable socket * @param which what kind of events we may do * @param arg pointer to the libcouchbase instance */ static void config_v0_handler(lcb_socket_t sock, short which, void *arg) { lcb_t instance = arg; lcb_connection_t conn = &instance->bootstrap.via.http.connection; lcb_sockrw_status_t status; lcb_assert(sock != INVALID_SOCKET); if ((which & LCB_WRITE_EVENT) == LCB_WRITE_EVENT) { status = lcb_sockrw_v0_write(conn, conn->output); if (status != LCB_SOCKRW_WROTE && status != LCB_SOCKRW_WOULDBLOCK) { lcb_bootstrap_error(instance, LCB_NETWORK_ERROR, "Problem with sending data. " "Failed to send data to REST server", 0); return; } if (lcb_sockrw_flushed(conn)) { lcb_sockrw_set_want(conn, LCB_READ_EVENT, 1); } } if ((which & LCB_READ_EVENT) == 0) { return; } status = lcb_sockrw_v0_slurp(conn, conn->input); if (status != LCB_SOCKRW_READ && status != LCB_SOCKRW_WOULDBLOCK) { lcb_bootstrap_error(instance, LCB_NETWORK_ERROR, "Problem with reading data. " "Failed to send read data from REST server", 0); return; } handle_vbstream_read(instance); (void)sock; }