static void timer_callback(lcb_socket_t sock, short which, void *arg) { lcb_timer_t timer = arg; lcb_t instance = timer->instance; lcb_assert(TMR_IS_ARMED(timer)); lcb_assert(!TMR_IS_DESTROYED(timer)); timer->state |= LCB_TIMER_S_ENTERED; lcb_timer_disarm(timer); timer->callback(timer, instance, timer->cookie); if (TMR_IS_DESTROYED(timer) == 0 && TMR_IS_PERIODIC(timer) != 0) { lcb_timer_rearm(timer, timer->usec_); return; } if (! TMR_IS_STANDALONE(timer)) { lcb_aspend_del(&instance->pendops, LCB_PENDTYPE_TIMER, timer); lcb_maybe_breakout(instance); } if (TMR_IS_DESTROYED(timer)) { destroy_timer(timer); } else { timer->state &= ~LCB_TIMER_S_ENTERED; } (void)sock; (void)which; }
static void initial_bootstrap_error(lcb_t instance, lcb_error_t err, const char *errinfo) { struct lcb_BOOTSTRAP *bs = instance->bootstrap; instance->last_error = lcb_confmon_last_error(instance->confmon); if (instance->last_error == LCB_SUCCESS) { instance->last_error = err; } instance->callbacks.error(instance, instance->last_error, errinfo); lcb_log(LOGARGS(instance, ERR), "Failed to bootstrap client=%p. Code=0x%x, Message=%s", (void *)instance, err, errinfo); lcbio_timer_disarm(bs->tm); instance->callbacks.bootstrap(instance, instance->last_error); lcb_aspend_del(&instance->pendops, LCB_PENDTYPE_COUNTER, NULL); lcb_maybe_breakout(instance); }
LIBCOUCHBASE_API lcb_error_t lcb_timer_destroy(lcb_t instance, lcb_timer_t timer) { int standalone = timer->options & LCB_TIMER_STANDALONE; if (!standalone) { lcb_aspend_del(&instance->pendops, LCB_PENDTYPE_TIMER, timer); } lcb_timer_disarm(timer); if (timer->state & LCB_TIMER_S_ENTERED) { timer->state |= LCB_TIMER_S_DESTROYED; lcb_assert(TMR_IS_DESTROYED(timer)); } else { destroy_timer(timer); } return LCB_SUCCESS; }
/** * Actually free the resources allocated by the dset (and all its entries). * Called by some other functions in libcouchbase */ void lcbdur_destroy(lcb_DURSET *dset) { lcb_t instance = dset->instance; if (DSET_PROCS(dset)->clean) { DSET_PROCS(dset)->clean(dset); } if (dset->timer) { lcbio_TABLE *io = instance->iotable; io->timer.cancel(io->p, dset->timer); io->timer.destroy(io->p, dset->timer); dset->timer = NULL; } lcb_aspend_del(&dset->instance->pendops, LCB_PENDTYPE_DURABILITY, dset); LCB_SSOBUF_CLEAN(&dset->entries_); lcb_string_release(&dset->kvbufs); free(dset); lcb_maybe_breakout(instance); }
/** * Actually free the resources allocated by the dset (and all its entries). * Called by some other functions in libcouchbase */ void lcb_durability_dset_destroy(lcb_DURSET *dset) { lcb_t instance = dset->instance; if (dset->timer) { lcbio_TABLE *io = instance->iotable; io->timer.cancel(io->p, dset->timer); io->timer.destroy(io->p, dset->timer); dset->timer = NULL; } lcb_aspend_del(&dset->instance->pendops, LCB_PENDTYPE_DURABILITY, dset); if (dset->nentries > 1) { if (dset->ht) { genhash_free(dset->ht); } free(dset->entries); } lcb_string_release(&dset->kvbufs); free(dset); lcb_maybe_breakout(instance); }
/** * This function is where the configuration actually takes place. We ensure * in other functions that this is only ever called directly from an event * loop stack frame (or one of the small mini functions here) so that we * don't accidentally end up destroying resources underneath us. */ static void config_callback(clconfig_listener *listener, clconfig_event_t event, clconfig_info *info) { struct lcb_BOOTSTRAP *bs = (struct lcb_BOOTSTRAP *)listener; lcb_t instance = bs->parent; if (event != CLCONFIG_EVENT_GOT_NEW_CONFIG) { if (event == CLCONFIG_EVENT_PROVIDERS_CYCLED) { if (!LCBT_VBCONFIG(instance)) { initial_bootstrap_error( instance, LCB_ERROR, "No more bootstrap providers remain"); } } return; } instance->last_error = LCB_SUCCESS; /** Ensure we're not called directly twice again */ listener->callback = async_step_callback; lcbio_timer_disarm(bs->tm); lcb_log(LOGARGS(instance, DEBUG), "Instance configured!"); if (info->origin != LCB_CLCONFIG_FILE) { /* Set the timestamp for the current config to control throttling, * but only if it's not an initial file-based config. See CCBC-482 */ bs->last_refresh = gethrtime(); bs->errcounter = 0; } if (info->origin == LCB_CLCONFIG_CCCP) { /* Disable HTTP provider if we've received something via CCCP */ if (instance->cur_configinfo == NULL || instance->cur_configinfo->origin != LCB_CLCONFIG_HTTP) { /* Never disable HTTP if it's still being used */ lcb_confmon_set_provider_active( instance->confmon, LCB_CLCONFIG_HTTP, 0); } } if (instance->type != LCB_TYPE_CLUSTER) { lcb_update_vbconfig(instance, info); } if (!bs->bootstrapped) { bs->bootstrapped = 1; lcb_aspend_del(&instance->pendops, LCB_PENDTYPE_COUNTER, NULL); if (instance->type == LCB_TYPE_BUCKET && LCBVB_DISTTYPE(LCBT_VBCONFIG(instance)) == LCBVB_DIST_KETAMA && instance->cur_configinfo->origin != LCB_CLCONFIG_MCRAW) { lcb_log(LOGARGS(instance, INFO), "Reverting to HTTP Config for memcached buckets"); instance->settings->bc_http_stream_time = -1; lcb_confmon_set_provider_active( instance->confmon, LCB_CLCONFIG_HTTP, 1); lcb_confmon_set_provider_active( instance->confmon, LCB_CLCONFIG_CCCP, 0); } instance->callbacks.bootstrap(instance, LCB_SUCCESS); } lcb_maybe_breakout(instance); }