static void vwk_sess_ev(struct vwk *vwk, const struct kevent *kp, double now) { struct sess *sp; AN(kp->udata); assert(kp->udata != vwk->pipes); CAST_OBJ_NOTNULL(sp, kp->udata, SESS_MAGIC); DSL(DBG_WAITER, sp->vxid, "KQ: sp %p kev data %lu flags 0x%x%s", sp, (unsigned long)kp->data, kp->flags, (kp->flags & EV_EOF) ? " EOF" : ""); if (kp->data > 0) { VTAILQ_REMOVE(&vwk->sesshead, sp, list); SES_Handle(sp, now); return; } else if (kp->flags & EV_EOF) { VTAILQ_REMOVE(&vwk->sesshead, sp, list); SES_Delete(sp, SC_REM_CLOSE, now); return; } else { VSL(SLT_Debug, sp->vxid, "KQ: sp %p kev data %lu flags 0x%x%s", sp, (unsigned long)kp->data, kp->flags, (kp->flags & EV_EOF) ? " EOF" : ""); } }
void * WS_Copy(struct ws *ws, const void *str, int len) { char *r; unsigned bytes; WS_Assert(ws); assert(ws->r == NULL); if (len == -1) len = strlen(str) + 1; assert(len >= 0); bytes = PRNDUP((unsigned)len); if (ws->f + bytes > ws->e) { WS_MarkOverflow(ws); WS_Assert(ws); return(NULL); } r = ws->f; ws->f += bytes; memcpy(r, str, len); DSL(DBG_WORKSPACE, 0, "WS_Copy(%p, %d) = %p", ws, len, r); WS_Assert(ws); return (r); }
char * WS_Snapshot(struct ws *ws) { WS_Assert(ws); assert(ws->r == NULL); DSL(DBG_WORKSPACE, 0, "WS_Snapshot(%p) = %p", ws, ws->f); return (ws->f); }
char * WS_Snapshot(struct ws *ws) { WS_Assert(ws); assert(ws->r == NULL); DSL(0x02, SLT_Debug, 0, "WS_Snapshot(%p) = %p", ws, ws->f); return (ws->f); }
static void vwk_kq_sess(struct vwk *vwk, struct sess *sp, short arm) { CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); assert(sp->fd >= 0); DSL(DBG_WAITER, sp->vxid, "KQ: EV_SET sp %p arm %x", sp, arm); EV_SET(&vwk->ki[vwk->nki], sp->fd, EVFILT_READ, arm, 0, 0, sp); if (++vwk->nki == NKEV) vwk_kq_flush(vwk); }
static void vca_kq_sess(struct sess *sp, short arm) { CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); assert(sp->sp_fd >= 0); DSL(0x04, SLT_Debug, sp->sp_fd, "KQ: EV_SET sp %p arm %x", sp, arm); EV_SET(&ki[nki], sp->sp_fd, EVFILT_READ, arm, 0, 0, sp); if (++nki == NKEV) vca_kq_flush(); }
void WS_ReleaseP(struct ws *ws, char *ptr) { WS_Assert(ws); DSL(DBG_WORKSPACE, 0, "WS_ReleaseP(%p, %p)", ws, ptr); assert(ws->r != NULL); assert(ptr >= ws->f); assert(ptr <= ws->r); ws->f += PRNDUP(ptr - ws->f); ws->r = NULL; WS_Assert(ws); }
void WS_ReleaseP(struct ws *ws, char *ptr) { WS_Assert(ws); DSL(0x02, SLT_Debug, 0, "WS_ReleaseP(%p, %p)", ws, ptr); assert(ws->r != NULL); assert(ptr >= ws->f); assert(ptr <= ws->r); ws->f += PRNDUP(ptr - ws->f); ws->r = NULL; WS_Assert(ws); }
static void vca_kev(const struct kevent *kp) { int i, j; struct sess *sp; struct sess *ss[NKEV]; AN(kp->udata); if (kp->udata == vca_pipes) { j = 0; i = read(vca_pipes[0], ss, sizeof ss); if (i == -1 && errno == EAGAIN) return; while (i >= sizeof ss[0]) { CHECK_OBJ_NOTNULL(ss[j], SESS_MAGIC); assert(ss[j]->sp_fd >= 0); AZ(ss[j]->obj); VTAILQ_INSERT_TAIL(&sesshead, ss[j], list); vca_kq_sess(ss[j], EV_ADD | EV_ONESHOT); j++; i -= sizeof ss[0]; } assert(i == 0); return; } CAST_OBJ_NOTNULL(sp, kp->udata, SESS_MAGIC); DSL(0x04, SLT_Debug, sp->id, "KQ: sp %p kev data %lu flags 0x%x%s", sp, (unsigned long)kp->data, kp->flags, (kp->flags & EV_EOF) ? " EOF" : ""); assert(sp->id == kp->ident); assert(sp->sp_fd == sp->id); if (kp->data > 0) { i = HTC_Rx(sp->htc); if (i == 0) { vca_kq_sess(sp, EV_ADD | EV_ONESHOT); return; /* more needed */ } VTAILQ_REMOVE(&sesshead, sp, list); vca_handover(sp, i); return; } else if (kp->flags & EV_EOF) { VTAILQ_REMOVE(&sesshead, sp, list); vca_close_session(sp, "EOF"); SES_Delete(sp); return; } else { VSL(SLT_Debug, sp->id, "KQ: sp %p kev data %lu flags 0x%x%s", sp, (unsigned long)kp->data, kp->flags, (kp->flags & EV_EOF) ? " EOF" : ""); } }
void WS_Release(struct ws *ws, unsigned bytes) { WS_Assert(ws); bytes = PRNDUP(bytes); assert(bytes <= ws->e - ws->f); DSL(DBG_WORKSPACE, 0, "WS_Release(%p, %u)", ws, bytes); assert(ws->r != NULL); assert(ws->f + bytes <= ws->r); ws->f += bytes; ws->r = NULL; WS_Assert(ws); }
char * WS_Dup(struct ws *ws, const char *s) { unsigned l; char *p; WS_Assert(ws); l = strlen(s) + 1; p = WS_Alloc(ws, l); if (p != NULL) memcpy(p, s, l); DSL(0x02, SLT_Debug, 0, "WS_Dup(%p, \"%s\") = %p", ws, s, p); WS_Assert(ws); return (p); }
char * WS_nDup(struct ws *ws, const char *s, size_t l) { char *p; WS_Assert(ws); p = WS_Alloc(ws, l + 1); if (p != NULL) { memcpy(p, s, l); p[l] = '\0'; } DSL(0x02, SLT_Debug, 0, "WS_nDup(%p, \"%s\", %zd) = %p", ws, s, p, l); WS_Assert(ws); return (p); }
void WS_Reset(struct ws *ws, char *p) { WS_Assert(ws); DSL(0x02, SLT_Debug, 0, "WS_Reset(%p, %p)", ws, p); assert(ws->r == NULL); if (p == NULL) ws->f = ws->s; else { assert(p >= ws->s); assert(p < ws->e); ws->f = p; } WS_Assert(ws); }
void WS_Reset(struct ws *ws, char *p) { WS_Assert(ws); DSL(DBG_WORKSPACE, 0, "WS_Reset(%p, %p)", ws, p); assert(ws->r == NULL); if (p == NULL) ws->f = ws->s; else { assert(p >= ws->s); assert(p < ws->e); ws->f = p; } WS_Assert(ws); }
void WS_Init(struct ws *ws, const char *id, void *space, unsigned len) { DSL(0x02, SLT_Debug, 0, "WS_Init(%p, \"%s\", %p, %u)", ws, id, space, len); assert(space != NULL); memset(ws, 0, sizeof *ws); ws->magic = WS_MAGIC; ws->s = space; assert(PAOK(space)); ws->e = ws->s + len; assert(PAOK(len)); ws->f = ws->s; ws->id = id; WS_Assert(ws); }
void WS_Init(struct ws *ws, const char *id, void *space, unsigned len) { DSL(DBG_WORKSPACE, 0, "WS_Init(%p, \"%s\", %p, %u)", ws, id, space, len); assert(space != NULL); INIT_OBJ(ws, WS_MAGIC); ws->s = space; assert(PAOK(space)); len = PRNDDN(len - 1); ws->e = ws->s + len; *ws->e = 0x15; ws->f = ws->s; assert(id[0] & 0x40); assert(strlen(id) < sizeof ws->id); strcpy(ws->id, id); WS_Assert(ws); }
unsigned WS_Reserve(struct ws *ws, unsigned bytes) { unsigned b2; WS_Assert(ws); assert(ws->r == NULL); b2 = PRNDDN(ws->e - ws->f); if (bytes != 0 && bytes < b2) b2 = PRNDUP(bytes); xxxassert(ws->f + b2 <= ws->e); ws->r = ws->f + b2; DSL(DBG_WORKSPACE, 0, "WS_Reserve(%p, %u/%u) = %u", ws, b2, bytes, pdiff(ws->f, ws->r)); WS_Assert(ws); return (pdiff(ws->f, ws->r)); }
void * WS_Alloc(struct ws *ws, unsigned bytes) { char *r; WS_Assert(ws); bytes = PRNDUP(bytes); assert(ws->r == NULL); if (ws->f + bytes > ws->e) { WS_MarkOverflow(ws); return(NULL); } r = ws->f; ws->f += bytes; DSL(DBG_WORKSPACE, 0, "WS_Alloc(%p, %u) = %p", ws, bytes, r); WS_Assert(ws); return (r); }
char * WS_Alloc(struct ws *ws, unsigned bytes) { char *r; WS_Assert(ws); bytes = PRNDUP(bytes); assert(ws->r == NULL); if (ws->f + bytes > ws->e) { ws->overflow++; WS_Assert(ws); return(NULL); } r = ws->f; ws->f += bytes; DSL(0x02, SLT_Debug, 0, "WS_Alloc(%p, %u) = %p", ws, bytes, r); WS_Assert(ws); return (r); }
unsigned WS_Reserve(struct ws *ws, unsigned bytes) { unsigned b2; WS_Assert(ws); assert(ws->r == NULL); if (bytes == 0) b2 = ws->e - ws->f; else if (bytes > ws->e - ws->f) b2 = ws->e - ws->f; else b2 = bytes; b2 = PRNDDN(b2); xxxassert(ws->f + b2 <= ws->e); ws->r = ws->f + b2; DSL(0x02, SLT_Debug, 0, "WS_Reserve(%p, %u/%u) = %u", ws, b2, bytes, pdiff(ws->f, ws->r)); WS_Assert(ws); return (pdiff(ws->f, ws->r)); }
void WS_Assert(const struct ws *ws) { CHECK_OBJ_NOTNULL(ws, WS_MAGIC); DSL(0x02, SLT_Debug, 0, "WS(%p = (%s, %p %u %u %u)", ws, ws->id, ws->s, pdiff(ws->s, ws->f), ws->r == NULL ? 0 : pdiff(ws->f, ws->r), pdiff(ws->s, ws->e)); assert(ws->s != NULL); assert(PAOK(ws->s)); assert(ws->e != NULL); assert(PAOK(ws->e)); assert(ws->s < ws->e); assert(ws->f >= ws->s); assert(ws->f <= ws->e); assert(PAOK(ws->f)); if (ws->r) { assert(ws->r > ws->s); assert(ws->r <= ws->e); assert(PAOK(ws->r)); } }
http1_reembark(struct worker *wrk, struct req *req) { struct sess *sp; sp = req->sp; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); http1_setstate(sp, H1BUSY); if (!SES_Reschedule_Req(req)) return; /* Couldn't schedule, ditch */ wrk->stats->busy_wakeup--; wrk->stats->busy_killed++; AN (req->vcl); VCL_Rel(&req->vcl); CNT_AcctLogCharge(wrk->stats, req); Req_Release(req); SES_Delete(sp, SC_OVERLOAD, NAN); DSL(DBG_WAITINGLIST, req->vsl->wid, "kill from waiting list"); usleep(10000); }
void WS_Assert(const struct ws *ws) { CHECK_OBJ_NOTNULL(ws, WS_MAGIC); DSL(DBG_WORKSPACE, 0, "WS(%p = (%s, %p %u %u %u)", ws, ws->id, ws->s, pdiff(ws->s, ws->f), ws->r == NULL ? 0 : pdiff(ws->f, ws->r), pdiff(ws->s, ws->e)); assert(ws->s != NULL); assert(PAOK(ws->s)); assert(ws->e != NULL); assert(PAOK(ws->e)); assert(ws->s < ws->e); assert(ws->f >= ws->s); assert(ws->f <= ws->e); assert(PAOK(ws->f)); if (ws->r) { assert(ws->r > ws->s); assert(ws->r <= ws->e); assert(PAOK(ws->r)); } assert(*ws->e == 0x15); }
static void ved_include(struct req *preq, const char *src, const char *host, struct ecx *ecx) { struct worker *wrk; struct req *req; enum req_fsm_nxt s; struct transport xp; CHECK_OBJ_NOTNULL(preq, REQ_MAGIC); CHECK_OBJ_NOTNULL(ecx, ECX_MAGIC); wrk = preq->wrk; if (preq->esi_level >= cache_param->max_esi_depth) return; req = Req_New(wrk, preq->sp); req->req_body_status = REQ_BODY_NONE; AZ(req->vsl->wid); req->vsl->wid = VXID_Get(wrk, VSL_CLIENTMARKER); VSLb(req->vsl, SLT_Begin, "req %u esi", VXID(preq->vsl->wid)); VSLb(preq->vsl, SLT_Link, "req %u esi", VXID(req->vsl->wid)); req->esi_level = preq->esi_level + 1; if (preq->esi_level == 0) assert(preq->top == preq); else CHECK_OBJ_NOTNULL(preq->top, REQ_MAGIC); req->top = preq->top; HTTP_Copy(req->http0, preq->http0); req->http0->ws = req->ws; req->http0->vsl = req->vsl; req->http0->logtag = SLT_ReqMethod; req->http0->conds = 0; http_SetH(req->http0, HTTP_HDR_URL, src); if (host != NULL && *host != '\0') { http_Unset(req->http0, H_Host); http_SetHeader(req->http0, host); } http_ForceField(req->http0, HTTP_HDR_METHOD, "GET"); http_ForceField(req->http0, HTTP_HDR_PROTO, "HTTP/1.1"); /* Don't allow conditionalss, we can't use a 304 */ http_Unset(req->http0, H_If_Modified_Since); http_Unset(req->http0, H_If_None_Match); /* Don't allow Range */ http_Unset(req->http0, H_Range); /* Set Accept-Encoding according to what we want */ http_Unset(req->http0, H_Accept_Encoding); if (ecx->isgzip) http_ForceHeader(req->http0, H_Accept_Encoding, "gzip"); /* Client content already taken care of */ http_Unset(req->http0, H_Content_Length); /* Reset request to status before we started messing with it */ HTTP_Copy(req->http, req->http0); req->vcl = preq->vcl; preq->vcl = NULL; req->wrk = preq->wrk; /* * XXX: We should decide if we should cache the director * XXX: or not (for session/backend coupling). Until then * XXX: make sure we don't trip up the check in vcl_recv. */ req->req_step = R_STP_RECV; req->t_req = preq->t_req; assert(isnan(req->t_first)); assert(isnan(req->t_prev)); INIT_OBJ(&xp, TRANSPORT_MAGIC); xp.deliver = VED_Deliver; req->transport = &xp; req->transport_priv = ecx; THR_SetRequest(req); VSLb_ts_req(req, "Start", W_TIM_real(wrk)); req->ws_req = WS_Snapshot(req->ws); while (1) { req->wrk = wrk; s = CNT_Request(wrk, req); if (s == REQ_FSM_DONE) break; DSL(DBG_WAITINGLIST, req->vsl->wid, "loop waiting for ESI (%d)", (int)s); assert(s == REQ_FSM_DISEMBARK); AZ(req->wrk); (void)usleep(10000); } VRTPRIV_dynamic_kill(req->sp->privs, (uintptr_t)req); CNT_AcctLogCharge(wrk->stats, req); VSL_End(req->vsl); preq->vcl = req->vcl; req->vcl = NULL; req->wrk = NULL; THR_SetRequest(preq); Req_Release(req); }