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); }
enum req_fsm_nxt CNT_Request(struct worker *wrk, struct req *req) { enum req_fsm_nxt nxt; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); /* * Possible entrance states */ assert( req->req_step == R_STP_LOOKUP || req->req_step == R_STP_RECV); AN(req->vsl->wid & VSL_CLIENTMARKER); req->wrk = wrk; wrk->vsl = req->vsl; for (nxt = REQ_FSM_MORE; nxt == REQ_FSM_MORE; ) { /* * This is a good place to be paranoid about the various * pointers still pointing to the things we expect. */ CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_ORNULL(wrk->nobjhead, OBJHEAD_MAGIC); CHECK_OBJ_NOTNULL(req, REQ_MAGIC); /* * We don't want the thread workspace to be used for * anything of long duration, so mandate that it be * empty on state-transitions. */ WS_Assert(wrk->aws); assert(wrk->aws->s == wrk->aws->f); switch (req->req_step) { #define REQ_STEP(l,u,arg) \ case R_STP_##u: \ if (DO_DEBUG(DBG_REQ_STATE)) \ cnt_diag(req, #u); \ nxt = cnt_##l arg; \ break; #include "tbl/steps.h" #undef REQ_STEP default: WRONG("State engine misfire"); } WS_Assert(wrk->aws); CHECK_OBJ_ORNULL(wrk->nobjhead, OBJHEAD_MAGIC); } wrk->vsl = NULL; if (nxt == REQ_FSM_DONE) { AN(req->vsl->wid); VRB_Free(req); req->wrk = NULL; } return (nxt); }
void CNT_Session(struct sess *sp) { int done; struct worker *w; CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); w = sp->wrk; CHECK_OBJ_NOTNULL(w, WORKER_MAGIC); /* * Possible entrance states */ assert( sp->step == STP_FIRST || sp->step == STP_START || sp->step == STP_LOOKUP || sp->step == STP_RECV); /* * Whenever we come in from the acceptor we need to set blocking * mode, but there is no point in setting it when we come from * ESI or when a parked sessions returns. * It would be simpler to do this in the acceptor, but we'd rather * do the syscall in the worker thread. */ if (sp->step == STP_FIRST || sp->step == STP_START) TCP_blocking(sp->fd); for (done = 0; !done; ) { assert(sp->wrk == w); /* * This is a good place to be paranoid about the various * pointers still pointing to the things we expect. */ CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_ORNULL(sp->obj, OBJECT_MAGIC); CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC); CHECK_OBJ_ORNULL(w->nobjhead, OBJHEAD_MAGIC); WS_Assert(w->ws); switch (sp->step) { #define STEP(l,u) \ case STP_##u: \ if (params->diag_bitmap & 0x01) \ cnt_diag(sp, #u); \ done = cnt_##l(sp); \ break; #include "steps.h" #undef STEP default: WRONG("State engine misfire"); } WS_Assert(w->ws); CHECK_OBJ_ORNULL(w->nobjhead, OBJHEAD_MAGIC); } WSL_Flush(w, 0); AZ(w->wfd); }
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); }
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_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); }
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); }
unsigned WS_Free(const struct ws *ws) { WS_Assert(ws); return(ws->e - ws->f); }
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); }
static void ses_pool_task(struct worker *wrk, void *arg) { struct sess *sp; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CAST_OBJ_NOTNULL(sp, arg, SESS_MAGIC); AZ(wrk->aws->r); wrk->lastused = NAN; THR_SetSession(sp); if (wrk->sp == NULL) wrk->sp = sp; else assert(wrk->sp == sp); AZ(sp->wrk); sp->wrk = wrk; CNT_Session(sp); sp = NULL; /* Cannot access sp now */ THR_SetSession(NULL); wrk->sp = NULL; WS_Assert(wrk->aws); AZ(wrk->busyobj); AZ(wrk->wrw); assert(wrk->vsl->wlp == wrk->vsl->wlb); if (cache_param->diag_bitmap & 0x00040000) { if (wrk->vcl != NULL) VCL_Rel(&wrk->vcl); } }
/* XXX: not used anywhere (yet) */ void WS_Return(struct ws *ws, char *s, char *e) { WS_Assert(ws); if (e == ws->f) ws->f = s; }
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); }
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); }
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 vmod_workspace_snap(VRT_CTX, VCL_ENUM which) { struct ws *ws; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); ws = wsfind(ctx, which); WS_Assert(ws); debug_ws_snap = WS_Snapshot(ws); }
VCL_BOOL vmod_workspace_overflowed(VRT_CTX, VCL_ENUM which) { struct ws *ws; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); ws = wsfind(ctx, which); WS_Assert(ws); return (WS_Overflowed(ws)); }
void vmod_workspace_overflow(VRT_CTX, VCL_ENUM which) { struct ws *ws; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); ws = wsfind(ctx, which); WS_Assert(ws); WS_MarkOverflow(ws); }
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); }
void vmod_workspace_reset(VRT_CTX, VCL_ENUM which) { struct ws *ws; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); ws = wsfind(ctx, which); WS_Assert(ws); WS_Reset(ws, debug_ws_snap); }
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)); }
VCL_INT vmod_workspace_free(VRT_CTX, VCL_ENUM which) { struct ws *ws; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); ws = wsfind(ctx, which); WS_Assert(ws); AZ(ws->r); return pdiff(ws->f, ws->e); }
http1_req(struct worker *wrk, void *arg) { struct req *req; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CAST_OBJ_NOTNULL(req, arg, REQ_MAGIC); THR_SetRequest(req); req->transport = &HTTP1_transport; AZ(wrk->aws->r); HTTP1_Session(wrk, req); AZ(wrk->v1l); WS_Assert(wrk->aws); THR_SetRequest(NULL); }
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 vmod_workspace_allocate(VRT_CTX, VCL_ENUM which, VCL_INT size) { struct ws *ws; char *s; CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); ws = wsfind(ctx, which); WS_Assert(ws); AZ(ws->r); s = WS_Alloc(ws, size); if (!s) return; memset(s, '\0', size); }
static void ses_req_pool_task(struct worker *wrk, void *arg) { struct req *req; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CAST_OBJ_NOTNULL(req, arg, REQ_MAGIC); THR_SetRequest(req); AZ(wrk->aws->r); wrk->lastused = NAN; HTTP1_Session(wrk, req); WS_Assert(wrk->aws); AZ(wrk->wrw); if (DO_DEBUG(DBG_VCLREL) && wrk->vcl != NULL) VCL_Rel(&wrk->vcl); THR_SetRequest(NULL); }
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); }
SES_Proto_Req(struct worker *wrk, void *arg) { struct req *req; CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CAST_OBJ_NOTNULL(req, arg, REQ_MAGIC); THR_SetRequest(req); AZ(wrk->aws->r); if (req->sp->sess_step < S_STP_H1_LAST) { HTTP1_Session(wrk, req); AZ(wrk->v1l); } else { WRONG("Wrong session step"); } WS_Assert(wrk->aws); if (DO_DEBUG(DBG_VCLREL) && wrk->vcl != NULL) VCL_Rel(&wrk->vcl); THR_SetRequest(NULL); }