示例#1
0
static void async_cb(uv_async_t *handle, int status)
{
    lcb_luv_socket_t sock = (lcb_luv_socket_t)handle->data;
    log_loop_trace("prepcb start");

    if (!sock) {
        fprintf(stderr, "We were called with prepare_t %p, with a missing socket\n",
                (void *)handle);
        return;
    }

    sock->async_state |= LCB_LUV_ASYNCf_ENTERED;
    do {

        if (ASYNC_IS(sock, DEINIT)) {
            /**
             * We were requested to asynchronously be cancelled
             */
            sock->async_state = 0;
            lcb_luv_socket_deinit(sock);
            break;
        }

        lcb_luv_socket_ref(sock);

        sock->async_state &= (~LCB_LUV_ASYNCf_REDO);
        maybe_callout(sock);

        lcb_luv_socket_unref(sock);

    } while (ASYNC_IS(sock, REDO));

    sock->async_state &= ~(
                             LCB_LUV_ASYNCf_ENTERED |
                             LCB_LUV_ASYNCf_REDO |
                             LCB_LUV_ASYNCf_SCHEDULED
                         );

    /**
     * we don't have an actual 'async_stop', so decrement the refcount
     * once more
     */
    lcb_luv_socket_unref(sock);

    log_loop_trace("prepcb stop");
    (void)status;
}
示例#2
0
static void
prepare_cb(uv_prepare_t *handle, int status)
{
    lcb_luv_socket_t sock = (lcb_luv_socket_t)handle->data;
    log_loop_trace("prepcb start");
    if (!sock) {
        fprintf(stderr, "We were called with prepare_t %p, with a missing socket\n",
                (void*)handle);
        return;
    }

    lcb_luv_socket_ref(sock);
    maybe_callout(sock);
    lcb_luv_socket_unref(sock);
    log_loop_trace("prepcb stop");
    (void)status;
}
示例#3
0
void
lcb_luv_schedule_disable(lcb_luv_socket_t sock)
{
    if (sock->prep_active == 0) {
        log_loop_trace("prep_active is false");
        return;
    }
    log_loop_debug("Disabling prepare");
    uv_prepare_stop(&sock->prep);
    lcb_luv_socket_unref(sock);
    sock->prep_active = 0;
}
示例#4
0
文件: common.c 项目: mgetz/couchnode
static void
async_cb(uv_async_t *handle, int status)
{
    lcb_luv_socket_t sock = (lcb_luv_socket_t)handle->data;
    log_loop_trace("prepcb start");

    if (!sock) {
        fprintf(stderr, "We were called with prepare_t %p, with a missing socket\n",
                (void*)handle);
        return;
    }

    sock->async_entered = 1;

    do {
        lcb_luv_socket_ref(sock);

        sock->async_redo = 0;
        maybe_callout(sock);

        lcb_luv_socket_unref(sock);

    } while (sock->async_redo);

    sock->async_entered = 0;
    sock->async_active = 0;

    /**
     * we don't have an actual 'async_stop', so decrement the refcount
     * once more
     */
    lcb_luv_socket_unref(sock);

    log_loop_trace("prepcb stop");
    (void)status;
}
示例#5
0
文件: common.c 项目: mgetz/couchnode
/**
 * Deliver an asynchronous 'write-ready' notification to libcouchbase.
 * This will invoke the normal callback chains..
 *
 * So how this works is rather complicated. It is used primarily for
 * write-readiness (i.e. to let libcouchbase put data into our socket buffer).
 *
 * If requested from within the callback (i.e. async_cb itself), then we need
 * to heuristically decide what exactly lcb will do.
 *
 * If it's a simple write event (i.e. actually copying the data between buffers)
 * then our buffer will eventually become full and this function will fail
 * to set the async_redo flag.
 *
 * The case is different in connect though: while a connect-readiness
 * notification is a write event, it doesn't actually fill the socket with
 * anything, so there is the possibility of recursion.
 *
 * Furthermore, connect-'readiness' is an actual event in uv, so there is no
 * need for this readiness emulation.
 */
void
lcb_luv_send_async_write_ready(lcb_luv_socket_t sock)
{
    if (sock->async_entered) {
        /**
         * Doing extra checks here to ensure we don't end up inside a busy
         * loop.
         */
        struct lcb_luv_evstate_st *wev = EVSTATE_FIND(sock, WRITE);
        struct lcb_luv_evstate_st *cev = EVSTATE_FIND(sock, CONNECT);

        if (!EVSTATE_IS(cev, CONNECTED)) {
            log_loop_debug("Not iterating again for phony write event");
            return;
        }

        if (EVSTATE_IS(wev, FLUSHING)) {
            log_loop_debug("Not requesting second iteration. "
                    "Already inside a flush");
            return;
        }

        if (sock->write.nb >= sizeof(sock->write.data)) {
            log_loop_debug("Not enough space to write..");
            return;
        }

        sock->async_redo = 1;
        return;
    }

    if (sock->async_active) {
        log_loop_trace("prep_active is true");
        return;
    }

    log_loop_debug("Will try and schedule prepare callback for %d", sock->idx);
    lcb_luv_socket_ref(sock);

    uv_async_send(&sock->async);
    sock->async_active = 1;
}
示例#6
-1
void
lcb_luv_schedule_enable(lcb_luv_socket_t sock)
{
    if (sock->prep_active) {
        log_loop_trace("prep_active is true");
        return;
    }

    log_loop_debug("Will try and schedule prepare callback for %d", sock->idx);
    lcb_luv_socket_ref(sock);
    uv_prepare_start(&sock->prep, prepare_cb);
    sock->prep_active = 1;
}