Exemple #1
0
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);
}
Exemple #2
0
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);
}
Exemple #4
0
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);
}
Exemple #5
0
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);
}
Exemple #6
0
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);
}
Exemple #7
0
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);
}
Exemple #8
0
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);
}
Exemple #9
0
unsigned
WS_Free(const struct ws *ws)
{

	WS_Assert(ws);
	return(ws->e - ws->f);
}
Exemple #10
0
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);
}
Exemple #11
0
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);
}
Exemple #12
0
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);
	}
}
Exemple #13
0
/* 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;
}
Exemple #14
0
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);
}
Exemple #15
0
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);
}
Exemple #16
0
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);
}
Exemple #17
0
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));
}
Exemple #18
0
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);
}
Exemple #21
0
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);
}
Exemple #22
0
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);
}
Exemple #23
0
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);
}
Exemple #26
0
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);
}
Exemple #29
0
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);
}
Exemple #30
0
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);
}