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; }
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; }
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; }
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; }
/** * 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; }
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; }