Ejemplo n.º 1
0
static lcb_error_t
dset_ctx_schedule(lcb_MULTICMD_CTX *mctx, const void *cookie)
{
    unsigned ii;
    char *kptr;
    lcb_DURSET *dset = CTX_FROM_MULTI(mctx);

    kptr = dset->kvbufs.base;
    for (ii = 0; ii < dset->nentries; ii++) {
        lcb_DURITEM *ent = dset->entries + ii;

        RESFLD(ent, key) = kptr;
        kptr += RESFLD(ent, nkey);
        if (ent->hashkey.contig.nbytes) {
            ent->hashkey.contig.bytes = kptr;
            kptr += ent->hashkey.contig.nbytes;
        }

        if (dset->ht) {
            int mt = genhash_update(dset->ht, RESFLD(ent, key),
                RESFLD(ent, nkey), ent, 0);
            if (mt != NEW) {
                lcb_durability_dset_destroy(dset);
                return LCB_DUPLICATE_COMMANDS;
            }
        }
    }

    dset_ref(dset);
    dset->cookie = cookie;
    dset->nremaining = dset->nentries;

    lcb_aspend_add(&dset->instance->pendops, LCB_PENDTYPE_DURABILITY, dset);
    return poll_once(dset, 1);
}
Ejemplo n.º 2
0
/**
 * Decrement the refcount for the 'dset'. When it hits zero then the dset is
 * freed.
 */
static void dset_unref(lcb_durability_set_t *dset)
{
    if (--dset->refcnt == 0) {
        lcb_durability_dset_destroy(dset);
    }
}
Ejemplo n.º 3
0
LIBCOUCHBASE_API
lcb_error_t lcb_durability_poll(lcb_t instance,
                                const void *cookie,
                                const lcb_durability_opts_t *options,
                                lcb_size_t ncmds,
                                const lcb_durability_cmd_t *const *cmds)
{
    hrtime_t now = gethrtime();
    lcb_durability_set_t *dset;
    lcb_size_t ii;
    lcb_io_opt_t io = instance->settings.io;

    if (!ncmds) {
        return LCB_EINVAL;
    }

    dset = calloc(1, sizeof(*dset));
    if (!dset) {
        return LCB_CLIENT_ENOMEM;
    }

    dset->opts = *options;
    dset->instance = instance;

    if (!DSET_OPTFLD(dset, timeout)) {
        DSET_OPTFLD(dset, timeout) = instance->settings.durability_timeout;
    }

    if (-1 == verify_critera(instance, dset)) {
        free(dset);
        return LCB_DURABILITY_ETOOMANY;
    }

    /* set our timeouts now */
    dset->us_timeout = (lcb_uint32_t)(now / 1000) + DSET_OPTFLD(dset, timeout);
    dset->timer = io->v.v0.create_timer(io);
    dset->cookie = cookie;
    dset->nentries = ncmds;
    dset->nremaining = ncmds;

    /** Get the timings */
    if (!DSET_OPTFLD(dset, interval)) {
        DSET_OPTFLD(dset, interval) = LCB_DEFAULT_DURABILITY_INTERVAL;
    }

    /* list of observe commands to schedule */
    if (dset->nentries == 1) {
        dset->entries = &dset->single.ent;
        dset->valid_entries = &dset->single.entp;

    } else {
        dset->ht = lcb_hashtable_nc_new(dset->nentries);
        dset->entries = calloc(dset->nentries, sizeof(*dset->entries));
        dset->valid_entries = malloc(dset->nentries * sizeof(*dset->valid_entries));
        if (dset->entries == NULL || dset->valid_entries == NULL) {
            lcb_durability_dset_destroy(dset);
            return LCB_CLIENT_ENOMEM;
        }
    }

    /* set up the observe commands */
    for (ii = 0; ii < dset->nentries; ii++) {
        lcb_durability_entry_t *ent = dset->entries + ii;
        ent_init(cmds[ii], ent);
        ent->parent = dset;

        if (dset->nentries > 1) {
            int mt = genhash_update(dset->ht,
                                    REQFLD(ent, key),
                                    REQFLD(ent, nkey),
                                    ent, 0);
            if (mt != NEW) {
                lcb_durability_dset_destroy(dset);
                return LCB_DUPLICATE_COMMANDS;
            }
        }
    }

    /**
     * Increase the refcount by one. This will be decremented
     * when the remaining_total count hits 0
     */

    dset_ref(dset);
    hashset_add(instance->durability_polls, dset);
    timer_schedule(dset, 0, STATE_OBSPOLL);
    return lcb_synchandler_return(instance, LCB_SUCCESS);
}
Ejemplo n.º 4
0
LIBCOUCHBASE_API
void lcb_destroy(lcb_t instance)
{
    lcb_size_t ii;
    lcb_settings *settings = &instance->settings;

    if (instance->cur_configinfo) {
        lcb_clconfig_decref(instance->cur_configinfo);
        instance->cur_configinfo = NULL;
    }
    instance->vbucket_config = NULL;

    lcb_bootstrap_destroy(instance);
    lcb_confmon_destroy(instance->confmon);
    hostlist_destroy(instance->usernodes);

    if (instance->timers != NULL) {
        for (ii = 0; ii < instance->timers->capacity; ++ii) {
            if (instance->timers->items[ii] > 1) {
                lcb_timer_destroy(instance,
                                  (lcb_timer_t)instance->timers->items[ii]);
            }
        }
        hashset_destroy(instance->timers);
    }

    if (instance->durability_polls) {
        struct lcb_durability_set_st **dset_list;
        lcb_size_t nitems = hashset_num_items(instance->durability_polls);
        dset_list = (struct lcb_durability_set_st **)
                    hashset_get_items(instance->durability_polls, NULL);
        if (dset_list) {
            for (ii = 0; ii < nitems; ii++) {
                lcb_durability_dset_destroy(dset_list[ii]);
            }
            free(dset_list);
        }
        hashset_destroy(instance->durability_polls);
    }

    for (ii = 0; ii < instance->nservers; ++ii) {
        lcb_server_destroy(instance->servers + ii);
    }

    if (instance->http_requests) {
        for (ii = 0; ii < instance->http_requests->capacity; ++ii) {
            if (instance->http_requests->items[ii] > 1) {
                lcb_http_request_t htreq =
                    (lcb_http_request_t)instance->http_requests->items[ii];

                /**
                 * We don't want to invoke callbacks *or* remove it from our
                 * hash table
                 */
                htreq->status |= LCB_HTREQ_S_CBINVOKED | LCB_HTREQ_S_HTREMOVED;

                /* we should figure out a better error code for this.. */
                lcb_http_request_finish(instance, htreq, LCB_ERROR);
            }
        }
    }

    hashset_destroy(instance->http_requests);

    free(instance->servers);

    connmgr_destroy(instance->memd_sockpool);

    if (settings->io && settings->io->v.v0.need_cleanup) {
        lcb_destroy_io_ops(settings->io);
    }

    ringbuffer_destruct(&instance->purged_buf);
    ringbuffer_destruct(&instance->purged_cookies);

    free(instance->histogram);
    free(instance->scratch);
    free(settings->username);
    free(settings->password);
    free(settings->bucket);
    free(settings->sasl_mech_force);
    if (instance->cmdht) {
        genhash_free(instance->cmdht);
        instance->cmdht = NULL;
    }

    memset(instance, 0xff, sizeof(*instance));
    free(instance);
}
Ejemplo n.º 5
0
static void
dset_ctx_fail(lcb_MULTICMD_CTX *mctx)
{
    lcb_DURSET *dset = CTX_FROM_MULTI(mctx);
    lcb_durability_dset_destroy(dset);
}