r2267 - trunk/varnish-cache/bin/varnishd

phk at projects.linpro.no phk at projects.linpro.no
Tue Nov 20 13:11:04 CET 2007


Author: phk
Date: 2007-11-20 13:11:04 +0100 (Tue, 20 Nov 2007)
New Revision: 2267

Modified:
   trunk/varnish-cache/bin/varnishd/cache_acceptor_kqueue.c
Log:
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)



Modified: trunk/varnish-cache/bin/varnishd/cache_acceptor_kqueue.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_acceptor_kqueue.c	2007-11-20 12:01:40 UTC (rev 2266)
+++ trunk/varnish-cache/bin/varnishd/cache_acceptor_kqueue.c	2007-11-20 12:11:04 UTC (rev 2267)
@@ -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 @@
 	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 @@
 			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 @@
 		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 @@
 		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 @@
 				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 @@
 	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));
 }
 




More information about the varnish-commit mailing list