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); } }
static int do_read_data(lcb_server_t *c, int allow_read) { lcb_sockrw_status_t status; lcb_size_t processed = 0; int rv = 0; /* ** The timers isn't supposed to be _that_ accurate.. it's better ** to shave off system calls :) */ hrtime_t stop = gethrtime(); if (allow_read) { status = lcb_sockrw_v0_slurp(&c->connection, c->connection.input); } else { status = LCB_SOCKRW_WOULDBLOCK; } while ((rv = lcb_proto_parse_single(c, stop)) > 0) { processed++; } if (rv == -1) { return -1; } if (processed) { lcb_connection_delay_timer(&c->connection); } if (status == LCB_SOCKRW_WOULDBLOCK || status == LCB_SOCKRW_READ) { return 0; } if (c->instance->compat.type == LCB_CACHED_CONFIG) { lcb_schedule_config_cache_refresh(c->instance); return 0; } return -1; }
/** * 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; }