예제 #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
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);
}
예제 #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;
}