r595 - trunk/varnish-cache/bin/varnishd

phk at projects.linpro.no phk at projects.linpro.no
Wed Aug 2 09:07:56 CEST 2006


Author: phk
Date: 2006-08-02 09:07:56 +0200 (Wed, 02 Aug 2006)
New Revision: 595

Modified:
   trunk/varnish-cache/bin/varnishd/cache.h
   trunk/varnish-cache/bin/varnishd/cache_acceptor.c
   trunk/varnish-cache/bin/varnishd/cache_fetch.c
   trunk/varnish-cache/bin/varnishd/cache_http.c
   trunk/varnish-cache/bin/varnishd/cache_pass.c
Log:
I have nothing but circumstantial evidence that libevent is involved
in the current stack corruption I see, but we might as well avoid
using it where we can:

Don't engage the eventengine when we talk to the backend, just call
read(2) directly.



Modified: trunk/varnish-cache/bin/varnishd/cache.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache.h	2006-08-02 04:57:58 UTC (rev 594)
+++ trunk/varnish-cache/bin/varnishd/cache.h	2006-08-02 07:07:56 UTC (rev 595)
@@ -347,7 +347,8 @@
 int http_HdrIs(struct http *hp, const char *hdr, const char *val);
 int http_GetTail(struct http *hp, unsigned len, char **b, char **e);
 int http_Read(struct http *hp, int fd, void *b, unsigned len);
-void http_RecvHead(struct http *hp, int fd, struct event_base *eb, http_callback_f *func, void *arg);
+void http_RecvHeadEv(struct http *hp, int fd, struct event_base *eb, http_callback_f *func, void *arg);
+int http_RecvHead(struct http *hp, int fd);
 int http_DissectRequest(struct http *sp, int fd);
 int http_DissectResponse(struct http *sp, int fd);
 

Modified: trunk/varnish-cache/bin/varnishd/cache_acceptor.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_acceptor.c	2006-08-02 04:57:58 UTC (rev 594)
+++ trunk/varnish-cache/bin/varnishd/cache_acceptor.c	2006-08-02 07:07:56 UTC (rev 595)
@@ -92,7 +92,7 @@
 	assert(i == sizeof sp);
 	clock_gettime(CLOCK_MONOTONIC, &sp->t_idle);
 	TAILQ_INSERT_TAIL(&sesshead, sp, list);
-	http_RecvHead(sp->http, sp->fd, evb, vca_callback, sp);
+	http_RecvHeadEv(sp->http, sp->fd, evb, vca_callback, sp);
 }
 
 static void
@@ -136,7 +136,7 @@
 	VSL(SLT_SessionOpen, sp->fd, "%s %s", sp->addr, sp->port);
 	clock_gettime(CLOCK_MONOTONIC, &sp->t_idle);
 	TAILQ_INSERT_TAIL(&sesshead, sp, list);
-	http_RecvHead(sp->http, sp->fd, evb, vca_callback, sp);
+	http_RecvHeadEv(sp->http, sp->fd, evb, vca_callback, sp);
 }
 
 static void *

Modified: trunk/varnish-cache/bin/varnishd/cache_fetch.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_fetch.c	2006-08-02 04:57:58 UTC (rev 594)
+++ trunk/varnish-cache/bin/varnishd/cache_fetch.c	2006-08-02 07:07:56 UTC (rev 595)
@@ -296,12 +296,9 @@
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 	CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);
 	CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC);
-	/*
-	 * XXX: It might be cheaper to avoid the event_engine and simply
-	 * XXX: read(2) the header
-	 */
-	http_RecvHead(vc->http, vc->fd, w->eb, NULL, NULL);
-	(void)event_base_loop(w->eb, 0);
+
+	i = http_RecvHead(vc->http, vc->fd);
+	assert(i == 0);
 	assert(http_DissectResponse(vc->http, vc->fd) == 0);
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 	CHECK_OBJ_NOTNULL(sp->wrk, WORKER_MAGIC);

Modified: trunk/varnish-cache/bin/varnishd/cache_http.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_http.c	2006-08-02 04:57:58 UTC (rev 594)
+++ trunk/varnish-cache/bin/varnishd/cache_http.c	2006-08-02 07:07:56 UTC (rev 595)
@@ -440,19 +440,36 @@
 	return (1);
 }
 
-
 /*--------------------------------------------------------------------*/
 
 static void
-http_read_f(int fd, short event, void *arg)
+http_preprecv(struct http *hp)
 {
-	struct http *hp;
 	unsigned l;
-	int i, ret = 0;
 
-	(void)event;
+	CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
+	assert(hp->v <= hp->e);
+	assert(hp->t <= hp->v);
+	if (hp->t > hp->s && hp->t < hp->v) {
+		l = hp->v - hp->t;
+		memmove(hp->s, hp->t, l);
+		hp->v = hp->s + l;
+		hp->t = hp->s;
+		*hp->v = '\0';
+	} else  {
+		hp->v = hp->s;
+		hp->t = hp->s;
+	}
+}
 
-	CAST_OBJ_NOTNULL(hp, arg, HTTP_MAGIC);
+/*--------------------------------------------------------------------*/
+
+static int
+http_read_hdr(int fd, struct http *hp)
+{
+	unsigned l;
+	int i;
+
 	l = (hp->e - hp->s) / 2;
 	if (l < hp->v - hp->s)
 		l = 0;
@@ -462,72 +479,87 @@
 		VSL(SLT_HttpError, fd, "Received too much");
 		VSLR(SLT_HttpGarbage, fd, hp->s, hp->v);
 		hp->t = NULL;
-		ret = 1;
-	} else {
-		errno = 0;
-		i = read(fd, hp->v, l - 1);
-		if (i > 0) {
-			hp->v += i;
-			*hp->v = '\0';
-			if (!http_header_complete(hp))
-				return;
-		} else {
-			if (hp->v != hp->s) {
-				VSL(SLT_HttpError, fd,
-				    "Received (only) %d bytes, errno %d",
-				    hp->v - hp->s, errno);
-				VSLR(SLT_Debug, fd, hp->s, hp->v);
-			} else if (errno == 0)
-				VSL(SLT_HttpError, fd, "Received nothing");
-			else
-				VSL(SLT_HttpError, fd,
-				    "Received errno %d", errno);
-			hp->t = NULL;
-			ret = 2;
-		}
+		return (1);
 	}
+	errno = 0;
+	i = read(fd, hp->v, l - 1);
+	if (i > 0) {
+		hp->v += i;
+		*hp->v = '\0';
+		if (http_header_complete(hp))
+			return(0);
+		return (-1);
+	} 
 
-	assert(hp->t != NULL || ret != 0);
+	if (hp->v != hp->s) {
+		VSL(SLT_HttpError, fd,
+		    "Received (only) %d bytes, errno %d",
+		    hp->v - hp->s, errno);
+		VSLR(SLT_Debug, fd, hp->s, hp->v);
+	} else if (errno == 0)
+		VSL(SLT_HttpError, fd, "Received nothing");
+	else
+		VSL(SLT_HttpError, fd,
+		    "Received errno %d", errno);
+	hp->t = NULL;
+	return(2);
+}
+
+/*--------------------------------------------------------------------*/
+
+static void
+http_read_f(int fd, short event, void *arg)
+{
+	struct http *hp;
+	int i;
+
+	(void)event;
+
+	CAST_OBJ_NOTNULL(hp, arg, HTTP_MAGIC);
+	i = http_read_hdr(fd, hp);
+	if (i < 0)
+		return;
+
 	event_del(&hp->ev);
 	if (hp->callback != NULL)
-		hp->callback(hp->arg, ret);
+		hp->callback(hp->arg, i);
 }
 
-/*--------------------------------------------------------------------*/
 
 void
-http_RecvHead(struct http *hp, int fd, struct event_base *eb, http_callback_f *func, void *arg)
+http_RecvHeadEv(struct http *hp, int fd, struct event_base *eb, http_callback_f *func, void *arg)
 {
-	unsigned l;
 
 	CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
-	assert(hp->v <= hp->e);
-	assert(hp->t <= hp->v);
-	if (0)
-		VSL(SLT_Debug, fd, "Recv t %u v %u",
-		    hp->t - hp->s, hp->v - hp->s);
-	if (hp->t > hp->s && hp->t < hp->v) {
-		l = hp->v - hp->t;
-		memmove(hp->s, hp->t, l);
-		hp->v = hp->s + l;
-		hp->t = hp->s;
-		*hp->v = '\0';
-		if (http_header_complete(hp)) {
-			assert(func != NULL);
-			func(arg, 0);
-			return;
-		}
-	} else  {
-		hp->v = hp->s;
-		hp->t = hp->s;
+	assert(func != NULL);
+	http_preprecv(hp);
+	if (hp->v != hp->s && http_header_complete(hp)) {
+		func(arg, 0);
+		return;
 	}
 	hp->callback = func;
 	hp->arg = arg;
 	event_set(&hp->ev, fd, EV_READ | EV_PERSIST, http_read_f, hp);
 	AZ(event_base_set(eb, &hp->ev));
 	AZ(event_add(&hp->ev, NULL));      /* XXX: timeout */
+	return;
 }
 
+/*--------------------------------------------------------------------*/
+
+int
+http_RecvHead(struct http *hp, int fd)
+{
+	int i;
+
+	CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
+	http_preprecv(hp);
+	do 
+		i = http_read_hdr(fd, hp);
+	while (i == -1);
+	return (i);
+}
+
 /*--------------------------------------------------------------------
  * Copy HTTP headers into malloc'ed space.
  */

Modified: trunk/varnish-cache/bin/varnishd/cache_pass.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_pass.c	2006-08-02 04:57:58 UTC (rev 594)
+++ trunk/varnish-cache/bin/varnishd/cache_pass.c	2006-08-02 07:07:56 UTC (rev 595)
@@ -205,12 +205,8 @@
 
 	/* XXX: copy any contents */
 
-	/*
-	 * XXX: It might be cheaper to avoid the event_engine and simply
-	 * XXX: read(2) the header
-	 */
-	http_RecvHead(vc->http, vc->fd, w->eb, NULL, NULL);
-	(void)event_base_loop(w->eb, 0);
+	i = http_RecvHead(vc->http, vc->fd);
+	assert(i == 0);
 	http_DissectResponse(vc->http, vc->fd);
 
 	sp->vbc = vc;




More information about the varnish-commit mailing list