Esempio n. 1
0
static int do_fill_input_buffer(libcouchbase_server_t *c)
{
    struct libcouchbase_iovec_st iov[2];
    libcouchbase_ssize_t nr;

    if (!ringbuffer_ensure_capacity(&c->input, 8192)) {
        libcouchbase_error_handler(c->instance, LIBCOUCHBASE_CLIENT_ENOMEM, NULL);
        return -1;
    }

    ringbuffer_get_iov(&c->input, RINGBUFFER_WRITE, iov);

    nr = c->instance->io->recvv(c->instance->io, c->sock, iov, 2);
    if (nr == -1) {
        switch (c->instance->io->error) {
        case EINTR:
            break;
        case EWOULDBLOCK:
            return 0;
        default:
            libcouchbase_failout_server(c, LIBCOUCHBASE_NETWORK_ERROR);
            return -1;
        }
    } else if (nr == 0) {
        assert((iov[0].iov_len + iov[1].iov_len) != 0);
        /* TODO stash error message somewhere
         * "Connection closed... we should resend to other nodes or reconnect!!" */
        libcouchbase_failout_server(c, LIBCOUCHBASE_NETWORK_ERROR);
        return -1;
    } else {
        ringbuffer_produced(&c->input, (libcouchbase_size_t)nr);
    }

    return 1;
}
Esempio n. 2
0
void libcouchbase_server_event_handler(libcouchbase_socket_t sock, short which, void *arg) {
    libcouchbase_server_t *c = arg;
    (void)sock;

    if (which & LIBCOUCHBASE_READ_EVENT) {
        if (do_read_data(c) != 0) {
            /* TODO stash error message somewhere
             * "Failed to read from connection to \"%s:%s\"", c->hostname, c->port */
            libcouchbase_failout_server(c, LIBCOUCHBASE_NETWORK_ERROR);
            return;
        }
    }

    if (which & LIBCOUCHBASE_WRITE_EVENT) {
        if (c->connected) {
            hrtime_t now = gethrtime();
            hrtime_t tmo = c->instance->timeout.usec;
            tmo *= 1000;
            if (c->next_timeout != 0 && (now > (tmo + c->next_timeout))) {
                libcouchbase_purge_single_server(c,
                                                 &c->cmd_log,
                                                 &c->output_cookies,
                                                 tmo, now,
                                                 LIBCOUCHBASE_ETIMEDOUT);
            }
        }

        if (do_send_data(c) != 0) {
            /* TODO stash error message somewhere
             * "Failed to send to the connection to \"%s:%s\"", c->hostname, c->port */
            libcouchbase_failout_server(c, LIBCOUCHBASE_NETWORK_ERROR);
            return;
        }
    }

    if (c->output.nbytes == 0) {
        c->instance->io->update_event(c->instance->io, c->sock,
                                      c->event, LIBCOUCHBASE_READ_EVENT,
                                      c, libcouchbase_server_event_handler);
    } else {
        c->instance->io->update_event(c->instance->io, c->sock,
                                      c->event, LIBCOUCHBASE_RW_EVENT,
                                      c, libcouchbase_server_event_handler);
    }

    libcouchbase_maybe_breakout(c->instance);

    /* Make it known that this was a success. */
    libcouchbase_error_handler(c->instance, LIBCOUCHBASE_SUCCESS, NULL);
}
Esempio n. 3
0
static int do_send_data(libcouchbase_server_t *c)
{
    do {
        struct libcouchbase_iovec_st iov[2];
        libcouchbase_ssize_t nw;
        ringbuffer_get_iov(&c->output, RINGBUFFER_READ, iov);
        nw = c->instance->io->sendv(c->instance->io, c->sock, iov, 2);
        if (nw == -1) {
            switch (c->instance->io->error) {
            case EINTR:
                /* retry */
                break;
            case EWOULDBLOCK:
                return 0;
            default:
                libcouchbase_failout_server(c, LIBCOUCHBASE_NETWORK_ERROR);
                return -1;
            }
        } else {
            ringbuffer_consumed(&c->output, (libcouchbase_size_t)nw);
        }
    } while (c->output.nbytes > 0);

    return 0;
}