r647 - trunk/varnish-cache/bin/varnishd

phk at projects.linpro.no phk at projects.linpro.no
Sat Aug 5 11:27:57 CEST 2006


Author: phk
Date: 2006-08-05 11:27:57 +0200 (Sat, 05 Aug 2006)
New Revision: 647

Modified:
   trunk/varnish-cache/bin/varnishd/mgt_event.c
   trunk/varnish-cache/bin/varnishd/mgt_event.h
Log:
Add signal support.


Modified: trunk/varnish-cache/bin/varnishd/mgt_event.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/mgt_event.c	2006-08-05 08:49:54 UTC (rev 646)
+++ trunk/varnish-cache/bin/varnishd/mgt_event.c	2006-08-05 09:27:57 UTC (rev 647)
@@ -2,16 +2,29 @@
  * $Id$
  */
 
+#include <stdio.h>
 #include <assert.h>
 #include <errno.h>
 #include <poll.h>
 #include <time.h>
+#include <signal.h>
+#include <string.h>
 #include <stdlib.h>
 
 #include "mgt_event.h"
 #include "miniobj.h"
 #include "binary_heap.h"
 
+struct evsig {
+	struct evbase		*evb;
+	struct ev		*ev;
+	struct sigaction	sigact;
+	unsigned char		happened;
+};
+
+static struct evsig		*ev_sigs;
+static unsigned			ev_nsig;
+
 struct evbase {
 	unsigned		magic;
 #define EVBASE_MAGIC		0x0cfd976f
@@ -64,6 +77,64 @@
 
 /*--------------------------------------------------------------------*/
 
+static int
+ev_get_pfd(struct evbase *evb)
+{
+	unsigned u;
+	void *p;
+
+	if (evb->lpfd < evb->npfd) 
+		return (0);
+
+	if (evb->npfd > 256)
+		u = evb->npfd + 256;
+	else if (evb->npfd > 8)
+		u = evb->npfd * 2;
+	else
+		u = 8;
+	p = realloc(evb->pfd, sizeof *evb->pfd * u);
+	if (p == NULL)
+		return (1);
+	evb->npfd = u;
+	evb->pfd = p;
+	return (0);
+}
+
+/*--------------------------------------------------------------------*/
+
+static int
+ev_get_sig(int sig)
+{
+	struct evsig *os;
+
+	if (sig < ev_nsig) 
+		return (0);
+
+	os = calloc(sizeof *os, (sig + 1));
+	if (os == NULL)
+		return (ENOMEM);
+
+	memcpy(os, ev_sigs, ev_nsig);
+
+	free(ev_sigs);
+	ev_sigs = os;
+	ev_nsig = sig + 1;
+
+	return (0);
+}
+
+/*--------------------------------------------------------------------*/
+
+static void
+ev_sighandler(int sig)
+{
+	assert(sig < ev_nsig);
+	assert(ev_sigs != NULL);
+	ev_sigs[sig].happened = 1;
+}
+
+/*--------------------------------------------------------------------*/
+
 struct evbase *
 ev_new_base(void)
 {
@@ -72,14 +143,12 @@
 	evb = calloc(sizeof *evb, 1);
 	if (!evb)
 		return (evb);
-	evb->magic = EVBASE_MAGIC;
-	TAILQ_INIT(&evb->events);
-	evb->npfd = 1;
-	evb->pfd = calloc(sizeof *evb->pfd, evb->npfd);
-	if (evb->pfd == NULL) {
+	if (ev_get_pfd(evb)) {
 		free(evb);
 		return (NULL);
 	}
+	evb->magic = EVBASE_MAGIC;
+	TAILQ_INIT(&evb->events);
 	evb->binheap = binheap_new(evb, ev_bh_cmp, ev_bh_update);
 	return (evb);
 }
@@ -94,48 +163,42 @@
 	free(evb);
 }
 
-/*--------------------------------------------------------------------*/
 
-static int
-ev_get_pfd(struct evbase *evb)
-{
-	unsigned u;
-	void *p;
-
-	if (evb->lpfd <= evb->npfd) 
-		return (0);
-
-	if (evb->npfd > 256)
-		u = evb->npfd + 256;
-	else
-		u = evb->npfd * 2;
-	p = realloc(evb->pfd, sizeof *evb->pfd * u);
-	if (p == NULL)
-		return (1);
-	evb->npfd = u;
-	evb->pfd = p;
-	return (0);
-}
-
 /*--------------------------------------------------------------------*/
 
 int
 ev_add(struct evbase *evb, struct ev *e)
 {
+	struct evsig *es;
 
 	CHECK_OBJ_NOTNULL(evb, EVBASE_MAGIC);
 	assert(e->magic != EV_MAGIC);
 	assert(e->callback != NULL);
+	assert(e->signal >= 0);
+	assert(e->timeout >= 0.0);
 
-	if (e->timeout < 0.0)
-		return (EINVAL);
+	if (e->signal > 0 && ev_get_sig(e->signal))
+		return (ENOMEM);
 
+	if (e->fd >= 0 && ev_get_pfd(evb))
+		return (ENOMEM);
+
+	if (e->signal > 0) {
+		es = &ev_sigs[e->signal];
+		if (es->ev != NULL)
+			return (EBUSY);
+		assert(es->happened == 0);
+		es->ev = e;
+		es->sigact.sa_flags = e->sig_flags;
+		es->sigact.sa_handler = ev_sighandler;
+		assert(sigaction(e->signal, &es->sigact, NULL) == 0);
+		es->evb = evb;
+	}
+
 	if (e->fd >= 0) {
-		if (ev_get_pfd(evb))
-			return (ENOMEM);
 		evb->pfd[evb->lpfd].fd = e->fd;
 		evb->pfd[evb->lpfd].events =
-		    e->flags & (EV_RD|EV_WR|EV_ERR|EV_HUP);
+		    e->fd_flags & (EV_RD|EV_WR|EV_ERR|EV_HUP);
 		e->__poll_idx = evb->lpfd;
 		evb->lpfd++;
 	} else
@@ -165,6 +228,8 @@
 void
 ev_del(struct evbase *evb, struct ev *e)
 {
+	struct evsig *es;
+
 	CHECK_OBJ_NOTNULL(evb, EVBASE_MAGIC);
 	CHECK_OBJ_NOTNULL(e, EV_MAGIC);
 	assert(evb == e->__evb);
@@ -179,6 +244,18 @@
 		e->fd = -1;
 	}
 
+	if (e->signal > 0) {
+		assert(e->signal < ev_nsig);
+		es = &ev_sigs[e->signal];
+		assert(es->ev == e);
+		es->ev = NULL;
+		es->evb = NULL;
+		es->sigact.sa_flags = e->sig_flags;
+		es->sigact.sa_handler = SIG_DFL;
+		assert(sigaction(e->signal, &es->sigact, NULL) == 0);
+		es->happened = 0;
+	}
+
 	TAILQ_REMOVE(&evb->events, e, __list);
 
 	e->magic = 0;
@@ -217,7 +294,9 @@
 {
 	int i;
 
+printf("Call %p %s (TMO)\n", e, e->name);
 	i = e->callback(e, 0);
+printf("Back %p %s (TMO)\n", e, e->name);
 	if (i) {
 		ev_del(evb, e);
 		free(e);
@@ -255,6 +334,23 @@
 	if (tmo == INFTIM && evb->lpfd == 0)
 		return (0);
 	i = poll(evb->pfd, evb->lpfd, tmo);
+	if(i == -1 && errno == EINTR) {
+		for (j = 0; j < ev_nsig; j++) {
+			if (!ev_sigs[j].happened || ev_sigs[j].evb != evb)
+				continue;
+			ev_sigs[j].happened = 0;
+			e = ev_sigs[j].ev;
+			assert(e != NULL);
+printf("Call %p %s (sig %d)\n", e, e->name, j);
+			i = e->callback(e, EV_SIG);
+printf("Back %p %s (sig %d)\n", e, e->name, j);
+			if (i) {
+				ev_del(evb, e);
+				free(e);
+			}
+		}
+		return (1);
+	}
 	if (i == 0) {
 		assert(e != NULL);
 		t = ev_now();
@@ -271,12 +367,12 @@
 		assert(e->__poll_idx < evb->lpfd);
 		pfd = &evb->pfd[e->__poll_idx];
 		assert(pfd->fd == e->fd);
-		assert(pfd->events == e->flags);
+		assert(pfd->events == e->fd_flags);
 		if (!pfd->revents)
 			continue;
 printf("Call %p %s (%u)\n", e, e->name, pfd->revents);
 		j = e->callback(e, pfd->revents);
-printf("Back from %p %s (%u)\n", e, e->name, pfd->revents);
+printf("Back %p %s (%u)\n", e, e->name, pfd->revents);
 		i--;
 		if (evb->disturbed) {
 			TAILQ_FOREACH(e2, &evb->events, __list)

Modified: trunk/varnish-cache/bin/varnishd/mgt_event.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/mgt_event.h	2006-08-05 08:49:54 UTC (rev 646)
+++ trunk/varnish-cache/bin/varnishd/mgt_event.h	2006-08-05 09:27:57 UTC (rev 647)
@@ -14,11 +14,14 @@
 	/* pub */
 	const char	*name;
 	int		fd;
-	unsigned	flags;
+	unsigned	fd_flags;
 #define		EV_RD	POLLIN
 #define		EV_WR	POLLOUT
 #define		EV_ERR	POLLERR
 #define		EV_HUP	POLLHUP
+#define		EV_SIG	-1
+	int		signal;
+	unsigned	sig_flags;
 	double		timeout;
 	ev_cb_f		*callback;
 	void		*priv;




More information about the varnish-commit mailing list