]> err.no Git - varnish/commitdiff
test backend connections at allocation time.
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Tue, 25 Apr 2006 09:32:14 +0000 (09:32 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Tue, 25 Apr 2006 09:32:14 +0000 (09:32 +0000)
General bush-wacking in the fetch code.

git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@156 d4fa192b-c00b-0410-8231-f00ffab90ce4

varnish-cache/bin/varnishd/cache_backend.c
varnish-cache/bin/varnishd/cache_fetch.c
varnish-cache/bin/varnishd/cache_http.c

index fe97e52ec63100c495d40d82d67a4038544ea2d4..2305dcbbd2e45224930627b1e91d1dfab31792ee 100644 (file)
@@ -14,6 +14,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <sys/select.h>
 
 #include "libvarnish.h"
 #include "shmlog.h"
@@ -90,12 +91,42 @@ connect_to_backend(struct vbe_conn *vc, struct backend *bp)
 
 /*--------------------------------------------------------------------*/
 
+int
+tst_fd(int fd)
+{
+       fd_set  r,w,e;
+       int i;
+       struct timeval tv;
+       char c;
+
+       FD_ZERO(&r);
+       FD_ZERO(&w);
+       FD_ZERO(&e);
+       FD_SET(fd, &r);
+       FD_SET(fd, &w);
+       FD_SET(fd, &e);
+       tv.tv_sec = 0;
+       tv.tv_usec = 0;
+       i = select(fd + 1, &r, &w, &e, &tv);
+       printf("tst_fd fd %d i %d flag %d/%d/%d\n",
+           fd, i, FD_ISSET(fd, &r), FD_ISSET(fd, &w), FD_ISSET(fd, &e));
+       if (FD_ISSET(fd, &r)) {
+               i = read(fd, &c, 1);
+               if (i == 0)
+                       return (1);
+       }
+       return (0);
+}
+
+/*--------------------------------------------------------------------*/
+
 int
 VBE_GetFd(struct backend *bp, void **ptr)
 {
        struct vbe *vp;
        struct vbe_conn *vc;
 
+again:
        AZ(pthread_mutex_lock(&vbemtx));
        vp = bp->vbe;
        if (vp == NULL) {
@@ -118,6 +149,10 @@ VBE_GetFd(struct backend *bp, void **ptr)
                TAILQ_REMOVE(&vp->fconn, vc, list);
                TAILQ_INSERT_TAIL(&vp->bconn, vc, list);
                AZ(pthread_mutex_unlock(&vbemtx));
+               if (tst_fd(vc->fd)) {
+                       VBE_ClosedFd(vc);
+                       goto again;
+               }
        } else {
                vc = calloc(sizeof *vc, 1);
                assert(vc != NULL);
index 39db10e526992f619aac6dd01401fd508dd76013..2dc7ed05c934a49a53db8b60b20d8d6883abb5d4 100644 (file)
 #include "cache.h"
 
 static int
-fetch_straight(struct worker *w, struct sess *sp, struct http *hp, char *b)
+fetch_straight(struct worker *w, struct sess *sp, int fd, struct http *hp, char *b)
 {
        int i;
        char *e;
-       struct sess sp2;
        unsigned char *p;
        off_t   cl;
        struct storage *st;
@@ -40,25 +39,27 @@ fetch_straight(struct worker *w, struct sess *sp, struct http *hp, char *b)
        sp->obj->len = cl;
        p = st->ptr;
 
-       i = fcntl(sp2.fd, F_GETFL);             /* XXX ? */
+       i = fcntl(fd, F_GETFL);         /* XXX ? */
        i &= ~O_NONBLOCK;
-       i = fcntl(sp2.fd, F_SETFL, i);
+       i = fcntl(fd, F_SETFL, i);
 
        if (http_GetTail(hp, cl, &b, &e)) {
                i = e - b;
+               VSL(SLT_Debug, 0, "Fetch_Tail %jd %d", cl, i);
                memcpy(p, b, i);
                p += i;
                cl -= i;
        }
 
        while (cl != 0) {
-               i = read(sp2.fd, p, cl);
+               i = read(fd, p, cl);
+               VSL(SLT_Debug, 0, "Fetch_Read %jd %d", cl, i);
                assert(i > 0);
                p += i;
                cl -= i;
        }
 
-       http_BuildSbuf(1, w->sb, hp);
+       http_BuildSbuf(2, w->sb, hp);
        i = write(sp->fd, sbuf_data(w->sb), sbuf_len(w->sb));
        assert(i == sbuf_len(w->sb));
 
@@ -76,20 +77,19 @@ fetch_straight(struct worker *w, struct sess *sp, struct http *hp, char *b)
 }
 
 static int
-fetch_chunked(struct worker *w, struct sess *sp, struct http *hp)
+fetch_chunked(struct worker *w, struct sess *sp, int fd, struct http *hp)
 {
        int i;
        char *b, *q, *e;
-       struct sess sp2;
        unsigned char *p;
        struct storage *st;
        unsigned u;
        char buf[20];
        char *bp, *be;
 
-       i = fcntl(sp2.fd, F_GETFL);             /* XXX ? */
+       i = fcntl(fd, F_GETFL);         /* XXX ? */
        i &= ~O_NONBLOCK;
-       i = fcntl(sp2.fd, F_SETFL, i);
+       i = fcntl(fd, F_SETFL, i);
 
        be = buf + sizeof buf;
        while (1) {
@@ -100,7 +100,7 @@ printf("Tail: (H)\n%#H\n", b, e - b);
                        memcpy(bp, b, e - b);
                        bp += e - b;
                } else {
-                       i = read(sp2.fd, bp, be - bp);
+                       i = read(fd, bp, be - bp);
                        assert(i >= 0);
                        bp += i;
                }
@@ -131,7 +131,7 @@ printf("Tail: (B)\n%#H\n", b, e - b);
                        u -= e - b;
                }
                if (u > 0) {
-                       i = read(sp2.fd, p, u);
+                       i = read(fd, p, u);
 if (0)
 printf("u = %u i = %d\n", u, i);
                        assert(i == u);
@@ -140,7 +140,7 @@ if (0)
 printf("Store:\n%#H\n", st->ptr, st->len);
        }
 
-       http_BuildSbuf(1, w->sb, hp);
+       http_BuildSbuf(2, w->sb, hp);
        i = write(sp->fd, sbuf_data(w->sb), sbuf_len(w->sb));
        assert(i == sbuf_len(w->sb));
 
@@ -165,7 +165,6 @@ FetchSession(struct worker *w, struct sess *sp)
 {
        int fd, i, cls;
        void *fd_token;
-       struct sess sp2;
        struct http *hp;
        char *b;
 
@@ -174,22 +173,21 @@ FetchSession(struct worker *w, struct sess *sp)
        VSL(SLT_Handling, sp->fd, "Fetch fd %d", fd);
 
        hp = http_New();
-       http_BuildSbuf(0, w->sb, sp->http);
+HERE();
+       http_BuildSbuf(1, w->sb, sp->http);
+HERE();
        i = write(fd, sbuf_data(w->sb), sbuf_len(w->sb));
        assert(i == sbuf_len(w->sb));
 
        /* XXX: copy any contents */
 
-       memset(&sp2, 0, sizeof sp2);
-       sp2.rd_e = &w->e1;
-       sp2.fd = fd;
        /*
         * XXX: It might be cheaper to avoid the event_engine and simply
         * XXX: read(2) the header
         */
-       http_RecvHead(hp, sp2.fd, w->eb, NULL, NULL);
+       http_RecvHead(hp, fd, w->eb, NULL, NULL);
        event_base_loop(w->eb, 0);
-       http_Dissect(hp, sp2.fd, 2);
+       http_Dissect(hp, fd, 2);
 
        /* XXX: fill in object from headers */
        sp->obj->valid = 1;
@@ -201,12 +199,12 @@ FetchSession(struct worker *w, struct sess *sp)
        assert(sp->handling == HND_Insert);
 
        if (http_GetHdr(hp, "Content-Length", &b)) {
-               cls = fetch_straight(w, sp, hp, b);
+               cls = fetch_straight(w, sp, fd, hp, b);
        } else if (http_GetHdr(hp, "Transfer-Encoding", &b) &&
            !strcasecmp(b, "chunked")) {
-               cls = fetch_chunked(w, sp, hp);
+               cls = fetch_chunked(w, sp, fd, hp);
        } else {
-               assert(0 == 1);
+               VSL(SLT_Debug, fd, "No transfer");
                cls = 0;
        }
 
index a4957c20e62d1a0931838edf2be28aba9ff5bbec..718980cece4a0eda88bfb47538cf431f55d69b2c 100644 (file)
@@ -137,6 +137,7 @@ http_Dissect(struct http *hp, int fd, int rr)
 {
        char *p, *q, *r;
 
+       assert(hp->t != NULL);
        if (rr == 1) {
                /* First, isolate and possibly identify request type */
                hp->req = hp->s;
@@ -227,6 +228,8 @@ http_Dissect(struct http *hp, int fd, int rr)
 
 /*--------------------------------------------------------------------*/
 
+#include <errno.h>
+
 static void
 http_read_f(int fd, short event, void *arg)
 {
@@ -235,13 +238,14 @@ http_read_f(int fd, short event, void *arg)
        int i;
 
        assert(hp->v < hp->e);
+       errno = 0;
        i = read(fd, hp->v, hp->e - hp->v);
        if (i <= 0) {
                if (hp->v != hp->s)
                        VSL(SLT_SessionClose, fd,
-                           "remote had %d bytes", hp->v - hp->s);
+                           "remote had %d bytes errno %d", hp->v - hp->s, errno);
                else
-                       VSL(SLT_SessionClose, fd, "remote");
+                       VSL(SLT_SessionClose, fd, "remote errno %d", errno);
                hp->t = NULL;
                event_del(&hp->ev);
                if (hp->callback != NULL)
@@ -329,25 +333,27 @@ http_BuildSbuf(int resp, struct sbuf *sb, struct http *hp)
 
        sbuf_clear(sb);
        assert(sb != NULL);
-       if (resp) {
+       if (resp == 2) {
                sbuf_cat(sb, hp->proto);
                sbuf_cat(sb, " ");
                sbuf_cat(sb, hp->status);
                sbuf_cat(sb, " ");
                sbuf_cat(sb, hp->response);
-       } else {
+       } else if (resp == 1) {
                sbuf_cat(sb, hp->req);
                sbuf_cat(sb, " ");
                sbuf_cat(sb, hp->url);
                sbuf_cat(sb, " ");
                sbuf_cat(sb, hp->proto);
+       } else {
+               assert(resp == 1 || resp == 2);
        }
        sbuf_cat(sb, "\r\n");
 
        for (u = 0; u < hp->nhdr; u++) {
                if (http_supress(hp->hdr[u], resp))
                        continue;
-               if (0)
+               if (1)
                        VSL(SLT_Debug, 0, "Build %s", hp->hdr[u]);
                sbuf_cat(sb, hp->hdr[u]);
                sbuf_cat(sb, "\r\n");