示例#1
0
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);
    }
}
示例#2
0
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;
}
示例#3
0
/**
 * 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;
}