From: phk Date: Tue, 20 Nov 2007 12:11:04 +0000 (+0000) Subject: Use a bitmap to check if we own a given file handle, before we X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f4ee6beecaa33ab56fb3768dba8f63a9e1b841dd;p=varnish Use a bitmap to check if we own a given file handle, before we do anything about the associated session. May be relevant relative to: #162 (Bitmap functions slightly general, for possible later reuse) git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@2267 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- diff --git a/varnish-cache/bin/varnishd/cache_acceptor_kqueue.c b/varnish-cache/bin/varnishd/cache_acceptor_kqueue.c index 2e7ab013..ed297cb2 100644 --- a/varnish-cache/bin/varnishd/cache_acceptor_kqueue.c +++ b/varnish-cache/bin/varnishd/cache_acceptor_kqueue.c @@ -36,6 +36,7 @@ #if defined(HAVE_KQUEUE) #include +#include #include #include #include @@ -48,9 +49,84 @@ #include "cache.h" #include "cache_acceptor.h" +/********************************************************************** + * Generic bitmap functions, may be generalized at some point. + */ + +#define VBITMAP_TYPE unsigned /* Our preferred wordsize */ +#define VBITMAP_LUMP (32*1024) /* How many bits we alloc at a time */ +#define VBITMAP_WORD (sizeof(VBITMAP_TYPE) * 8) +#define VBITMAP_IDX(n) (n / VBITMAP_WORD) +#define VBITMAP_BIT(n) (1U << (n % VBITMAP_WORD)) + +struct vbitmap { + VBITMAP_TYPE *bits; + unsigned nbits; +}; + +static void +vbit_expand(struct vbitmap *vb, unsigned bit) +{ + unsigned char *p; + + bit += VBITMAP_LUMP - 1; + bit -= (bit % VBITMAP_LUMP); + VSL(SLT_Debug, 0, "Expanding KQ VBIT to %u", bit); + p = realloc(vb->bits, bit / 8); + AN(p); + memset(p + vb->nbits / 8, 0, (bit - vb->nbits) / 8); + vb->bits = (void*)p; + vb->nbits = bit; +} + +static struct vbitmap * +vbit_init(unsigned initial) +{ + struct vbitmap *vb; + + vb = calloc(sizeof *vb, 1); + AN(vb); + if (initial == 0) + initial = VBITMAP_LUMP; + vbit_expand(vb, initial); + return (vb); +} + +static void +vbit_set(struct vbitmap *vb, unsigned bit) +{ + + if (bit >= vb->nbits) + vbit_expand(vb, bit); + vb->bits[VBITMAP_IDX(bit)] |= VBITMAP_BIT(bit); +} + +static void +vbit_clr(struct vbitmap *vb, unsigned bit) +{ + + if (bit >= vb->nbits) + vbit_expand(vb, bit); + vb->bits[VBITMAP_IDX(bit)] &= ~VBITMAP_BIT(bit); +} + +static int +vbit_test(struct vbitmap *vb, unsigned bit) +{ + + if (bit >= vb->nbits) + vbit_expand(vb, bit); + return (vb->bits[VBITMAP_IDX(bit)] & VBITMAP_BIT(bit)); +} + +/**********************************************************************/ + + static pthread_t vca_kqueue_thread; static int kq = -1; +struct vbitmap *vca_kqueue_bits; + static VTAILQ_HEAD(,sess) sesshead = VTAILQ_HEAD_INITIALIZER(sesshead); #define NKEV 100 @@ -66,7 +142,7 @@ vca_kq_sess(struct sess *sp, short arm) if (sp->fd < 0) return; EV_SET(&ki[nki], sp->fd, EVFILT_READ, arm, 0, 0, sp); - if (++nki == NKEV || arm == EV_DELETE) { + if (++nki == NKEV) { AZ(kevent(kq, ki, nki, NULL, 0, NULL)); nki = 0; } @@ -89,6 +165,8 @@ vca_kev(const struct kevent *kp) CHECK_OBJ_NOTNULL(ss[j], SESS_MAGIC); assert(ss[j]->fd >= 0); AZ(ss[j]->obj); + AZ(vbit_test(vca_kqueue_bits, ss[j]->fd)); + vbit_set(vca_kqueue_bits, ss[j]->fd); VTAILQ_INSERT_TAIL(&sesshead, ss[j], list); vca_kq_sess(ss[j], EV_ADD); j++; @@ -97,6 +175,13 @@ vca_kev(const struct kevent *kp) assert(i == 0); return; } + if (!vbit_test(vca_kqueue_bits, kp->ident)) { + VSL(SLT_Debug, kp->ident, + "KQ: not my fd %d, sp %p kev data %lu flags 0x%x%s", + kp->ident, kp->udata, (unsigned long)kp->data, kp->flags, + (kp->flags & EV_EOF) ? " EOF" : ""); + return; + } CAST_OBJ_NOTNULL(sp, kp->udata, SESS_MAGIC); #ifdef DIAGNOSTICS VSL(SLT_Debug, sp->id, "sp %p kev data %lu flags 0x%x%s", @@ -107,11 +192,13 @@ vca_kev(const struct kevent *kp) i = HTC_Rx(sp->htc); if (i == 0) return; /* more needed */ + vbit_clr(vca_kqueue_bits, sp->fd); VTAILQ_REMOVE(&sesshead, sp, list); vca_kq_sess(sp, EV_DELETE); vca_handover(sp, i); return; } else if (kp->flags == EV_EOF) { + vbit_clr(vca_kqueue_bits, sp->fd); VTAILQ_REMOVE(&sesshead, sp, list); vca_close_session(sp, "EOF"); SES_Delete(sp); @@ -164,6 +251,7 @@ vca_kqueue_main(void *arg) break; if (sp->t_open > deadline) break; + vbit_clr(vca_kqueue_bits, sp->fd); VTAILQ_REMOVE(&sesshead, sp, list); vca_close_session(sp, "timeout"); SES_Delete(sp); @@ -182,6 +270,7 @@ vca_kqueue_init(void) i |= O_NONBLOCK; i = fcntl(vca_pipes[0], F_SETFL, i); + vca_kqueue_bits = vbit_init(0); AZ(pthread_create(&vca_kqueue_thread, NULL, vca_kqueue_main, NULL)); }