Commit b636e251 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Wrap the management of the session workspace in functions, to prevent

pointer gymnastics getting out of hand.

In addition to the obvious alloc/return primitives there are also 
reserve/release primitives for when we don't know the length yet.



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@1498 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent f54ff6ba
......@@ -29,6 +29,7 @@ varnishd_SOURCES = \
cache_vrt.c \
cache_vrt_acl.c \
cache_vrt_re.c \
cache_ws.c \
hash_simple_list.c \
hash_classic.c \
mgt_child.c \
......
......@@ -76,9 +76,30 @@ enum step {
#undef STEP
};
/*--------------------------------------------------------------------
* Workspace structure for quick memory allocation.
*/
struct ws {
char *s; /* (S)tart of buffer */
char *e; /* (E)nd of buffer */
char *f; /* (F)ree pointer */
char *r; /* (R)eserved length */
};
void WS_Init(struct ws *ws, void *space, unsigned len);
unsigned WS_Reserve(struct ws *ws, unsigned bytes);
void WS_Release(struct ws *ws, unsigned bytes);
void WS_ReleaseP(struct ws *ws, char *ptr);
void WS_Assert(struct ws *ws);
void WS_Reset(struct ws *ws);
char *WS_Alloc(struct ws *ws, unsigned bytes);
void WS_Return(struct ws *ws, char *b, char *e);
/*--------------------------------------------------------------------
* HTTP Request/Response/Header handling structure.
* RSN: struct worker and struct session will have one of these embedded.
*/
struct http_hdr {
......@@ -90,11 +111,9 @@ struct http {
unsigned magic;
#define HTTP_MAGIC 0x6428b5c9
char *s; /* (S)tart of buffer */
char *t; /* start of (T)railing data */
char *v; /* end of (V)alid bytes */
char *f; /* first (F)ree byte */
char *e; /* (E)nd of buffer */
struct ws ws[1];
char *rx_s, *rx_e; /* Received Request */
char *pl_s, *pl_e; /* Pipelined bytes */
unsigned char conds; /* If-* headers present */
enum httpwhence {
......
......@@ -214,7 +214,7 @@ cnt_done(struct sess *sp)
sp->step = STP_RECV;
return (0);
}
if (sp->http->t < sp->http->v) {
if (sp->http->pl_s < sp->http->pl_e) {
VSL_stats->sess_readahead++;
sp->step = STP_AGAIN;
return (0);
......@@ -426,13 +426,12 @@ cnt_lookup(struct sess *sp)
{
struct object *o;
assert(sp->http->f > sp->http->s);
assert(sp->http->f >= sp->http->t);
if (sp->obj == NULL) {
sp->hash_b = sp->http->f;
WS_Reserve(sp->http->ws, 0);
sp->hash_b = sp->http->ws->f;
sp->hash_e = sp->hash_b;
VCL_hash_method(sp); /* XXX: no-op for now */
WS_ReleaseP(sp->http->ws, sp->hash_e);
/* XXX check error */
}
......@@ -449,12 +448,7 @@ cnt_lookup(struct sess *sp)
return (1);
}
xxxassert (sp->hash_e == sp->http->f);
if (sp->hash_e == sp->http->f) {
/* Nobody alloc'ed after us, free again */
sp->http->f = sp->hash_b;
}
WS_Return(sp->http->ws, sp->hash_b, sp->hash_e);
sp->hash_b = sp->hash_e = NULL;
sp->obj = o;
......
......@@ -251,8 +251,8 @@ HSH_Deref(struct object *o)
if (r != 0)
return;
if (o->http.s != NULL)
free(o->http.s);
if (o->http.ws->s != NULL)
free(o->http.ws->s);
HSH_Freestore(o);
free(o);
......
This diff is collapsed.
......@@ -57,7 +57,6 @@ SYN_ErrorPage(struct sess *sp, int status, const char *reason, int ttl)
const char *msg;
char date[40];
time_t now;
size_t len;
int fd;
assert(status >= 100 && status <= 999);
......@@ -122,10 +121,8 @@ SYN_ErrorPage(struct sess *sp, int status, const char *reason, int ttl)
vsb_delete(&vsb);
/* allocate space for header */
/* XXX what if the object already has a header? */
h->v = h->s = calloc(len = 1024, 1);
XXXAN(h->s);
h->e = h->s + len;
WS_Init(h->ws, malloc(1024), 1024);
/* generate header */
http_ClrHeader(h);
......
......@@ -284,10 +284,8 @@ VRT_l_req_hash(struct sess *sp, const char *str)
if (str == NULL)
str = "";
l = strlen(str);
xxxassert (sp->hash_e == sp->http->f);
xxxassert (sp->hash_e + l + 1 <= sp->http->e);
xxxassert (sp->hash_e + l + 1 <= sp->http->ws->e);
memcpy(sp->hash_e, str, l);
sp->hash_e[l] = '#';
sp->hash_e += l + 1;
sp->http->f += l + 1;
}
/*-
* Copyright (c) 2006 Verdens Gang AS
* Copyright (c) 2006 Linpro AS
* All rights reserved.
*
* Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
*
*/
#include <sys/types.h>
#include <sys/uio.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "heritage.h"
#include "shmlog.h"
#include "vcl.h"
#include "cli_priv.h"
#include "cache.h"
void
WS_Assert(struct ws *ws)
{
assert(ws != NULL);
assert(ws->s != NULL);
assert(ws->e != NULL);
assert(ws->s < ws->e);
assert(ws->f >= ws->s);
assert(ws->f <= ws->e);
if (ws->r) {
assert(ws->r > ws->s);
assert(ws->r <= ws->e);
}
}
void
WS_Init(struct ws *ws, void *space, unsigned len)
{
assert(space != NULL);
memset(ws, 0, sizeof *ws);
ws->s = space;
ws->e = ws->s + len;
ws->f = ws->s;
WS_Assert(ws);
}
void
WS_Reset(struct ws *ws)
{
WS_Assert(ws);
assert(ws->r == NULL);
ws->f = ws->s;
}
char *
WS_Alloc(struct ws *ws, unsigned bytes)
{
char *r;
WS_Assert(ws);
assert(ws->r == NULL);
xxxassert(ws->f + bytes <= ws->e);
r = ws->f;
ws->f += bytes;
return (r);
}
unsigned
WS_Reserve(struct ws *ws, unsigned bytes)
{
WS_Assert(ws);
assert(ws->r == NULL);
if (bytes == 0)
bytes = ws->e - ws->f;
xxxassert(ws->f + bytes <= ws->e);
ws->r = ws->f + bytes;
return (ws->r - ws->f);
}
void
WS_Release(struct ws *ws, unsigned bytes)
{
WS_Assert(ws);
assert(ws->r != NULL);
assert(ws->f + bytes <= ws->r);
ws->f += bytes;
ws->r = NULL;
}
void
WS_ReleaseP(struct ws *ws, char *ptr)
{
WS_Assert(ws);
assert(ws->r != NULL);
assert(ptr >= ws->f);
assert(ptr <= ws->r);
ws->f = ptr;
ws->r = NULL;
}
void
WS_Return(struct ws *ws, char *s, char *e)
{
WS_Assert(ws);
if (e == ws->f)
ws->f = s;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment