static lcb_RESPCALLBACK find_callback(lcb_t instance, lcb_CALLBACKTYPE type) { lcb_RESPCALLBACK cb = instance->callbacks.v3callbacks[type]; if (!cb) { cb = lcb_find_callback(instance, type); } return cb; }
static void rget_callback(mc_PIPELINE *pl, mc_PACKET *pkt, lcb_error_t err, const void *arg) { rget_cookie *rck = (rget_cookie *)pkt->u_rdata.exdata; lcb_RESPGET *resp = (void *)arg; lcb_RESPCALLBACK callback; lcb_t instance = rck->instance; callback = lcb_find_callback(instance, LCB_CALLBACK_GETREPLICA); /** Figure out what the strategy is.. */ if (rck->strategy == LCB_REPLICA_SELECT || rck->strategy == LCB_REPLICA_ALL) { /** Simplest */ if (rck->strategy == LCB_REPLICA_SELECT || rck->remaining == 1) { resp->rflags |= LCB_RESP_F_FINAL; } callback(instance, LCB_CALLBACK_GETREPLICA, (const lcb_RESPBASE *)resp); } else { mc_CMDQUEUE *cq = &instance->cmdq; mc_PIPELINE *nextpl = NULL; /** FIRST */ do { int nextix; rck->r_cur++; nextix = lcbvb_vbreplica(cq->config, rck->vbucket, rck->r_cur); if (nextix > -1 && nextix < (int)cq->npipelines) { /* have a valid next index? */ nextpl = cq->pipelines[nextix]; break; } } while (rck->r_cur < rck->r_max); if (err == LCB_SUCCESS || rck->r_cur == rck->r_max || nextpl == NULL) { resp->rflags |= LCB_RESP_F_FINAL; callback(instance, LCB_CALLBACK_GETREPLICA, (lcb_RESPBASE *)resp); /* refcount=1 . Free this now */ rck->remaining = 1; } else if (err != LCB_SUCCESS) { mc_PACKET *newpkt = mcreq_renew_packet(pkt); newpkt->flags &= ~MCREQ_STATE_FLAGS; mcreq_sched_add(nextpl, newpkt); /* Use this, rather than lcb_sched_leave(), because this is being * invoked internally by the library. */ mcreq_sched_leave(cq, 1); /* wait */ rck->remaining = 2; } } if (!--rck->remaining) { free(rck); } (void)pl; }
void lcbdur_ent_finish(lcb_DURITEM *ent) { lcb_RESPCALLBACK callback; lcb_t instance; if (ent->done) { return; } ent->done = 1; ent->parent->nremaining--; /** Invoke the callback now :) */ ent->result.cookie = (void *)ent->parent->cookie; instance = ent->parent->instance; if (ent->parent->is_durstore) { lcb_RESPSTOREDUR resp = { 0 }; resp.key = ent->result.key; resp.nkey = ent->result.nkey; resp.rc = ent->result.rc; resp.cas = ent->reqcas; resp.cookie = ent->result.cookie; resp.store_ok = 1; resp.dur_resp = &ent->result; callback = lcb_find_callback(instance, LCB_CALLBACK_STOREDUR); callback(instance, LCB_CALLBACK_STOREDUR, (lcb_RESPBASE*)&resp); } else { callback = lcb_find_callback(instance, LCB_CALLBACK_ENDURE); callback(instance, LCB_CALLBACK_ENDURE, (lcb_RESPBASE*)&ent->result); } if (ent->parent->nremaining == 0) { lcbdur_unref(ent->parent); } }
/** * Set the logical state of the entry to done, and invoke the callback. * It is safe to call this multiple times */ static void ent_set_resdone(lcb_DURITEM *ent) { lcb_RESPCALLBACK callback; if (ent->done) { return; } ent->done = 1; ent->parent->nremaining--; /** Invoke the callback now :) */ ent->result.cookie = (void *)ent->parent->cookie; callback = lcb_find_callback(ent->parent->instance, LCB_CALLBACK_ENDURE); callback(ent->parent->instance, LCB_CALLBACK_ENDURE, (lcb_RESPBASE*)&ent->result); if (ent->parent->nremaining == 0) { dset_unref(ent->parent); } }
static void flush_cb(lcb_t instance, int cbtype, const lcb_RESPBASE *rb) { const lcb_RESPHTTP *resp = (const lcb_RESPHTTP *)rb; lcb_RESPCBFLUSH fresp = { 0 }; lcb_RESPCALLBACK callback = lcb_find_callback(instance, LCB_CALLBACK_CBFLUSH); fresp = *(lcb_RESPBASE *)rb; fresp.rflags |= LCB_RESP_F_FINAL; if (resp->rc == LCB_SUCCESS) { if (resp->htstatus < 200 || resp->htstatus > 299) { fresp.rc = LCB_HTTP_ERROR; } } if (callback) { callback(instance, LCB_CALLBACK_CBFLUSH, (lcb_RESPBASE*)&fresp); } (void)cbtype; }
static void handle_observe_callback(mc_PIPELINE *pl, mc_PACKET *pkt, lcb_error_t err, const void *arg) { OBSERVECTX *oc = (void *)pkt->u_rdata.exdata; lcb_RESPOBSERVE *resp = (void *)arg; lcb_t instance = oc->instance; (void)pl; if (resp == NULL) { int nfailed = 0; /** We need to fail the request manually.. */ const char *ptr = SPAN_BUFFER(&pkt->u_value.single); const char *end = ptr + pkt->u_value.single.size; while (ptr < end) { lcb_uint16_t nkey; lcb_RESPOBSERVE cur = { 0 }; cur.rflags = LCB_RESP_F_CLIENTGEN; ptr += 2; memcpy(&nkey, ptr, sizeof(nkey)); nkey = ntohs(nkey); ptr += 2; memset(&cur, 0, sizeof(cur)); cur.key = ptr; cur.nkey = nkey; cur.cookie = (void *)oc->base.cookie; cur.rc = err; handle_observe_callback(NULL, pkt, err, &cur); ptr += nkey; nfailed++; } lcb_assert(nfailed); return; } resp->cookie = (void *)oc->base.cookie; resp->rc = err; if (oc->oflags & F_DURABILITY) { lcb_durability_dset_update( instance, (lcb_DURSET *)MCREQ_PKT_COOKIE(pkt), err, resp); } else if ((oc->oflags & F_SCHEDFAILED) == 0) { lcb_RESPCALLBACK callback = lcb_find_callback(instance, LCB_CALLBACK_OBSERVE); callback(instance, LCB_CALLBACK_OBSERVE, (lcb_RESPBASE *)resp); } if (oc->oflags & F_DESTROY) { return; } if (--oc->remaining) { return; } else { lcb_RESPOBSERVE resp2 = { 0 }; resp2.rc = err; resp2.rflags = LCB_RESP_F_CLIENTGEN|LCB_RESP_F_FINAL; oc->oflags |= F_DESTROY; handle_observe_callback(NULL, pkt, err, &resp2); free(oc); } }
/** Observe stuff */ static void handle_dur_storecb(mc_PIPELINE *pl, mc_PACKET *pkt, lcb_error_t err, const void *arg) { lcb_RESPCALLBACK cb; lcb_RESPSTOREDUR resp = { 0 }; lcb_CMDENDURE dcmd = { 0 }; DURSTORECTX *dctx = (DURSTORECTX *)pkt->u_rdata.exdata; lcb_MULTICMD_CTX *mctx; lcb_durability_opts_t opts = { 0 }; const lcb_RESPSTORE *sresp = (const lcb_RESPSTORE *)arg; if (err != LCB_SUCCESS) { goto GT_BAIL; } if (sresp->rc != LCB_SUCCESS) { err = sresp->rc; goto GT_BAIL; } resp.store_ok = 1; LCB_CMD_SET_KEY(&dcmd, sresp->key, sresp->nkey); dcmd.cas = sresp->cas; if (LCB_SYNCTOKEN_ISVALID(&sresp->synctoken)) { dcmd.synctoken = &sresp->synctoken; } /* Set the options.. */ opts.v.v0.persist_to = dctx->persist_to; opts.v.v0.replicate_to = dctx->replicate_to; mctx = lcb_endure3_ctxnew(dctx->instance, &opts, &err); if (mctx == NULL) { goto GT_BAIL; } lcbdurctx_set_durstore(mctx, 1); err = mctx->addcmd(mctx, (lcb_CMDBASE*)&dcmd); if (err != LCB_SUCCESS) { mctx->fail(mctx); goto GT_BAIL; } lcb_sched_enter(dctx->instance); err = mctx->done(mctx, sresp->cookie); lcb_sched_leave(dctx->instance); if (err == LCB_SUCCESS) { /* Everything OK? */ free(dctx); return; } GT_BAIL: { lcb_RESPENDURE dresp = { 0 }; resp.key = sresp->key; resp.nkey = sresp->nkey; resp.cookie = sresp->cookie; resp.rc = err; resp.dur_resp = &dresp; cb = lcb_find_callback(dctx->instance, LCB_CALLBACK_STOREDUR); cb(dctx->instance, LCB_CALLBACK_STOREDUR, (const lcb_RESPBASE*)&resp); free(dctx); } (void)pl; }