static enum req_fsm_nxt cnt_purge(struct worker *wrk, struct req *req) { struct objcore *oc, *boc; 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, 1, 1); assert (lr == HSH_MISS); AZ(oc); CHECK_OBJ_NOTNULL(boc, OBJCORE_MAGIC); VRY_Finish(req, DISCARD); HSH_Purge(wrk, boc->objhead, 0, 0); AZ(HSH_DerefObjCore(&wrk->stats, &boc)); VCL_purge_method(req->vcl, wrk, req, NULL, req->http->ws); req->req_step = R_STP_ERROR; return (REQ_FSM_MORE); }
static enum req_fsm_nxt cnt_purge(struct worker *wrk, struct req *req) { struct objcore *oc, *boc; enum lookup_e lr; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); AZ(req->objcore); AN(req->vcl); VRY_Prep(req); AZ(req->objcore); lr = HSH_Lookup(req, &oc, &boc, 1, 1); assert (lr == HSH_MISS); AZ(oc); CHECK_OBJ_NOTNULL(boc, OBJCORE_MAGIC); VRY_Finish(req, DISCARD); HSH_Purge(wrk, boc->objhead, 0, 0, 0); AZ(HSH_DerefObjCore(wrk, &boc)); VCL_purge_method(req->vcl, wrk, req, NULL, NULL); switch (wrk->handling) { case VCL_RET_RESTART: req->req_step = R_STP_RESTART; break; case VCL_RET_SYNTH: req->req_step = R_STP_SYNTH; break; default: WRONG("Illegal return from vcl_purge{}"); } return (REQ_FSM_MORE); }
static enum req_fsm_nxt cnt_lookup(struct worker *wrk, struct req *req) { struct objcore *oc, *busy; enum lookup_e lr; int had_objhead = 0; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); AZ(req->objcore); AN(req->vcl); VRY_Prep(req); AZ(req->objcore); if (req->hash_objhead) had_objhead = 1; lr = HSH_Lookup(req, &oc, &busy, 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 (had_objhead) VSLb_ts_req(req, "Waitinglist", W_TIM_real(wrk)); if (busy == NULL) { VRY_Finish(req, DISCARD); } else { AN(busy->flags & OC_F_BUSY); VRY_Finish(req, KEEP); } AZ(req->objcore); if (lr == HSH_MISS) { /* Found nothing */ AZ(oc); AN(busy); AN(busy->flags & OC_F_BUSY); req->objcore = busy; req->req_step = R_STP_MISS; return (REQ_FSM_MORE); } CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); AZ(oc->flags & OC_F_BUSY); req->objcore = oc; if ((oc->flags & OC_F_PASS) && busy != NULL) { /* Treat a graced Hit-For-Pass as a miss */ req->objcore = busy; req->stale_oc = oc; req->req_step = R_STP_MISS; return (REQ_FSM_MORE); } else if (oc->flags & OC_F_PASS) { /* Found a hit-for-pass */ VSLb(req->vsl, SLT_Debug, "XXXX HIT-FOR-PASS"); VSLb(req->vsl, SLT_HitPass, "%u", ObjGetXID(wrk, req->objcore)); (void)HSH_DerefObjCore(wrk, &req->objcore); wrk->stats->cache_hitpass++; req->req_step = R_STP_PASS; return (REQ_FSM_MORE); } VSLb(req->vsl, SLT_Hit, "%u", ObjGetXID(wrk, req->objcore)); VCL_hit_method(req->vcl, wrk, req, NULL, NULL); switch (wrk->handling) { case VCL_RET_DELIVER: if (busy != NULL) { AZ(oc->flags & OC_F_PASS); CHECK_OBJ_NOTNULL(busy->boc, BOC_MAGIC); VBF_Fetch(wrk, req, busy, oc, VBF_BACKGROUND); } else { (void)VRB_Ignore(req);// XXX: handle err } wrk->stats->cache_hit++; req->is_hit = 1; req->req_step = R_STP_DELIVER; return (REQ_FSM_MORE); case VCL_RET_FETCH: VSLb(req->vsl, SLT_VCL_Error, "change return(fetch) to return(miss) in vcl_hit{}"); /* FALL-THROUGH */ case VCL_RET_MISS: if (busy != NULL) { req->objcore = busy; req->stale_oc = oc; req->req_step = R_STP_MISS; } else { (void)HSH_DerefObjCore(wrk, &req->objcore); /* * We don't have a busy object, so treat this * like a pass */ VSLb(req->vsl, SLT_VCL_Error, "vcl_hit{} returns miss 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_SYNTH: req->req_step = R_STP_SYNTH; break; case VCL_RET_PASS: wrk->stats->cache_hit++; req->is_hit = 1; req->req_step = R_STP_PASS; break; default: WRONG("Illegal return from vcl_hit{}"); } /* Drop our object, we won't need it */ (void)HSH_DerefObjCore(wrk, &req->objcore); if (busy != NULL) { (void)HSH_DerefObjCore(wrk, &busy); VRY_Clear(req); } 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; int had_objhead = 0; 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); if (req->hash_objhead) had_objhead = 1; 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 (had_objhead) VSLb_ts_req(req, "Waitinglist", W_TIM_real(wrk)); 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); o = ObjGetObj(oc, &wrk->stats); CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC); req->obj = o; if (oc->flags & OC_F_PASS) { /* Found a hit-for-pass */ VSLb(req->vsl, SLT_Debug, "XXXX HIT-FOR-PASS"); VSLb(req->vsl, SLT_HitPass, "%u", req->obj->vxid); AZ(boc); (void)HSH_DerefObj(&wrk->stats, &req->obj); 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); 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) { AZ(oc->flags & (OC_F_FAILED|OC_F_PASS)); AZ(oc->exp_flags & OC_EF_DYING); AZ(boc->busyobj); 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: req->objcore = boc; if (req->objcore != NULL) req->req_step = R_STP_MISS; else { (void)HSH_DerefObj(&wrk->stats, &req->obj); /* * We don't have a busy object, so treat this * like 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_SYNTH: req->req_step = R_STP_SYNTH; 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); }