bind 8.2.3 vs. munnari: second try

Paul A Vixie vixie at mibh.net
Thu Jul 20 19:24:41 UTC 2000


i don't know why i didn't think of this years ago.  need review please!

all this does is change the main loop to use evWaitFor() to queue up the
needs handlers (and evDo() to activate them immediately upon addition.)
originally we did evDo() in the main loop, and it was dog-slow, and i just
don't understand why the approach below didn't occur to me.

invariants are:

1. "needs" integer is never read or written while signals are unblocked.
2. heap memory is never allocated from a signal handler.
3. never call evGetNext(EV_WAIT) while needs remain unhandled (or unqueued).
4. never call evGetNext(EV_POLL) hoping it won't find anything.

i've tested this lightly.  it can reload zones after named-xfer exits, and
named itself can exit.  i don't think the performance will be too bad but
i havn't stressed it yet.

Index: ns_glob.h
===================================================================
RCS file: /proj/cvs/isc/bind/src/bin/named/ns_glob.h,v
retrieving revision 8.54
diff -u -r8.54 ns_glob.h
--- ns_glob.h	2000/04/21 06:54:07	8.54
+++ ns_glob.h	2000/07/20 18:34:35
@@ -209,7 +209,6 @@
 DECL	server_info		nameserver_info		INIT(NULL);
 DECL	key_info_list		secretkey_info		INIT(NULL);
 
-DECL	int			main_needs_exit		INIT(0);
 DECL	ip_match_list		bogus_nameservers	INIT(NULL);
 
 DECL	log_context 		log_ctx;
Index: ns_main.c
===================================================================
RCS file: /proj/cvs/isc/bind/src/bin/named/ns_main.c,v
retrieving revision 8.125
diff -u -r8.125 ns_main.c
--- ns_main.c	2000/04/21 06:54:08	8.125
+++ ns_main.c	2000/07/20 19:22:37
@@ -163,8 +163,9 @@
 static	int                     nsid_algorithm;
 
 typedef void (*handler)(void);
-static	int			needs = 0;
+static	int			needs = 0, needs_exit = 0;
 static	handler			handlers[main_need_num];
+static	void			need_waitfunc(evContext, void *, const void *);
 
 static	struct qstream		*sq_add(void);
 static	int			opensocket_d(interface *),
@@ -196,7 +197,7 @@
 static int			only_digits(const char *);
 
 static void			init_needs(void),
-				handle_need(void);
+				handle_needs(void);
 
 #ifndef HAVE_CUSTOM
 static void			custom_init(void),
@@ -525,21 +526,16 @@
 	ns_notice(ns_log_default, "Ready to answer queries.");
 	gettime(&tt);
 	prime_cache();
-	while (!main_needs_exit) {
+	while (!needs_exit) {
 		evEvent event;
 
 		ns_debug(ns_log_default, 15, "main loop");
-		if (needs != 0) {
-			/* Drain outstanding events; handlers ~block~. */
-			while (evGetNext(ev, &event, EV_POLL) != -1)
-				INSIST_ERR(evDispatch(ev, event) != -1);
-			INSIST_ERR(errno == EINTR || errno == EWOULDBLOCK);
-			handle_need();
-		} else if (evGetNext(ev, &event, EV_WAIT) != -1) {
+		if (needs != 0)
+			handle_needs();
+		else if (evGetNext(ev, &event, EV_WAIT) != -1)
 			INSIST_ERR(evDispatch(ev, event) != -1);
-		} else {
+		else
 			INSIST_ERR(errno == EINTR);
-		}
 	}
 	ns_info(ns_log_default, "named shutting down");
 #ifdef BIND_UPDATE
@@ -2551,11 +2547,6 @@
 }
 	
 static void
-ns_exit(void) {
-	main_needs_exit++;
-}
-
-static void
 ns_restart(void) {
 	ns_info(ns_log_default, "named restarting");
 #ifdef BIND_UPDATE
@@ -2639,7 +2630,7 @@
 	handlers[main_need_zoneload] = loadxfer;
 	handlers[main_need_dump] = doadump;
 	handlers[main_need_statsdump] = ns_stats;
-	handlers[main_need_exit] = ns_exit;
+	handlers[main_need_exit] = wild;
 	handlers[main_need_qrylog] = toggle_qrylog;
 	handlers[main_need_debug] = use_desired_debug;
 	handlers[main_need_restart] = ns_restart;
@@ -2648,20 +2639,32 @@
 }
 
 static void
-handle_need(void) {
-	int need;
+handle_needs(void) {
+	int need, queued = 0;
 
-	ns_debug(ns_log_default, 15, "handle_need()");
+	ns_debug(ns_log_default, 15, "handle_needs()");
+	block_signals();
 	for (need = 0; need < main_need_num; need++)
 		if ((needs & (1 << need)) != 0) {
-			/* Turn off flag first, handlers ~turn~ it back on. */
-			block_signals();
+			INSIST_ERR(evWaitFor(ev, handle_needs, need_waitfunc,
+					     handlers[need], NULL) != -1);
 			needs &= ~(1 << need);
-			unblock_signals();
-			(handlers[need])();
-			return;
+			queued++;
 		}
-	ns_panic(ns_log_default, 1, "handle_need() found no needs", NULL);
+	unblock_signals();
+	ns_debug(ns_log_default, 15, "handle_needs(): queued %d", queued);
+	if (queued != 0) {
+		INSIST_ERR(evDo(ev, handle_needs) != -1);
+		return;
+	}
+	ns_panic(ns_log_default, 1, "ns_handle_needs: queued == 0", NULL);
+}
+
+static void
+need_waitfunc(evContext ctx, void *uap, const void *tag) {
+	handler hand = (handler) uap;
+
+	(*hand)();
 }
 
 void
@@ -2675,6 +2678,8 @@
 void
 ns_need_unsafe(enum need need) {
 	needs |= (1 << need);
+	if (need == main_need_exit)
+		needs_exit = 1;
 }
 
 void



More information about the bind-workers mailing list