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