static enum req_fsm_nxt cnt_fetch(struct worker *wrk, struct req *req) { CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC); AZ(req->obj); req->acct_req.fetch++; (void)HTTP1_DiscardReqBody(req); if (req->objcore->flags & OC_F_FAILED) { req->err_code = 503; req->req_step = R_STP_ERROR; (void)HSH_DerefObjCore(&wrk->stats, &req->objcore); req->objcore = NULL; return (REQ_FSM_MORE); } req->obj = oc_getobj(&wrk->stats, req->objcore); req->objcore = NULL; req->err_code = req->obj->response; req->req_step = R_STP_DELIVER; return (REQ_FSM_MORE); }
static int cnt_lookup(struct worker *wrk, struct req *req) { struct objcore *oc; struct object *o; struct objhead *oh; struct busyobj *bo; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); AZ(req->objcore); CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC); AZ(req->busyobj); VRY_Prep(req); AZ(req->objcore); oc = HSH_Lookup(req); if (oc == NULL) { /* * We lost the session to a busy object, disembark the * worker thread. We return to STP_LOOKUP when the busy * object has been unbusied, and still have the objhead * around to restart the lookup with. */ return (2); } AZ(req->objcore); CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); oh = oc->objhead; CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); /* If we inserted a new object it's a miss */ if (oc->flags & OC_F_BUSY) { AZ(req->busyobj); bo = VBO_GetBusyObj(wrk, req); req->busyobj = bo; /* One ref for req, one for FetchBody */ bo->refcount = 2; VRY_Finish(req, bo); oc->busyobj = bo; wrk->stats.cache_miss++; req->objcore = oc; req->req_step = R_STP_MISS; return (0); } /* We are not prepared to do streaming yet */ XXXAZ(req->busyobj); o = oc_getobj(&wrk->stats, oc); CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); req->obj = o; VRY_Finish(req, NULL); if (oc->flags & OC_F_PASS) { wrk->stats.cache_hitpass++; VSLb(req->vsl, SLT_HitPass, "%u", req->obj->vxid); (void)HSH_Deref(&wrk->stats, NULL, &req->obj); AZ(req->objcore); req->req_step = R_STP_PASS; return (0); } wrk->stats.cache_hit++; VSLb(req->vsl, SLT_Hit, "%u", req->obj->vxid); req->req_step = R_STP_HIT; return (0); }
static enum req_fsm_nxt cnt_lookup(struct worker *wrk, struct req *req) { struct objcore *oc, *boc; struct object *o; struct objhead *oh; enum lookup_e lr; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); AZ(req->objcore); CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC); VRY_Prep(req); AZ(req->objcore); lr = HSH_Lookup(req, &oc, &boc, req->esi_level == 0 ? 1 : 0, req->hash_always_miss ? 1 : 0 ); if (lr == HSH_BUSY) { /* * We lost the session to a busy object, disembark the * worker thread. We return to STP_LOOKUP when the busy * object has been unbusied, and still have the objhead * around to restart the lookup with. */ return (REQ_FSM_DISEMBARK); } if (boc == NULL) { VRY_Finish(req, DISCARD); } else { AN(boc->flags & OC_F_BUSY); VRY_Finish(req, KEEP); } AZ(req->objcore); if (lr == HSH_MISS) { /* Found nothing */ VSLb(req->vsl, SLT_Debug, "XXXX MISS"); AZ(oc); AN(boc); AN(boc->flags & OC_F_BUSY); req->objcore = boc; req->req_step = R_STP_MISS; return (REQ_FSM_MORE); } CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); AZ (oc->flags & OC_F_BUSY); AZ(req->objcore); if (oc->flags & OC_F_PASS) { /* Found a hit-for-pass */ VSLb(req->vsl, SLT_Debug, "XXXX HIT-FOR-PASS"); AZ(boc); (void)HSH_DerefObjCore(&wrk->stats, &oc); req->objcore = NULL; wrk->stats.cache_hitpass++; req->req_step = R_STP_PASS; return (REQ_FSM_MORE); } oh = oc->objhead; CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); o = oc_getobj(&wrk->stats, oc); CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); req->obj = o; VSLb(req->vsl, SLT_Hit, "%u", req->obj->vxid); VCL_hit_method(req->vcl, wrk, req, NULL, req->http->ws); switch (wrk->handling) { case VCL_RET_DELIVER: if (boc != NULL) { VBF_Fetch(wrk, req, boc, o, VBF_BACKGROUND); } else { (void)HTTP1_DiscardReqBody(req);// XXX: handle err } wrk->stats.cache_hit++; req->req_step = R_STP_DELIVER; return (REQ_FSM_MORE); case VCL_RET_FETCH: (void)HSH_DerefObj(&wrk->stats, &req->obj); req->objcore = boc; if (req->objcore != NULL) req->req_step = R_STP_MISS; else { /* * We don't have a busy object, so treat this * lige a pass */ VSLb(req->vsl, SLT_VCL_Error, "vcl_hit{} returns fetch without busy object." " Doing pass."); req->req_step = R_STP_PASS; } return (REQ_FSM_MORE); case VCL_RET_RESTART: req->req_step = R_STP_RESTART; break; case VCL_RET_ERROR: req->req_step = R_STP_ERROR; break; case VCL_RET_PASS: wrk->stats.cache_hit++; req->req_step = R_STP_PASS; break; default: INCOMPL(); } /* Drop our object, we won't need it */ (void)HSH_DerefObj(&wrk->stats, &req->obj); req->objcore = NULL; if (boc != NULL) { (void)HSH_DerefObjCore(&wrk->stats, &boc); free(req->vary_b); req->vary_b = NULL; } return (REQ_FSM_MORE); }
static int cnt_lookup(struct sess *sp) { struct objcore *oc; struct object *o; struct objhead *oh; struct worker *wrk; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); wrk = sp->wrk; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(sp->vcl, VCL_CONF_MAGIC); AZ(wrk->busyobj); if (sp->hash_objhead == NULL) { /* Not a waiting list return */ AZ(sp->vary_b); AZ(sp->vary_l); AZ(sp->vary_e); (void)WS_Reserve(sp->ws, 0); } else { AN(sp->ws->r); } sp->vary_b = (void*)sp->ws->f; sp->vary_e = (void*)sp->ws->r; sp->vary_b[2] = '\0'; oc = HSH_Lookup(sp, &oh); if (oc == NULL) { /* * We lost the session to a busy object, disembark the * worker thread. The hash code to restart the session, * still in STP_LOOKUP, later when the busy object isn't. * NB: Do not access sp any more ! */ return (1); } CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); /* If we inserted a new object it's a miss */ if (oc->flags & OC_F_BUSY) { wrk->stats.cache_miss++; if (sp->vary_l != NULL) { assert(oc->busyobj->vary == sp->vary_b); VRY_Validate(oc->busyobj->vary); WS_ReleaseP(sp->ws, (void*)sp->vary_l); } else { AZ(oc->busyobj->vary); WS_Release(sp->ws, 0); } sp->vary_b = NULL; sp->vary_l = NULL; sp->vary_e = NULL; wrk->objcore = oc; CHECK_OBJ_NOTNULL(wrk->busyobj, BUSYOBJ_MAGIC); sp->step = STP_MISS; return (0); } o = oc_getobj(wrk, oc); CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); wrk->obj = o; WS_Release(sp->ws, 0); sp->vary_b = NULL; sp->vary_l = NULL; sp->vary_e = NULL; if (oc->flags & OC_F_PASS) { wrk->stats.cache_hitpass++; WSP(sp, SLT_HitPass, "%u", wrk->obj->xid); (void)HSH_Deref(wrk, NULL, &wrk->obj); wrk->objcore = NULL; sp->step = STP_PASS; return (0); } wrk->stats.cache_hit++; WSP(sp, SLT_Hit, "%u", wrk->obj->xid); sp->step = STP_HIT; return (0); }