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

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: http://www.varnish-cache.org/svn/trunk/varnish-cache@2267 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent b6469445
......@@ -36,6 +36,7 @@
#if defined(HAVE_KQUEUE)
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
......@@ -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));
}
......
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