/** * All-purpose callback dispatcher. */ static void timer_callback(lcb_socket_t sock, short which, void *arg) { lcb_DURSET *dset = arg; hrtime_t ns_now = gethrtime(); lcb_U32 us_now = (lcb_U32)(ns_now / 1000); if (us_now >= (dset->us_timeout - 50)) { dset->next_state = STATE_TIMEOUT; } switch (dset->next_state) { case STATE_OBSPOLL: poll_once(dset, 0); break; case STATE_TIMEOUT: { if (us_now >= (dset->us_timeout - 50)) { purge_entries(dset, LCB_ETIMEDOUT); } else { timer_schedule(dset, dset->us_timeout - us_now, STATE_TIMEOUT); } break; } case STATE_IGNORE: break; default: lcb_assert("unexpected state" && 0); break; } (void)sock; (void)which; }
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); }
/** * All-purpose callback dispatcher. */ static void timer_callback(lcb_socket_t sock, short which, void *arg) { lcb_DURSET *dset = arg; hrtime_t now = gethrtime(); if (dset->ns_timeout && now > dset->ns_timeout) { dset->next_state = LCBDUR_STATE_TIMEOUT; } switch (dset->next_state) { case LCBDUR_STATE_OBSPOLL: case LCBDUR_STATE_INIT: poll_once(dset); break; case LCBDUR_STATE_TIMEOUT: { lcb_size_t ii; lcb_error_t err = dset->lasterr ? dset->lasterr : LCB_ETIMEDOUT; dset->ns_timeout = 0; dset->next_state = LCBDUR_STATE_IGNORE; lcb_log(LOGARGS(dset, WARN), "Polling durability timed out!"); lcbdur_ref(dset); for (ii = 0; ii < DSET_COUNT(dset); ii++) { lcb_DURITEM *ent = DSET_ENTRIES(dset) + ii; if (ent->done) { continue; } if (RESFLD(ent, rc) == LCB_SUCCESS) { RESFLD(ent, rc) = err; } lcbdur_ent_finish(ent); } lcbdur_unref(dset); break; } case LCBDUR_STATE_IGNORE: break; default: lcb_assert("unexpected state" && 0); break; } (void)sock; (void)which; }