]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Update isc_timer to use isc_loopmgr
authorOndřej Surý <ondrej@isc.org>
Tue, 26 Jul 2022 11:03:40 +0000 (13:03 +0200)
committerOndřej Surý <ondrej@isc.org>
Thu, 25 Aug 2022 15:17:07 +0000 (17:17 +0200)
* isc_timer was rewritten using the uv_timer, and isc_timermgr_t was
  completely removed; isc_timer objects are now directly created on the
  isc_loop event loops.

* the isc_timer API has been simplified. the "inactive" timer type has
  been removed; timers are now stopped by calling isc_timer_stop()
  instead of resetting to inactive.

* isc_manager now creates a loop manager rather than a timer manager.

* modules and applications using isc_timer have been updated to use the
  new API.

48 files changed:
bin/delv/delv.c
bin/dig/dig.c
bin/dig/dighost.c
bin/dig/dighost.h
bin/dig/host.c
bin/dig/nslookup.c
bin/dnssec/dnssec-signzone.c
bin/named/include/named/globals.h
bin/named/include/named/main.h
bin/named/main.c
bin/named/server.c
bin/nsupdate/nsupdate.c
bin/rndc/rndc.c
bin/tests/test_client.c
bin/tests/test_server.c
bin/tools/mdig.c
lib/dns/cache.c
lib/dns/catz.c
lib/dns/client.c
lib/dns/dyndb.c
lib/dns/include/dns/cache.h
lib/dns/include/dns/catz.h
lib/dns/include/dns/client.h
lib/dns/include/dns/dyndb.h
lib/dns/include/dns/nta.h
lib/dns/include/dns/resolver.h
lib/dns/include/dns/rpz.h
lib/dns/include/dns/view.h
lib/dns/include/dns/zone.h
lib/dns/nta.c
lib/dns/resolver.c
lib/dns/rpz.c
lib/dns/sdb.c
lib/dns/view.c
lib/dns/zone.c
lib/isc/Makefile.am
lib/isc/include/isc/managers.h
lib/isc/include/isc/ratelimiter.h
lib/isc/include/isc/timer.h
lib/isc/managers.c
lib/isc/ratelimiter.c
lib/isc/timer.c
lib/isc/timer_p.h [deleted file]
lib/ns/client.c
lib/ns/include/ns/client.h
lib/ns/include/ns/interfacemgr.h
lib/ns/interfacemgr.c
tests/isc/timer_test.c

index f83501578cd60240e1f474c0f6a64163a0f16f90..5c3240c5744621712fe5124e06e902aa1d208814 100644 (file)
@@ -1719,9 +1719,9 @@ main(int argc, char *argv[]) {
        dns_rdataset_t *rdataset;
        dns_namelist_t namelist;
        unsigned int resopt;
+       isc_loopmgr_t *loopmgr = NULL;
        isc_nm_t *netmgr = NULL;
        isc_taskmgr_t *taskmgr = NULL;
-       isc_timermgr_t *timermgr = NULL;
        dns_master_style_t *style = NULL;
 
        progname = argv[0];
@@ -1737,7 +1737,7 @@ main(int argc, char *argv[]) {
                fatal("dst_lib_init failed: %d", result);
        }
 
-       isc_managers_create(mctx, 1, 0, &netmgr, &taskmgr, &timermgr);
+       isc_managers_create(mctx, 1, 0, &loopmgr, &netmgr, &taskmgr);
 
        parse_args(argc, argv);
 
@@ -1746,7 +1746,7 @@ main(int argc, char *argv[]) {
        setup_logging(stderr);
 
        /* Create client */
-       result = dns_client_create(mctx, taskmgr, netmgr, timermgr, 0, &client,
+       result = dns_client_create(mctx, loopmgr, taskmgr, netmgr, 0, &client,
                                   srcaddr4, srcaddr6);
        if (result != ISC_R_SUCCESS) {
                delv_log(ISC_LOG_ERROR, "dns_client_create: %s",
@@ -1830,7 +1830,7 @@ cleanup:
                dns_client_detach(&client);
        }
 
-       isc_managers_destroy(&netmgr, &taskmgr, &timermgr);
+       isc_managers_destroy(&loopmgr, &netmgr, &taskmgr);
 
        if (lctx != NULL) {
                isc_log_destroy(&lctx);
index 04ca4001c716b5202546f4ed16aab54b8cefcfd3..a416f3fd47613ec43677cecb4fadcfa9c8e942ee 100644 (file)
@@ -19,9 +19,9 @@
 #include <stdlib.h>
 #include <time.h>
 
-#include <isc/app.h>
 #include <isc/attributes.h>
 #include <isc/dir.h>
+#include <isc/loop.h>
 #include <isc/netaddr.h>
 #include <isc/parseint.h>
 #include <isc/print.h>
@@ -59,7 +59,7 @@
 
 dig_lookup_t *default_lookup = NULL;
 
-static atomic_uintptr_t batchname = 0;
+static char *batchname = NULL;
 static FILE *batchfp = NULL;
 static char *argv0;
 static int addresscount = 0;
@@ -2352,7 +2352,7 @@ dash_option(char *option, char *next, dig_lookup_t **lookup,
                }
                return (value_from_next);
        case 'f':
-               atomic_store(&batchname, (uintptr_t)value);
+               batchname = value;
                return (value_from_next);
        case 'k':
                strlcpy(keyfile, value, sizeof(keyfile));
@@ -2838,7 +2838,7 @@ parse_args(bool is_batchfile, bool config_only, int argc, char **argv) {
         * first entry, then trust the callback in dighost_shutdown
         * to get the rest
         */
-       char *filename = (char *)atomic_load(&batchname);
+       char *filename = batchname;
        if ((filename != NULL) && !(is_batchfile)) {
                if (strcmp(filename, "-") == 0) {
                        batchfp = stdin;
@@ -2902,38 +2902,32 @@ parse_args(bool is_batchfile, bool config_only, int argc, char **argv) {
 static void
 query_finished(void) {
        char batchline[MXNAME];
-       int bargc;
-       char *bargv[16];
-
-       if (atomic_load(&batchname) == 0) {
-               isc_app_shutdown();
-               return;
-       }
 
        fflush(stdout);
-       if (feof(batchfp)) {
-               atomic_store(&batchname, 0);
-               isc_app_shutdown();
-               if (batchfp != stdin) {
-                       fclose(batchfp);
-               }
-               return;
-       }
 
-       if (fgets(batchline, sizeof(batchline), batchfp) != 0) {
+       if (batchname != NULL && !feof(batchfp) &&
+           fgets(batchline, sizeof(batchline), batchfp) != NULL)
+       {
+               int bargc;
+               char *bargv[16];
                debug("batch line %s", batchline);
                bargc = split_batchline(batchline, bargv, 14, "batch argv");
                bargv[0] = argv0;
                parse_args(true, false, bargc, (char **)bargv);
                start_lookup();
-       } else {
-               atomic_store(&batchname, 0);
+               return;
+       }
+
+       debug("shutdown");
+
+       /* We are done */
+       if (batchname != NULL) {
                if (batchfp != stdin) {
                        fclose(batchfp);
                }
-               isc_app_shutdown();
-               return;
+               batchname = NULL;
        }
+       isc_loopmgr_shutdown(loopmgr);
 }
 
 static void
@@ -2997,8 +2991,6 @@ dig_comments(dig_lookup_t *lookup, const char *format, ...) {
 
 void
 dig_setup(int argc, char **argv) {
-       isc_result_t result;
-
        ISC_LIST_INIT(lookup_list);
        ISC_LIST_INIT(server_list);
        ISC_LIST_INIT(search_list);
@@ -3017,9 +3009,6 @@ dig_setup(int argc, char **argv) {
        progname = argv[0];
        preparse_args(argc, argv);
 
-       result = isc_app_start();
-       check_result(result, "isc_app_start");
-
        setup_libs();
        setup_system(ipv4only, ipv6only);
 }
@@ -3042,13 +3031,10 @@ dig_query_setup(bool is_batchfile, bool config_only, int argc, char **argv) {
 
 void
 dig_startup(void) {
-       isc_result_t result;
-
        debug("dig_startup()");
 
-       result = isc_app_onrun(mctx, global_task, onrun_callback, NULL);
-       check_result(result, "isc_app_onrun");
-       isc_app_run();
+       isc_loopmgr_setup(loopmgr, run_loop, NULL);
+       isc_loopmgr_run(loopmgr);
 }
 
 void
@@ -3059,15 +3045,8 @@ dig_query_start(void) {
 void
 dig_shutdown(void) {
        destroy_lookup(default_lookup);
-       if (atomic_load(&batchname) != 0) {
-               if (batchfp != stdin) {
-                       fclose(batchfp);
-               }
-               atomic_store(&batchname, 0);
-       }
        cancel_all();
        destroy_libs();
-       isc_app_finish();
 }
 
 /*% Main processing routine for dig */
index d9dac0e15cf7e0f0e13da83b32fb84cbf33facbf..f0771b2d8b8dcab61035299f849216c881fc1a91 100644 (file)
 #include <idn2.h>
 #endif /* HAVE_LIBIDN2 */
 
-#include <isc/app.h>
 #include <isc/base64.h>
 #include <isc/file.h>
 #include <isc/hex.h>
 #include <isc/lang.h>
 #include <isc/log.h>
+#include <isc/loop.h>
 #include <isc/managers.h>
 #include <isc/netaddr.h>
 #include <isc/netdb.h>
@@ -53,7 +53,6 @@
 #include <isc/sockaddr.h>
 #include <isc/string.h>
 #include <isc/task.h>
-#include <isc/timer.h>
 #include <isc/types.h>
 #include <isc/util.h>
 
@@ -89,7 +88,7 @@ dig_lookuplist_t lookup_list;
 dig_serverlist_t server_list;
 dig_searchlistlist_t search_list;
 
-static atomic_bool cancel_now = false;
+static bool cancel_now = false;
 
 bool check_ra = false, have_ipv4 = false, have_ipv6 = false,
      specified_source = false, free_now = false, usesearch = false,
@@ -103,7 +102,8 @@ isc_mem_t *mctx = NULL;
 isc_log_t *lctx = NULL;
 isc_nm_t *netmgr = NULL;
 isc_taskmgr_t *taskmgr = NULL;
-isc_task_t *global_task = NULL;
+isc_loopmgr_t *loopmgr = NULL;
+isc_loop_t *mainloop = NULL;
 isc_sockaddr_t localaddr;
 isc_refcount_t sendcount = 0;
 isc_refcount_t recvcount = 0;
@@ -151,27 +151,10 @@ bool debugging = false;
 bool debugtiming = false;
 bool memdebugging = false;
 char *progname = NULL;
-isc_mutex_t lookup_lock;
 dig_lookup_t *current_lookup = NULL;
 
 #define DIG_MAX_ADDRESSES 20
 
-/*%
- * Apply and clear locks at the event level in global task.
- * Can I get rid of these using shutdown events?  XXX
- */
-#define LOCK_LOOKUP                                             \
-       {                                                       \
-               debug("lock_lookup %s:%d", __FILE__, __LINE__); \
-               isc_mutex_lock((&lookup_lock));                 \
-               debug("success");                               \
-       }
-#define UNLOCK_LOOKUP                                             \
-       {                                                         \
-               debug("unlock_lookup %s:%d", __FILE__, __LINE__); \
-               isc_mutex_unlock((&lookup_lock));                 \
-       }
-
 static void
 default_warnerr(const char *format, ...) {
        va_list args;
@@ -552,8 +535,10 @@ set_nameserver(char *opt) {
                return;
        }
 
+       isc_loopmgr_blocking(loopmgr);
        result = bind9_getaddresses(opt, 0, sockaddrs, DIG_MAX_ADDRESSES,
                                    &count);
+       isc_loopmgr_nonblocking(loopmgr);
        if (result != ISC_R_SUCCESS) {
                fatal("couldn't get address for '%s': %s", opt,
                      isc_result_totext(result));
@@ -1377,6 +1362,8 @@ setup_libs(void) {
        isc_mem_create(&mctx);
        isc_mem_setname(mctx, "dig");
 
+       isc_managers_create(mctx, 1, 0, &loopmgr, &netmgr, &taskmgr);
+
        isc_log_create(mctx, &lctx, &logconfig);
        isc_log_setcontext(lctx);
        dns_log_init(lctx);
@@ -1387,17 +1374,11 @@ setup_libs(void) {
 
        isc_log_setdebuglevel(lctx, 0);
 
-       isc_managers_create(mctx, 1, 0, &netmgr, &taskmgr, NULL);
-
-       result = isc_task_create(taskmgr, 0, &global_task, 0);
-       check_result(result, "isc_task_create");
-       isc_task_setname(global_task, "dig", NULL);
+       mainloop = isc_loop_main(loopmgr);
 
        result = dst_lib_init(mctx, NULL);
        check_result(result, "dst_lib_init");
        is_dst_up = true;
-
-       isc_mutex_init(&lookup_lock);
 }
 
 typedef struct dig_ednsoptname {
@@ -1546,6 +1527,10 @@ check_if_done(void) {
                INSIST(isc_refcount_current(&recvcount) == 0);
                debug("shutting down");
                dighost_shutdown();
+
+               if (current_lookup == NULL && keep != NULL) {
+                       isc_nmhandle_detach(&keep);
+               }
        }
 }
 
@@ -1773,7 +1758,7 @@ void
 start_lookup(void) {
        debug("start_lookup()");
 
-       if (atomic_load(&cancel_now)) {
+       if (cancel_now) {
                return;
        }
 
@@ -2732,8 +2717,6 @@ send_done(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
 
        INSIST(!free_now);
 
-       LOCK_LOOKUP;
-
        isc_nmhandle_detach(&query->sendhandle);
 
        lookup_attach(query->lookup, &l);
@@ -2745,7 +2728,6 @@ send_done(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
                }
                query_detach(&query);
                lookup_detach(&l);
-               UNLOCK_LOOKUP;
                return;
        } else if (eresult != ISC_R_SUCCESS) {
                debug("send failed: %s", isc_result_totext(eresult));
@@ -2759,7 +2741,6 @@ send_done(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
        }
 
        check_if_done();
-       UNLOCK_LOOKUP;
 }
 
 /*%
@@ -2930,6 +2911,8 @@ start_tcp(dig_query_t *query) {
        isc_tlsctx_t *tlsctx = NULL;
        bool tls_mode = false;
        isc_tlsctx_client_session_cache_t *sess_cache = NULL;
+       int local_timeout;
+
        REQUIRE(DIG_VALID_QUERY(query));
 
        debug("start_tcp(%p)", query);
@@ -3000,69 +2983,67 @@ start_tcp(dig_query_t *query) {
                launch_next_query(query);
                query_detach(&query);
                return;
-       } else {
-               int local_timeout = timeout * 1000;
-               if (local_timeout == 0) {
-                       local_timeout = TCP_TIMEOUT * 1000;
-               }
+       } else if (keep != NULL) {
+               isc_nmhandle_detach(&keep);
+       }
 
-               if (keep != NULL) {
-                       isc_nmhandle_detach(&keep);
-               }
+       if (timeout != 0) {
+               local_timeout = timeout * 1000;
+       } else {
+               local_timeout = TCP_TIMEOUT * 1000;
+       }
 
-               if (!specified_source) {
-                       if ((isc_sockaddr_pf(&query->sockaddr) == AF_INET) &&
-                           have_ipv4) {
-                               isc_sockaddr_any(&localaddr);
-                       } else {
-                               isc_sockaddr_any6(&localaddr);
-                       }
+       if (!specified_source) {
+               if ((isc_sockaddr_pf(&query->sockaddr) == AF_INET) && have_ipv4)
+               {
+                       isc_sockaddr_any(&localaddr);
+               } else {
+                       isc_sockaddr_any6(&localaddr);
                }
+       }
 
-               REQUIRE(query != NULL);
+       REQUIRE(query != NULL);
 
-               query_attach(query, &connectquery);
+       query_attach(query, &connectquery);
 
-               if (tls_mode) {
-                       tlsctx = get_create_tls_context(connectquery, false,
+       if (tls_mode) {
+               tlsctx = get_create_tls_context(connectquery, false,
+                                               &sess_cache);
+               if (tlsctx == NULL) {
+                       goto failure_tls;
+               }
+               isc_nm_tlsdnsconnect(netmgr, &localaddr, &query->sockaddr,
+                                    tcp_connected, connectquery, local_timeout,
+                                    tlsctx, sess_cache);
+#if HAVE_LIBNGHTTP2
+       } else if (query->lookup->https_mode) {
+               char uri[4096] = { 0 };
+               isc_nm_http_makeuri(!query->lookup->http_plain,
+                                   &query->sockaddr, query->userarg, port,
+                                   query->lookup->https_path, uri,
+                                   sizeof(uri));
+
+               if (!query->lookup->http_plain) {
+                       tlsctx = get_create_tls_context(connectquery, true,
                                                        &sess_cache);
                        if (tlsctx == NULL) {
                                goto failure_tls;
                        }
-                       isc_nm_tlsdnsconnect(netmgr, &localaddr,
-                                            &query->sockaddr, tcp_connected,
-                                            connectquery, local_timeout,
-                                            tlsctx, sess_cache);
-#if HAVE_LIBNGHTTP2
-               } else if (query->lookup->https_mode) {
-                       char uri[4096] = { 0 };
-                       isc_nm_http_makeuri(!query->lookup->http_plain,
-                                           &query->sockaddr, query->userarg,
-                                           port, query->lookup->https_path,
-                                           uri, sizeof(uri));
-
-                       if (!query->lookup->http_plain) {
-                               tlsctx = get_create_tls_context(
-                                       connectquery, true, &sess_cache);
-                               if (tlsctx == NULL) {
-                                       goto failure_tls;
-                               }
-                       }
-
-                       isc_nm_httpconnect(netmgr, &localaddr, &query->sockaddr,
-                                          uri, !query->lookup->https_get,
-                                          tcp_connected, connectquery, tlsctx,
-                                          sess_cache, local_timeout);
-#endif
-               } else {
-                       isc_nm_tcpdnsconnect(netmgr, &localaddr,
-                                            &query->sockaddr, tcp_connected,
-                                            connectquery, local_timeout);
                }
 
-               /* XXX: set DSCP */
+               isc_nm_httpconnect(netmgr, &localaddr, &query->sockaddr, uri,
+                                  !query->lookup->https_get, tcp_connected,
+                                  connectquery, tlsctx, sess_cache,
+                                  local_timeout);
+#endif
+       } else {
+               isc_nm_tcpdnsconnect(netmgr, &localaddr, &query->sockaddr,
+                                    tcp_connected, connectquery,
+                                    local_timeout);
        }
 
+       /* XXX: set DSCP */
+
        return;
 
 failure_tls:
@@ -3145,7 +3126,7 @@ udp_ready(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
 
        query->started = true;
 
-       if (atomic_load(&cancel_now)) {
+       if (cancel_now) {
                query_detach(&query);
                return;
        }
@@ -3255,8 +3236,7 @@ udp_ready(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
 
 /*%
  * Send a UDP packet to the remote nameserver, possible starting the
- * recv action as well.  Also make sure that the timer is running and
- * is properly reset.
+ * recv action as well.
  */
 static void
 start_udp(dig_query_t *query) {
@@ -3357,11 +3337,9 @@ force_next(dig_query_t *query) {
 
        debug("force_next()");
 
-       LOCK_LOOKUP;
        INSIST(!free_now);
 
-       if (atomic_load(&cancel_now)) {
-               UNLOCK_LOOKUP;
+       if (cancel_now) {
                return;
        }
 
@@ -3369,7 +3347,6 @@ force_next(dig_query_t *query) {
 
        if (try_next_server(l)) {
                lookup_detach(&l);
-               UNLOCK_LOOKUP;
                return;
        }
 
@@ -3384,7 +3361,6 @@ force_next(dig_query_t *query) {
                      isc_refcount_current(&recvcount));
                query_detach(&query);
                clear_current_lookup();
-               UNLOCK_LOOKUP;
                return;
        }
 
@@ -3415,7 +3391,6 @@ force_next(dig_query_t *query) {
        cancel_lookup(l);
        lookup_detach(&l);
        clear_current_lookup();
-       UNLOCK_LOOKUP;
 }
 
 /*%
@@ -3533,7 +3508,7 @@ tcp_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
 
        query->started = true;
 
-       if (atomic_load(&cancel_now)) {
+       if (cancel_now) {
                query_detach(&query);
                return;
        }
@@ -3543,7 +3518,6 @@ tcp_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
        debug("tcp_connected(%p, %s, %p)", handle, isc_result_totext(eresult),
              query);
 
-       LOCK_LOOKUP;
        lookup_attach(query->lookup, &l);
 
        if (eresult == ISC_R_CANCELED || eresult == ISC_R_TLSBADPEERCERT ||
@@ -3570,7 +3544,6 @@ tcp_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
                query_detach(&query);
                lookup_detach(&l);
                clear_current_lookup();
-               UNLOCK_LOOKUP;
                return;
        }
 
@@ -3628,7 +3601,6 @@ tcp_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
                }
 
                check_if_done();
-               UNLOCK_LOOKUP;
                return;
        }
 
@@ -3647,7 +3619,6 @@ tcp_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
        launch_next_query(query);
        query_detach(&query);
        lookup_detach(&l);
-       UNLOCK_LOOKUP;
 }
 
 /*%
@@ -3921,8 +3892,6 @@ recv_done(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
        debug("recv_done(%p, %s, %p, %p)", handle, isc_result_totext(eresult),
              region, arg);
 
-       LOCK_LOOKUP;
-
        isc_refcount_decrement0(&recvcount);
        debug("recvcount=%" PRIuFAST32, isc_refcount_current(&recvcount));
 
@@ -3937,7 +3906,6 @@ recv_done(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
                query_detach(&query);
                lookup_detach(&l);
                clear_current_lookup();
-               UNLOCK_LOOKUP;
                return;
        }
 
@@ -3947,7 +3915,7 @@ recv_done(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
                TIME_NOW(&query->time_recv);
        }
 
-       if ((!l->pending && !l->ns_search_only) || atomic_load(&cancel_now)) {
+       if ((!l->pending && !l->ns_search_only) || cancel_now) {
                debug("no longer pending.  Got %s", isc_result_totext(eresult));
 
                goto next_lookup;
@@ -4379,7 +4347,7 @@ recv_done(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
                 * the timeout to much longer, so brief network
                 * outages won't cause the XFR to abort
                 */
-               if (timeout != INT_MAX && query->timer != NULL) {
+               if (timeout != INT_MAX) {
                        unsigned int local_timeout;
 
                        if (timeout == 0) {
@@ -4529,7 +4497,6 @@ keep_query:
        if (donext) {
                clear_current_lookup();
        }
-       UNLOCK_LOOKUP;
 }
 
 /*%
@@ -4541,16 +4508,10 @@ isc_result_t
 get_address(char *host, in_port_t myport, isc_sockaddr_t *sockaddr) {
        int count;
        isc_result_t result;
-       bool is_running;
 
-       is_running = isc_app_isrunning();
-       if (is_running) {
-               isc_app_block();
-       }
+       isc_loopmgr_blocking(loopmgr);
        result = bind9_getaddresses(host, myport, sockaddr, 1, &count);
-       if (is_running) {
-               isc_app_unblock();
-       }
+       isc_loopmgr_nonblocking(loopmgr);
        if (result != ISC_R_SUCCESS) {
                return (result);
        }
@@ -4569,8 +4530,10 @@ getaddresses(dig_lookup_t *lookup, const char *host, isc_result_t *resultp) {
        dig_server_t *srv;
        char tmp[ISC_NETADDR_FORMATSIZE];
 
+       isc_loopmgr_blocking(loopmgr);
        result = bind9_getaddresses(host, 0, sockaddrs, DIG_MAX_ADDRESSES,
                                    &count);
+       isc_loopmgr_nonblocking(loopmgr);
        if (resultp != NULL) {
                *resultp = result;
        }
@@ -4618,13 +4581,17 @@ do_lookup(dig_lookup_t *lookup) {
  * Start everything in action upon task startup.
  */
 void
-onrun_callback(isc_task_t *task, isc_event_t *event) {
-       UNUSED(task);
+onrun_callback(void *arg) {
+       UNUSED(arg);
+
+       start_lookup();
+}
+
+void
+run_loop(void *arg) {
+       UNUSED(arg);
 
-       isc_event_free(&event);
-       LOCK_LOOKUP;
        start_lookup();
-       UNLOCK_LOOKUP;
 }
 
 /*%
@@ -4638,12 +4605,12 @@ cancel_all(void) {
 
        debug("cancel_all()");
 
-       LOCK_LOOKUP;
        if (free_now) {
-               UNLOCK_LOOKUP;
                return;
        }
-       atomic_store(&cancel_now, true);
+
+       cancel_now = true;
+
        while (current_lookup != NULL) {
                for (q = ISC_LIST_HEAD(current_lookup->q); q != NULL; q = nq) {
                        nq = ISC_LIST_NEXT(q, link);
@@ -4671,7 +4638,6 @@ cancel_all(void) {
                lookup_detach(&l);
                l = n;
        }
-       UNLOCK_LOOKUP;
 }
 
 /*%
@@ -4680,18 +4646,8 @@ cancel_all(void) {
  */
 void
 destroy_libs(void) {
-       if (keep != NULL) {
-               isc_nmhandle_detach(&keep);
-       }
        debug("destroy_libs()");
-       if (global_task != NULL) {
-               debug("freeing task");
-               isc_task_detach(&global_task);
-       }
 
-       isc_managers_destroy(&netmgr, &taskmgr, NULL);
-
-       LOCK_LOOKUP;
        isc_refcount_destroy(&recvcount);
        isc_refcount_destroy(&sendcount);
 
@@ -4719,8 +4675,6 @@ destroy_libs(void) {
                is_dst_up = false;
        }
 
-       UNLOCK_LOOKUP;
-       isc_mutex_destroy(&lookup_lock);
        debug("Removing log context");
        isc_log_destroy(&lctx);
 
@@ -4728,9 +4682,8 @@ destroy_libs(void) {
        if (memdebugging != 0) {
                isc_mem_stats(mctx, stderr);
        }
-       if (mctx != NULL) {
-               isc_mem_destroy(&mctx);
-       }
+
+       isc_managers_destroy(&loopmgr, &netmgr, &taskmgr);
 }
 
 #ifdef HAVE_LIBIDN2
index 00158ac6f94121bb9445500e963bfccb831a3082..f2ba9239e41c6755a33e1a9964028a773f0b4b59 100644 (file)
@@ -23,6 +23,7 @@
 #include <isc/formatcheck.h>
 #include <isc/lang.h>
 #include <isc/list.h>
+#include <isc/loop.h>
 #include <isc/magic.h>
 #include <isc/mem.h>
 #include <isc/netmgr.h>
@@ -218,7 +219,6 @@ struct dig_query {
        isc_time_t time_sent;
        isc_time_t time_recv;
        uint64_t byte_count;
-       isc_timer_t *timer;
 };
 
 struct dig_server {
@@ -263,7 +263,8 @@ extern unsigned int digestbits;
 extern dns_tsigkey_t *tsigkey;
 extern bool validated;
 extern isc_taskmgr_t *taskmgr;
-extern isc_task_t *global_task;
+extern isc_loopmgr_t *loopmgr;
+extern isc_loop_t *mainloop;
 extern bool free_now;
 extern bool debugging, debugtiming, memdebugging;
 extern bool keep_open;
@@ -313,7 +314,10 @@ void
 start_lookup(void);
 
 void
-onrun_callback(isc_task_t *task, isc_event_t *event);
+onrun_callback(void *arg);
+
+void
+run_loop(void *arg);
 
 int
 dhmain(int argc, char **argv);
index 436e9d7741306777046077285f8ba98a94fa8f61..abc2e7bc0f49515d47ef9bf0c190364ab2ec5bf3 100644 (file)
@@ -19,9 +19,9 @@
 #include <stdbool.h>
 #include <stdlib.h>
 
-#include <isc/app.h>
 #include <isc/attributes.h>
 #include <isc/commandline.h>
+#include <isc/loop.h>
 #include <isc/netaddr.h>
 #include <isc/print.h>
 #include <isc/string.h>
@@ -139,7 +139,7 @@ show_usage(void) {
 
 static void
 host_shutdown(void) {
-       (void)isc_app_shutdown();
+       isc_loopmgr_shutdown(loopmgr);
 }
 
 static void
@@ -878,8 +878,6 @@ parse_args(bool is_batchfile, int argc, char **argv) {
 
 int
 main(int argc, char **argv) {
-       isc_result_t result;
-
        tries = 2;
 
        ISC_LIST_INIT(lookup_list);
@@ -897,8 +895,6 @@ main(int argc, char **argv) {
        debug("main()");
        progname = argv[0];
        pre_parse_args(argc, argv);
-       result = isc_app_start();
-       check_result(result, "isc_app_start");
        setup_libs();
        setup_system(ipv4only, ipv6only);
        parse_args(false, argc, argv);
@@ -907,11 +903,12 @@ main(int argc, char **argv) {
        } else if (keysecret[0] != 0) {
                setup_text_key();
        }
-       result = isc_app_onrun(mctx, global_task, onrun_callback, NULL);
-       check_result(result, "isc_app_onrun");
-       isc_app_run();
+
+       isc_loopmgr_setup(loopmgr, run_loop, NULL);
+       isc_loopmgr_run(loopmgr);
+
        cancel_all();
        destroy_libs();
-       isc_app_finish();
+
        return ((seen_error == 0) ? 0 : 1);
 }
index 92bc2c2fa931daada37fb8f3dd92ff11b1e21a56..5896055c3f00b22defda209d8cff0115f296c275 100644 (file)
 #include <stdlib.h>
 #include <unistd.h>
 
-#include <isc/app.h>
 #include <isc/attributes.h>
 #include <isc/buffer.h>
 #include <isc/commandline.h>
+#include <isc/condition.h>
 #include <isc/event.h>
+#include <isc/job.h>
+#include <isc/loop.h>
 #include <isc/netaddr.h>
 #include <isc/parseint.h>
 #include <isc/print.h>
 #include <isc/string.h>
 #include <isc/task.h>
 #include <isc/util.h>
+#include <isc/work.h>
 
 #include <dns/byaddr.h>
 #include <dns/fixedname.h>
@@ -41,6 +44,9 @@
 #include "dighost.h"
 #include "readline.h"
 
+static char cmdlinebuf[COMMSIZE];
+static char *cmdline = NULL;
+
 static bool short_form = true, tcpmode = false, tcpmode_set = false,
            identify = false, stats = true, comments = true,
            section_question = true, section_answer = true,
@@ -53,7 +59,6 @@ static bool interactive;
 static bool in_use = false;
 static char defclass[MXRD] = "IN";
 static char deftype[MXRD] = "A";
-static isc_event_t *global_event = NULL;
 static int query_error = 1, print_error = 0;
 
 static char domainopt[DNS_NAME_MAXTEXT];
@@ -112,9 +117,6 @@ static const char *rtypetext[] = {
 
 #define N_KNOWN_RRTYPES (sizeof(rtypetext) / sizeof(rtypetext[0]))
 
-static void
-getinput(isc_task_t *task, isc_event_t *event);
-
 static char *
 rcode_totext(dns_rcode_t rcode) {
        static char buf[sizeof("?65535")];
@@ -132,20 +134,6 @@ rcode_totext(dns_rcode_t rcode) {
        return (totext.deconsttext);
 }
 
-static void
-query_finished(void) {
-       isc_event_t *event = global_event;
-
-       debug("dighost_shutdown()");
-
-       if (!in_use) {
-               isc_app_shutdown();
-               return;
-       }
-
-       isc_task_send(global_task, &event);
-}
-
 static void
 printsoa(dns_rdata_t *rdata) {
        dns_rdata_soa_t soa;
@@ -401,8 +389,6 @@ chase_cnamechain(dns_message_t *msg, dns_name_t *qname) {
 static isc_result_t
 printmessage(dig_query_t *query, const isc_buffer_t *msgbuf, dns_message_t *msg,
             bool headers) {
-       char servtext[ISC_SOCKADDR_FORMATSIZE];
-
        UNUSED(msgbuf);
 
        /* I've we've gotten this far, we've reached a server. */
@@ -411,6 +397,7 @@ printmessage(dig_query_t *query, const isc_buffer_t *msgbuf, dns_message_t *msg,
        debug("printmessage()");
 
        if (!default_lookups || query->lookup->rdtype == dns_rdatatype_a) {
+               char servtext[ISC_SOCKADDR_FORMATSIZE];
                isc_sockaddr_format(&query->sockaddr, servtext,
                                    sizeof(servtext));
                printf("Server:\t\t%s\n", query->userarg);
@@ -805,10 +792,8 @@ do_next_command(char *input) {
        } else if ((strcasecmp(ptr, "server") == 0) ||
                   (strcasecmp(ptr, "lserver") == 0))
        {
-               isc_app_block();
                set_nameserver(arg);
                check_ra = false;
-               isc_app_unblock();
                show_settings(true, true);
        } else if (strcasecmp(ptr, "exit") == 0) {
                in_use = false;
@@ -825,28 +810,31 @@ do_next_command(char *input) {
 }
 
 static void
-get_next_command(void) {
-       char cmdlinebuf[COMMSIZE];
-       char *cmdline, *ptr = NULL;
+readline_next_command(void *arg) {
+       char *ptr = NULL;
 
-       isc_app_block();
-       if (interactive) {
-               cmdline = ptr = readline("> ");
-               if (ptr != NULL && *ptr != 0) {
-                       add_history(ptr);
-               }
-       } else {
-               cmdline = fgets(cmdlinebuf, COMMSIZE, stdin);
-       }
-       isc_app_unblock();
-       if (cmdline == NULL) {
-               in_use = false;
-       } else {
-               do_next_command(cmdline);
+       UNUSED(arg);
+
+       isc_loopmgr_blocking(loopmgr);
+       ptr = readline("> ");
+       isc_loopmgr_nonblocking(loopmgr);
+       if (ptr == NULL) {
+               return;
        }
-       if (ptr != NULL) {
-               free(ptr);
+
+       if (*ptr != 0) {
+               add_history(ptr);
+               strlcpy(cmdlinebuf, ptr, COMMSIZE);
+               cmdline = cmdlinebuf;
        }
+       free(ptr);
+}
+
+static void
+fgets_next_command(void *arg) {
+       UNUSED(arg);
+
+       cmdline = fgets(cmdlinebuf, COMMSIZE, stdin);
 }
 
 noreturn static void
@@ -899,25 +887,53 @@ parse_args(int argc, char **argv) {
 }
 
 static void
-getinput(isc_task_t *task, isc_event_t *event) {
-       UNUSED(task);
-       if (global_event == NULL) {
-               global_event = event;
-       }
-       while (in_use) {
-               get_next_command();
+start_next_command(void);
+
+static void
+process_next_command(void *arg __attribute__((__unused__))) {
+       if (cmdline == NULL) {
+               in_use = false;
+       } else {
+               do_next_command(cmdline);
                if (ISC_LIST_HEAD(lookup_list) != NULL) {
-                       start_lookup();
+                       isc_job_run(loopmgr, run_loop, NULL);
                        return;
                }
        }
-       isc_app_shutdown();
+
+       start_next_command();
+}
+
+static void
+start_next_command(void) {
+       isc_loop_t *loop = isc_loop_main(loopmgr);
+       if (!in_use) {
+               isc_loopmgr_shutdown(loopmgr);
+               return;
+       }
+
+       cmdline = NULL;
+
+       isc_loopmgr_pause(loopmgr);
+       if (interactive) {
+               isc_work_enqueue(loop, readline_next_command,
+                                process_next_command, loop);
+       } else {
+               isc_work_enqueue(loop, fgets_next_command, process_next_command,
+                                loop);
+       }
+       isc_loopmgr_resume(loopmgr);
+}
+
+static void
+read_loop(void *arg) {
+       UNUSED(arg);
+
+       start_next_command();
 }
 
 int
 main(int argc, char **argv) {
-       isc_result_t result;
-
        interactive = isatty(0);
 
        ISC_LIST_INIT(lookup_list);
@@ -930,10 +946,7 @@ main(int argc, char **argv) {
        dighost_printmessage = printmessage;
        dighost_received = received;
        dighost_trying = trying;
-       dighost_shutdown = query_finished;
-
-       result = isc_app_start();
-       check_result(result, "isc_app_start");
+       dighost_shutdown = start_next_command;
 
        setup_libs();
        progname = argv[0];
@@ -949,23 +962,18 @@ main(int argc, char **argv) {
                set_search_domain(domainopt);
        }
        if (in_use) {
-               result = isc_app_onrun(mctx, global_task, onrun_callback, NULL);
+               isc_loopmgr_setup(loopmgr, run_loop, NULL);
        } else {
-               result = isc_app_onrun(mctx, global_task, getinput, NULL);
+               isc_loopmgr_setup(loopmgr, read_loop, NULL);
        }
-       check_result(result, "isc_app_onrun");
        in_use = !in_use;
 
-       (void)isc_app_run();
+       isc_loopmgr_run(loopmgr);
 
        puts("");
        debug("done, and starting to shut down");
-       if (global_event != NULL) {
-               isc_event_free(&global_event);
-       }
        cancel_all();
        destroy_libs();
-       isc_app_finish();
 
        return (query_error | print_error);
 }
index 1780a93ae81d8409ba08d8504de39d1cc9ba462a..b63a2b9632a573afbaa317b65850e4226e2e9e00 100644 (file)
@@ -144,6 +144,7 @@ static unsigned int nsigned = 0, nretained = 0, ndropped = 0;
 static unsigned int nverified = 0, nverifyfailed = 0;
 static const char *directory = NULL, *dsdir = NULL;
 static isc_mutex_t namelock, statslock;
+static isc_loopmgr_t *loopmgr = NULL;
 static isc_nm_t *netmgr = NULL;
 static isc_taskmgr_t *taskmgr = NULL;
 static dns_db_t *gdb;            /* The database */
@@ -3995,7 +3996,7 @@ main(int argc, char *argv[]) {
        print_time(outfp);
        print_version(outfp);
 
-       isc_managers_create(mctx, ntasks, 0, &netmgr, &taskmgr, NULL);
+       isc_managers_create(mctx, ntasks, 0, &loopmgr, &netmgr, &taskmgr);
 
        main_task = NULL;
        result = isc_task_create(taskmgr, 0, &main_task, 0);
@@ -4046,7 +4047,7 @@ main(int argc, char *argv[]) {
        for (i = 0; i < (int)ntasks; i++) {
                isc_task_detach(&tasks[i]);
        }
-       isc_managers_destroy(&netmgr, &taskmgr, NULL);
+       isc_managers_destroy(&loopmgr, &netmgr, &taskmgr);
        isc_mem_put(mctx, tasks, ntasks * sizeof(isc_task_t *));
        postsign();
        TIME_NOW(&sign_finish);
index 5467d28736450c713e319f9baf0e22ec7b257592..ebacca1524da966877c83fe1e7f19f72c72b77b9 100644 (file)
@@ -18,6 +18,7 @@
 #include <stdbool.h>
 
 #include <isc/log.h>
+#include <isc/loop.h>
 #include <isc/net.h>
 #include <isc/netmgr.h>
 #include <isc/rwlock.h>
@@ -50,6 +51,8 @@ EXTERN isc_mem_t *named_g_mctx                      INIT(NULL);
 EXTERN unsigned int named_g_cpus             INIT(0);
 EXTERN unsigned int named_g_udpdisp          INIT(0);
 EXTERN isc_taskmgr_t *named_g_taskmgr        INIT(NULL);
+EXTERN isc_loop_t *named_g_mainloop          INIT(NULL);
+EXTERN isc_loopmgr_t *named_g_loopmgr        INIT(NULL);
 EXTERN dns_dispatchmgr_t *named_g_dispatchmgr INIT(NULL);
 EXTERN unsigned int named_g_cpus_detected     INIT(1);
 
@@ -61,21 +64,20 @@ EXTERN bool named_g_run_done INIT(false);
  *         for really short timers, another for client timers, and one
  *         for zone timers.
  */
-EXTERN isc_timermgr_t *named_g_timermgr INIT(NULL);
-EXTERN isc_nm_t *named_g_netmgr                INIT(NULL);
-EXTERN cfg_parser_t *named_g_parser    INIT(NULL);
-EXTERN cfg_parser_t *named_g_addparser INIT(NULL);
-EXTERN const char *named_g_version     INIT(PACKAGE_VERSION);
-EXTERN const char *named_g_product     INIT(PACKAGE_NAME);
-EXTERN const char *named_g_description INIT(PACKAGE_DESCRIPTION);
-EXTERN const char *named_g_srcid       INIT(PACKAGE_SRCID);
-EXTERN const char *named_g_configargs  INIT(PACKAGE_CONFIGARGS);
-EXTERN const char *named_g_builder     INIT(PACKAGE_BUILDER);
-EXTERN in_port_t named_g_port          INIT(0);
-EXTERN in_port_t named_g_tlsport       INIT(0);
-EXTERN in_port_t named_g_httpsport     INIT(0);
-EXTERN in_port_t named_g_httpport      INIT(0);
-EXTERN isc_dscp_t named_g_dscp         INIT(-1);
+EXTERN isc_nm_t *named_g_netmgr               INIT(NULL);
+EXTERN cfg_parser_t *named_g_parser    INIT(NULL);
+EXTERN cfg_parser_t *named_g_addparser INIT(NULL);
+EXTERN const char *named_g_version     INIT(PACKAGE_VERSION);
+EXTERN const char *named_g_product     INIT(PACKAGE_NAME);
+EXTERN const char *named_g_description INIT(PACKAGE_DESCRIPTION);
+EXTERN const char *named_g_srcid       INIT(PACKAGE_SRCID);
+EXTERN const char *named_g_configargs  INIT(PACKAGE_CONFIGARGS);
+EXTERN const char *named_g_builder     INIT(PACKAGE_BUILDER);
+EXTERN in_port_t named_g_port         INIT(0);
+EXTERN in_port_t named_g_tlsport       INIT(0);
+EXTERN in_port_t named_g_httpsport     INIT(0);
+EXTERN in_port_t named_g_httpport      INIT(0);
+EXTERN isc_dscp_t named_g_dscp        INIT(-1);
 
 EXTERN in_port_t named_g_http_listener_clients INIT(0);
 EXTERN in_port_t named_g_http_streams_per_conn INIT(0);
index 42fd138314dcbdf7c9d25fdac70058f7e6e86ccd..bed5dd9787c128d91325caa7639aae0dc470182c 100644 (file)
@@ -34,3 +34,6 @@ named_main_earlywarning(const char *format, ...) ISC_FORMAT_PRINTF(1, 2);
 
 void
 named_main_setmemstats(const char *);
+
+void
+named_main_shutdown(void *arg, int signum);
index ddf002dd967d93168fa5ef8ea10803f8dfbf95bd..b57b608211f73fbbf1ed14cd8c1c6eb6227a09bc 100644 (file)
@@ -923,8 +923,8 @@ create_managers(void) {
                      named_g_udpdisp == 1 ? "" : "s");
 
        result = isc_managers_create(named_g_mctx, named_g_cpus,
-                                    0 /* quantum */, &named_g_netmgr,
-                                    &named_g_taskmgr, &named_g_timermgr);
+                                    0 /* quantum */, &named_g_loopmgr,
+                                    &named_g_netmgr, &named_g_taskmgr);
        if (result != ISC_R_SUCCESS) {
                return (result);
        }
@@ -936,8 +936,8 @@ create_managers(void) {
 
 static void
 destroy_managers(void) {
-       isc_managers_destroy(&named_g_netmgr, &named_g_taskmgr,
-                            &named_g_timermgr);
+       isc_managers_destroy(&named_g_loopmgr, &named_g_netmgr,
+                            &named_g_taskmgr);
 }
 
 static void
index a2d3beef2d9fe81867bc60be5b35a2cabcc95dde..73f85bf53500e1a6028a57d876b3e76589a6ca85 100644 (file)
@@ -38,6 +38,7 @@
 #include <isc/hmac.h>
 #include <isc/httpd.h>
 #include <isc/lex.h>
+#include <isc/loop.h>
 #include <isc/meminfo.h>
 #include <isc/netmgr.h>
 #include <isc/nonce.h>
@@ -1110,7 +1111,7 @@ configure_view_dnsseckeys(dns_view_t *view, const cfg_obj_t *vconfig,
                return (ISC_R_UNEXPECTED);
        }
 
-       result = dns_view_initntatable(view, named_g_taskmgr, named_g_timermgr);
+       result = dns_view_initntatable(view, named_g_taskmgr, named_g_loopmgr);
        if (result != ISC_R_SUCCESS) {
                isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
                              NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,
@@ -2489,8 +2490,8 @@ configure_rpz(dns_view_t *view, dns_view_t *pview, const cfg_obj_t **maps,
 #endif /* ifndef USE_DNSRPS */
 
        result = dns_rpz_new_zones(&view->rpzs, rps_cstr, rps_cstr_size,
-                                  view->mctx, named_g_taskmgr,
-                                  named_g_timermgr);
+                                  view->mctx, named_g_loopmgr,
+                                  named_g_taskmgr);
        if (result != ISC_R_SUCCESS) {
                return (result);
        }
@@ -3157,8 +3158,7 @@ configure_catz(dns_view_t *view, dns_view_t *pview, const cfg_obj_t *config,
        }
 
        CHECK(dns_catz_new_zones(&view->catzs, &ns_catz_zonemodmethods,
-                                view->mctx, named_g_taskmgr,
-                                named_g_timermgr));
+                                view->mctx, named_g_taskmgr, named_g_loopmgr));
 
        if (pview != NULL) {
                old = pview->catzs;
@@ -4703,9 +4703,8 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
                        isc_mem_create(&hmctx);
                        isc_mem_setname(hmctx, "cache_heap");
                        CHECK(dns_cache_create(cmctx, hmctx, named_g_taskmgr,
-                                              named_g_timermgr, view->rdclass,
-                                              cachename, "rbt", 0, NULL,
-                                              &cache));
+                                              view->rdclass, cachename, "rbt",
+                                              0, NULL, &cache));
                        isc_mem_detach(&cmctx);
                        isc_mem_detach(&hmctx);
                }
@@ -4751,7 +4750,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
 
        ndisp = 4 * ISC_MIN(named_g_udpdisp, MAX_UDP_DISPATCH);
        CHECK(dns_view_createresolver(
-               view, named_g_taskmgr, ndisp, named_g_netmgr, named_g_timermgr,
+               view, named_g_loopmgr, named_g_taskmgr, ndisp, named_g_netmgr,
                resopts, named_g_dispatchmgr, dispatch4, dispatch6));
 
        if (resstats == NULL) {
@@ -5658,7 +5657,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
                        CHECK(dns_dyndb_createctx(mctx, hashinit, named_g_lctx,
                                                  view, named_g_server->zonemgr,
                                                  named_g_server->task,
-                                                 named_g_timermgr, &dctx));
+                                                 named_g_loopmgr, &dctx));
                }
 
                CHECK(configure_dyndb(dyndb, mctx, dctx));
@@ -7048,22 +7047,17 @@ directory_callback(const char *clausename, const cfg_obj_t *obj, void *arg) {
  */
 
 static void
-interface_timer_tick(isc_task_t *task, isc_event_t *event) {
-       named_server_t *server = (named_server_t *)event->ev_arg;
-       INSIST(task == server->task);
-       UNUSED(task);
+interface_timer_tick(void *arg) {
+       named_server_t *server = (named_server_t *)arg;
 
-       isc_event_free(&event);
        ns_interfacemgr_scan(server->interfacemgr, false, false);
 }
 
 static void
-heartbeat_timer_tick(isc_task_t *task, isc_event_t *event) {
-       named_server_t *server = (named_server_t *)event->ev_arg;
-       dns_view_t *view;
+heartbeat_timer_tick(void *arg) {
+       named_server_t *server = (named_server_t *)arg;
+       dns_view_t *view = NULL;
 
-       UNUSED(task);
-       isc_event_free(&event);
        view = ISC_LIST_HEAD(server->viewlist);
        while (view != NULL) {
                dns_view_dialup(view);
@@ -7294,10 +7288,10 @@ dotat(dns_keytable_t *keytable, dns_keynode_t *keynode, dns_name_t *keyname,
       void *arg) {
        struct dotat_arg *dotat_arg = arg;
        isc_result_t result;
-       dns_view_t *view;
-       isc_task_t *task;
-       ns_tat_t *tat;
-       isc_event_t *event;
+       dns_view_t *view = NULL;
+       isc_task_t *task = NULL;
+       ns_tat_t *tat = NULL;
+       isc_event_t *event = NULL;
 
        REQUIRE(keytable != NULL);
        REQUIRE(keynode != NULL);
@@ -7307,11 +7301,8 @@ dotat(dns_keytable_t *keytable, dns_keynode_t *keynode, dns_name_t *keyname,
        task = dotat_arg->task;
 
        tat = isc_mem_get(dotat_arg->view->mctx, sizeof(*tat));
+       *tat = (ns_tat_t){ 0 };
 
-       tat->fetch = NULL;
-       tat->mctx = NULL;
-       tat->task = NULL;
-       tat->view = NULL;
        dns_rdataset_init(&tat->rdataset);
        dns_rdataset_init(&tat->sigrdataset);
        dns_name_copy(keyname, dns_fixedname_initname(&tat->keyname));
@@ -7345,15 +7336,13 @@ dotat(dns_keytable_t *keytable, dns_keynode_t *keynode, dns_name_t *keyname,
 }
 
 static void
-tat_timer_tick(isc_task_t *task, isc_event_t *event) {
+tat_timer_tick(void *arg) {
        isc_result_t result;
-       named_server_t *server = (named_server_t *)event->ev_arg;
-       struct dotat_arg arg;
-       dns_view_t *view;
+       named_server_t *server = (named_server_t *)arg;
+       struct dotat_arg dotat_arg = { 0 };
+       dns_view_t *view = NULL;
        dns_keytable_t *secroots = NULL;
 
-       isc_event_free(&event);
-
        for (view = ISC_LIST_HEAD(server->viewlist); view != NULL;
             view = ISC_LIST_NEXT(view, link))
        {
@@ -7366,20 +7355,19 @@ tat_timer_tick(isc_task_t *task, isc_event_t *event) {
                        continue;
                }
 
-               arg.view = view;
-               arg.task = task;
-               (void)dns_keytable_forall(secroots, dotat, &arg);
+               dotat_arg.view = view;
+               dotat_arg.task = server->task;
+               (void)dns_keytable_forall(secroots, dotat, &dotat_arg);
                dns_keytable_detach(&secroots);
        }
 }
 
 static void
-pps_timer_tick(isc_task_t *task, isc_event_t *event) {
+pps_timer_tick(void *arg) {
        static unsigned int oldrequests = 0;
        unsigned int requests = atomic_load_relaxed(&ns_client_requests);
 
-       UNUSED(task);
-       isc_event_free(&event);
+       UNUSED(arg);
 
        /*
         * Don't worry about wrapping as the overflow result will be right.
@@ -9004,17 +8992,13 @@ load_configuration(const char *filename, named_server_t *server,
        result = named_config_get(maps, "interface-interval", &obj);
        INSIST(result == ISC_R_SUCCESS);
        interface_interval = cfg_obj_asduration(obj);
-
        if (server->interface_timer != NULL) {
                if (interface_interval == 0) {
-                       CHECK(isc_timer_reset(server->interface_timer,
-                                             isc_timertype_inactive, NULL,
-                                             true));
+                       isc_timer_stop(server->interface_timer);
                } else if (server->interface_interval != interface_interval) {
                        isc_interval_set(&interval, interface_interval, 0);
-                       CHECK(isc_timer_reset(server->interface_timer,
-                                             isc_timertype_ticker, &interval,
-                                             false));
+                       isc_timer_start(server->interface_timer,
+                                       isc_timertype_ticker, &interval);
                }
        }
        server->interface_interval = interface_interval;
@@ -9035,22 +9019,19 @@ load_configuration(const char *filename, named_server_t *server,
        INSIST(result == ISC_R_SUCCESS);
        heartbeat_interval = cfg_obj_asuint32(obj) * 60;
        if (heartbeat_interval == 0) {
-               CHECK(isc_timer_reset(server->heartbeat_timer,
-                                     isc_timertype_inactive, NULL, true));
+               isc_timer_stop(server->heartbeat_timer);
        } else if (server->heartbeat_interval != heartbeat_interval) {
                isc_interval_set(&interval, heartbeat_interval, 0);
-               CHECK(isc_timer_reset(server->heartbeat_timer,
-                                     isc_timertype_ticker, &interval, false));
+               isc_timer_start(server->heartbeat_timer, isc_timertype_ticker,
+                               &interval);
        }
        server->heartbeat_interval = heartbeat_interval;
 
        isc_interval_set(&interval, 1200, 0);
-       CHECK(isc_timer_reset(server->pps_timer, isc_timertype_ticker,
-                             &interval, false));
+       isc_timer_start(server->pps_timer, isc_timertype_ticker, &interval);
 
        isc_interval_set(&interval, named_g_tat_interval, 0);
-       CHECK(isc_timer_reset(server->tat_timer, isc_timertype_ticker,
-                             &interval, false));
+       isc_timer_start(server->tat_timer, isc_timertype_ticker, &interval);
 
        /*
         * Write the PID file.
@@ -9856,11 +9837,10 @@ run_server(isc_task_t *task, isc_event_t *event) {
        geoip = NULL;
 #endif /* if defined(HAVE_GEOIP2) */
 
-       CHECKFATAL(ns_interfacemgr_create(named_g_mctx, server->sctx,
-                                         named_g_taskmgr, named_g_timermgr,
-                                         named_g_netmgr, named_g_dispatchmgr,
-                                         server->task, geoip, true,
-                                         &server->interfacemgr),
+       CHECKFATAL(ns_interfacemgr_create(
+                          named_g_mctx, server->sctx, named_g_taskmgr,
+                          named_g_loopmgr, named_g_netmgr, named_g_dispatchmgr,
+                          server->task, geoip, true, &server->interfacemgr),
                   "creating interface manager");
 
        /*
@@ -9876,18 +9856,17 @@ run_server(isc_task_t *task, isc_event_t *event) {
                              NAMED_LOGMODULE_SERVER, ISC_LOG_INFO,
                              "Disabling periodic interface re-scans timer");
        } else {
-               isc_timer_create(named_g_timermgr, server->task,
-                                interface_timer_tick, server,
+               isc_timer_create(named_g_mainloop, interface_timer_tick, server,
                                 &server->interface_timer);
        }
 
-       isc_timer_create(named_g_timermgr, server->task, heartbeat_timer_tick,
-                        server, &server->heartbeat_timer);
+       isc_timer_create(named_g_mainloop, heartbeat_timer_tick, server,
+                        &server->heartbeat_timer);
 
-       isc_timer_create(named_g_timermgr, server->task, tat_timer_tick, server,
+       isc_timer_create(named_g_mainloop, tat_timer_tick, server,
                         &server->tat_timer);
 
-       isc_timer_create(named_g_timermgr, server->task, pps_timer_tick, server,
+       isc_timer_create(named_g_mainloop, pps_timer_tick, server,
                         &server->pps_timer);
 
        CHECKFATAL(
@@ -10124,6 +10103,8 @@ named_server_create(isc_mem_t *mctx, named_server_t **serverp) {
        server->sctx->fuzznotify = named_fuzz_notify;
 #endif /* ifdef ENABLE_AFL */
 
+       named_g_mainloop = isc_loop_main(named_g_loopmgr);
+
        CHECKFATAL(
                isc_app_onrun(named_g_mctx, server->task, run_server, server),
                "isc_app_onrun");
@@ -10136,8 +10117,8 @@ named_server_create(isc_mem_t *mctx, named_server_t **serverp) {
        server->interface_interval = 0;
        server->heartbeat_interval = 0;
 
-       CHECKFATAL(dns_zonemgr_create(named_g_mctx, named_g_taskmgr,
-                                     named_g_timermgr, named_g_netmgr,
+       CHECKFATAL(dns_zonemgr_create(named_g_mctx, named_g_loopmgr,
+                                     named_g_taskmgr, named_g_netmgr,
                                      &server->zonemgr),
                   "dns_zonemgr_create");
 
index b57fe20bb2705e8a2b43695cb5d3934e9a130213..fe3a7d1ce8eb56531589d74254997b94f838b3c5 100644 (file)
@@ -125,6 +125,7 @@ static bool use_win2k_gsstsig = false;
 static bool tried_other_gsstsig = false;
 static bool local_only = false;
 static isc_nm_t *netmgr = NULL;
+static isc_loopmgr_t *loopmgr = NULL;
 static isc_taskmgr_t *taskmgr = NULL;
 static isc_task_t *global_task = NULL;
 static isc_event_t *global_event = NULL;
@@ -905,7 +906,7 @@ setup_system(void) {
 
        irs_resconf_destroy(&resconf);
 
-       result = isc_managers_create(gmctx, 1, 0, &netmgr, &taskmgr, NULL);
+       result = isc_managers_create(gmctx, 1, 0, &loopmgr, &netmgr, &taskmgr);
        check_result(result, "isc_managers_create");
 
        result = dns_dispatchmgr_create(gmctx, netmgr, &dispatchmgr);
@@ -3277,7 +3278,7 @@ cleanup(void) {
        UNLOCK(&answer_lock);
 
        ddebug("Shutting down managers");
-       isc_managers_destroy(&netmgr, &taskmgr, NULL);
+       isc_managers_destroy(&loopmgr, &netmgr, &taskmgr);
 
 #if HAVE_GSSAPI
        if (tsigkey != NULL) {
index bd9afeac1a0081d7a8a7a57a95247f74e4fdc0e7..50de03175ba7f7ac7cc743508d5c9ad8bab76c08 100644 (file)
@@ -22,6 +22,7 @@
 #include <isc/attributes.h>
 #include <isc/buffer.h>
 #include <isc/commandline.h>
+#include <isc/event.h>
 #include <isc/file.h>
 #include <isc/log.h>
 #include <isc/managers.h>
@@ -60,6 +61,7 @@ const char *progname = NULL;
 bool verbose;
 
 static isc_nm_t *netmgr = NULL;
+static isc_loopmgr_t *loopmgr = NULL;
 static isc_taskmgr_t *taskmgr = NULL;
 static isc_task_t *rndc_task = NULL;
 
@@ -1027,7 +1029,7 @@ main(int argc, char **argv) {
        serial = isc_random32();
 
        isc_mem_create(&rndc_mctx);
-       isc_managers_create(rndc_mctx, 1, 0, &netmgr, &taskmgr, NULL);
+       isc_managers_create(rndc_mctx, 1, 0, &loopmgr, &netmgr, &taskmgr);
        DO("create task", isc_task_create(taskmgr, 0, &rndc_task, 0));
        isc_log_create(rndc_mctx, &log, &logconfig);
        isc_log_setcontext(log);
@@ -1082,7 +1084,7 @@ main(int argc, char **argv) {
        }
 
        isc_task_detach(&rndc_task);
-       isc_managers_destroy(&netmgr, &taskmgr, NULL);
+       isc_managers_destroy(&loopmgr, &netmgr, &taskmgr);
 
        /*
         * Note: when TCP connections are shut down, there will be a final
index c7615e27d993c06a403fdf164c178bd82a2690c8..45afc4c371231981609de3ea2610645497f09409 100644 (file)
@@ -52,6 +52,7 @@ static const char *protocols[] = { "udp",         "tcp",
 
 static isc_mem_t *mctx = NULL;
 static isc_nm_t *netmgr = NULL;
+static isc_loopmgr_t *loopmgr = NULL;
 
 static protocol_t protocol;
 static const char *address;
@@ -308,7 +309,7 @@ setup(void) {
 
        isc_mem_create(&mctx);
 
-       isc_managers_create(mctx, workers, 0, &netmgr, NULL, NULL);
+       isc_managers_create(mctx, workers, 0, &loopmgr, &netmgr, NULL);
 }
 
 static void
@@ -317,7 +318,7 @@ teardown(void) {
                close(out);
        }
 
-       isc_managers_destroy(&netmgr, NULL, NULL);
+       isc_managers_destroy(&loopmgr, &netmgr, NULL);
        isc_mem_destroy(&mctx);
        if (tls_ctx) {
                isc_tlsctx_free(&tls_ctx);
index 728927e355568d0f91d1434b11cc80982ff70d75..3c3159024446ef1fb9089403ce5b126307a4b98b 100644 (file)
@@ -34,6 +34,7 @@ static const char *protocols[] = { "udp", "tcp", "dot", "https", "http-plain" };
 
 static isc_mem_t *mctx = NULL;
 static isc_nm_t *netmgr = NULL;
+static isc_loopmgr_t *loopmgr = NULL;
 
 static protocol_t protocol;
 static in_port_t port;
@@ -189,12 +190,12 @@ setup(void) {
 
        isc_mem_create(&mctx);
 
-       isc_managers_create(mctx, workers, 0, &netmgr, NULL, NULL);
+       isc_managers_create(mctx, workers, 0, &loopmgr, &netmgr, NULL);
 }
 
 static void
 teardown(void) {
-       isc_managers_destroy(&netmgr, NULL, NULL);
+       isc_managers_destroy(&loopmgr, &netmgr, NULL);
        isc_mem_destroy(&mctx);
        if (tls_ctx) {
                isc_tlsctx_free(&tls_ctx);
index ad4139ffee35d986ae747ef2d746d2a811a736c0..eb72c62f08e29de77b3ae3ac2cf49e26b1826e01 100644 (file)
@@ -2103,6 +2103,7 @@ main(int argc, char *argv[]) {
        isc_sockaddr_t bind_any;
        isc_log_t *lctx = NULL;
        isc_logconfig_t *lcfg = NULL;
+       isc_loopmgr_t *loopmgr = NULL;
        isc_nm_t *netmgr = NULL;
        isc_taskmgr_t *taskmgr = NULL;
        isc_task_t *task = NULL;
@@ -2156,7 +2157,7 @@ main(int argc, char *argv[]) {
                fatal("can't choose between IPv4 and IPv6");
        }
 
-       isc_managers_create(mctx, 1, 0, &netmgr, &taskmgr, NULL);
+       isc_managers_create(mctx, 1, 0, &loopmgr, &netmgr, &taskmgr);
        RUNCHECK(isc_task_create(taskmgr, 0, &task, 0));
        RUNCHECK(dns_dispatchmgr_create(mctx, netmgr, &dispatchmgr));
 
@@ -2217,7 +2218,7 @@ main(int argc, char *argv[]) {
 
        isc_task_detach(&task);
 
-       isc_managers_destroy(&netmgr, &taskmgr, NULL);
+       isc_managers_destroy(&loopmgr, &netmgr, &taskmgr);
 
        dst_lib_destroy();
 
index 011338e9977703a97678f7f9b3b94a12cfcb36a4..6c856d0a1690856ed1e406f477f9f64c1af9c33f 100644 (file)
@@ -16,6 +16,7 @@
 #include <inttypes.h>
 #include <stdbool.h>
 
+#include <isc/event.h>
 #include <isc/mem.h>
 #include <isc/print.h>
 #include <isc/refcount.h>
@@ -152,7 +153,7 @@ struct dns_cache {
 
 static isc_result_t
 cache_cleaner_init(dns_cache_t *cache, isc_taskmgr_t *taskmgr,
-                  isc_timermgr_t *timermgr, cache_cleaner_t *cleaner);
+                  cache_cleaner_t *cleaner);
 
 static void
 incremental_cleaning_action(isc_task_t *task, isc_event_t *event);
@@ -180,9 +181,9 @@ cache_create_db(dns_cache_t *cache, dns_db_t **db) {
 
 isc_result_t
 dns_cache_create(isc_mem_t *cmctx, isc_mem_t *hmctx, isc_taskmgr_t *taskmgr,
-                isc_timermgr_t *timermgr, dns_rdataclass_t rdclass,
-                const char *cachename, const char *db_type,
-                unsigned int db_argc, char **db_argv, dns_cache_t **cachep) {
+                dns_rdataclass_t rdclass, const char *cachename,
+                const char *db_type, unsigned int db_argc, char **db_argv,
+                dns_cache_t **cachep) {
        isc_result_t result;
        dns_cache_t *cache;
        int i, extra = 0;
@@ -275,10 +276,9 @@ dns_cache_create(isc_mem_t *cmctx, isc_mem_t *hmctx, isc_taskmgr_t *taskmgr,
         * need the control of the generic cleaner.
         */
        if (strcmp(db_type, "rbt") == 0) {
-               result = cache_cleaner_init(cache, NULL, NULL, &cache->cleaner);
+               result = cache_cleaner_init(cache, NULL, &cache->cleaner);
        } else {
-               result = cache_cleaner_init(cache, taskmgr, timermgr,
-                                           &cache->cleaner);
+               result = cache_cleaner_init(cache, taskmgr, &cache->cleaner);
        }
        if (result != ISC_R_SUCCESS) {
                goto cleanup_db;
@@ -447,7 +447,7 @@ dns_cache_getname(dns_cache_t *cache) {
 
 static isc_result_t
 cache_cleaner_init(dns_cache_t *cache, isc_taskmgr_t *taskmgr,
-                  isc_timermgr_t *timermgr, cache_cleaner_t *cleaner) {
+                  cache_cleaner_t *cleaner) {
        isc_result_t result;
 
        isc_mutex_init(&cleaner->lock);
@@ -469,7 +469,7 @@ cache_cleaner_init(dns_cache_t *cache, isc_taskmgr_t *taskmgr,
                goto cleanup;
        }
 
-       if (taskmgr != NULL && timermgr != NULL) {
+       if (taskmgr != NULL) {
                result = isc_task_create(taskmgr, 1, &cleaner->task, 0);
                if (result != ISC_R_SUCCESS) {
                        UNEXPECTED_ERROR(__FILE__, __LINE__,
index 8cf4e1cb9383db52cd79bd1b9b610bf9319f847a..e53df3b7fa859df92efcaaf22e43c4256afbad65 100644 (file)
@@ -17,6 +17,7 @@
 #include <stdbool.h>
 
 #include <isc/hex.h>
+#include <isc/loop.h>
 #include <isc/md.h>
 #include <isc/mem.h>
 #include <isc/parseint.h>
@@ -90,7 +91,6 @@ struct dns_catz_zone {
        dns_dbversion_t *dbversion;
 
        isc_timer_t *updatetimer;
-       isc_event_t updateevent;
 
        bool active;
        bool db_registered;
@@ -122,7 +122,7 @@ struct dns_catz_zones {
        isc_mutex_t lock;
        dns_catz_zonemodmethods_t *zmm;
        isc_taskmgr_t *taskmgr;
-       isc_timermgr_t *timermgr;
+       isc_loopmgr_t *loopmgr;
        dns_view_t *view;
        isc_task_t *updater;
 };
@@ -711,7 +711,7 @@ dns_catz_zones_merge(dns_catz_zone_t *target, dns_catz_zone_t *newzone) {
 isc_result_t
 dns_catz_new_zones(dns_catz_zones_t **catzsp, dns_catz_zonemodmethods_t *zmm,
                   isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
-                  isc_timermgr_t *timermgr) {
+                  isc_loopmgr_t *loopmgr) {
        dns_catz_zones_t *new_zones;
        isc_result_t result;
 
@@ -729,7 +729,7 @@ dns_catz_new_zones(dns_catz_zones_t **catzsp, dns_catz_zonemodmethods_t *zmm,
 
        isc_mem_attach(mctx, &new_zones->mctx);
        new_zones->zmm = zmm;
-       new_zones->timermgr = timermgr;
+       new_zones->loopmgr = loopmgr;
        new_zones->taskmgr = taskmgr;
 
        result = isc_task_create(taskmgr, 0, &new_zones->updater, 0);
@@ -780,7 +780,7 @@ dns_catz_new_zone(dns_catz_zones_t *catzs, dns_catz_zone_t **zonep,
        isc_ht_init(&new_zone->coos, catzs->mctx, 4, ISC_HT_CASE_INSENSITIVE);
 
        new_zone->updatetimer = NULL;
-       isc_timer_create(catzs->timermgr, catzs->updater,
+       isc_timer_create(isc_loop_main(catzs->loopmgr),
                         dns_catz_update_taskaction, new_zone,
                         &new_zone->updatetimer);
 
@@ -1981,22 +1981,16 @@ cleanup:
 }
 
 void
-dns_catz_update_taskaction(isc_task_t *task, isc_event_t *event) {
+dns_catz_update_taskaction(void *arg) {
        isc_result_t result;
-       dns_catz_zone_t *zone;
-       (void)task;
+       dns_catz_zone_t *zone = arg;
 
-       REQUIRE(event != NULL);
-       zone = event->ev_arg;
        REQUIRE(DNS_CATZ_ZONE_VALID(zone));
 
        LOCK(&zone->catzs->lock);
        zone->updatepending = false;
        dns_catz_update_from_db(zone->db, zone->catzs);
-       result = isc_timer_reset(zone->updatetimer, isc_timertype_inactive,
-                                NULL, true);
-       RUNTIME_CHECK(result == ISC_R_SUCCESS);
-       isc_event_free(&event);
+       isc_timer_stop(zone->updatetimer);
        result = isc_time_now(&zone->lastupdated);
        RUNTIME_CHECK(result == ISC_R_SUCCESS);
        UNLOCK(&zone->catzs->lock);
@@ -2040,11 +2034,11 @@ dns_catz_dbupdate_callback(dns_db_t *db, void *fn_arg) {
        }
 
        if (!zone->updatepending) {
+               isc_interval_t interval;
                zone->updatepending = true;
                isc_time_now(&now);
                tdiff = isc_time_microdiff(&now, &zone->lastupdated) / 1000000;
                if (tdiff < zone->defoptions.min_update_interval) {
-                       isc_interval_t interval;
                        isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
                                      DNS_LOGMODULE_MASTER, ISC_LOG_INFO,
                                      "catz: new zone version came too soon, "
@@ -2053,25 +2047,12 @@ dns_catz_dbupdate_callback(dns_db_t *db, void *fn_arg) {
                                         zone->defoptions.min_update_interval -
                                                 (unsigned int)tdiff,
                                         0);
-                       dns_db_currentversion(db, &zone->dbversion);
-                       result = isc_timer_reset(zone->updatetimer,
-                                                isc_timertype_once, &interval,
-                                                true);
-                       if (result != ISC_R_SUCCESS) {
-                               goto cleanup;
-                       }
                } else {
-                       isc_event_t *event;
-
-                       dns_db_currentversion(db, &zone->dbversion);
-                       ISC_EVENT_INIT(&zone->updateevent,
-                                      sizeof(zone->updateevent), 0,
-                                      DNS_EVENT_CATZUPDATED,
-                                      dns_catz_update_taskaction, zone, zone,
-                                      NULL, NULL);
-                       event = &zone->updateevent;
-                       isc_task_send(catzs->updater, &event);
+                       isc_interval_set(&interval, 0, 0);
                }
+               dns_db_currentversion(db, &zone->dbversion);
+               isc_timer_start(zone->updatetimer, isc_timertype_once,
+                               &interval);
        } else {
                isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
                              DNS_LOGMODULE_MASTER, ISC_LOG_DEBUG(3),
index 586be89103af16afe3190ae07a56e7f493af0343..af34beba05510872fcf9884906656a127f99049f 100644 (file)
@@ -25,7 +25,6 @@
 #include <isc/safe.h>
 #include <isc/sockaddr.h>
 #include <isc/task.h>
-#include <isc/timer.h>
 #include <isc/util.h>
 
 #include <dns/adb.h>
@@ -84,7 +83,7 @@ struct dns_client {
        isc_taskmgr_t *taskmgr;
        isc_task_t *task;
        isc_nm_t *nm;
-       isc_timermgr_t *timermgr;
+       isc_loopmgr_t *loopmgr;
        dns_dispatchmgr_t *dispatchmgr;
        dns_dispatch_t *dispatchv4;
        dns_dispatch_t *dispatchv6;
@@ -219,9 +218,9 @@ getudpdispatch(int family, dns_dispatchmgr_t *dispatchmgr,
 
 static isc_result_t
 createview(isc_mem_t *mctx, dns_rdataclass_t rdclass, isc_taskmgr_t *taskmgr,
-          isc_nm_t *nm, isc_timermgr_t *timermgr,
-          dns_dispatchmgr_t *dispatchmgr, dns_dispatch_t *dispatchv4,
-          dns_dispatch_t *dispatchv6, dns_view_t **viewp) {
+          isc_nm_t *nm, isc_loopmgr_t *loopmgr, dns_dispatchmgr_t *dispatchmgr,
+          dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6,
+          dns_view_t **viewp) {
        isc_result_t result;
        dns_view_t *view = NULL;
 
@@ -237,7 +236,7 @@ createview(isc_mem_t *mctx, dns_rdataclass_t rdclass, isc_taskmgr_t *taskmgr,
                return (result);
        }
 
-       result = dns_view_createresolver(view, taskmgr, 1, nm, timermgr, 0,
+       result = dns_view_createresolver(view, loopmgr, taskmgr, 1, nm, 0,
                                         dispatchmgr, dispatchv4, dispatchv6);
        if (result != ISC_R_SUCCESS) {
                dns_view_detach(&view);
@@ -256,8 +255,8 @@ createview(isc_mem_t *mctx, dns_rdataclass_t rdclass, isc_taskmgr_t *taskmgr,
 }
 
 isc_result_t
-dns_client_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, isc_nm_t *nm,
-                 isc_timermgr_t *timermgr, unsigned int options,
+dns_client_create(isc_mem_t *mctx, isc_loopmgr_t *loopmgr,
+                 isc_taskmgr_t *taskmgr, isc_nm_t *nm, unsigned int options,
                  dns_client_t **clientp, const isc_sockaddr_t *localaddr4,
                  const isc_sockaddr_t *localaddr6) {
        isc_result_t result;
@@ -268,7 +267,7 @@ dns_client_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, isc_nm_t *nm,
 
        REQUIRE(mctx != NULL);
        REQUIRE(taskmgr != NULL);
-       REQUIRE(timermgr != NULL);
+       REQUIRE(loopmgr != NULL);
        REQUIRE(nm != NULL);
        REQUIRE(clientp != NULL && *clientp == NULL);
 
@@ -277,7 +276,7 @@ dns_client_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, isc_nm_t *nm,
        client = isc_mem_get(mctx, sizeof(*client));
        *client = (dns_client_t){
                .taskmgr = taskmgr,
-               .timermgr = timermgr,
+               .loopmgr = loopmgr,
                .nm = nm,
        };
 
@@ -328,7 +327,7 @@ dns_client_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, isc_nm_t *nm,
        isc_refcount_init(&client->references, 1);
 
        /* Create the default view for class IN */
-       result = createview(mctx, dns_rdataclass_in, taskmgr, nm, timermgr,
+       result = createview(mctx, dns_rdataclass_in, taskmgr, nm, loopmgr,
                            client->dispatchmgr, dispatchv4, dispatchv6, &view);
        if (result != ISC_R_SUCCESS) {
                goto cleanup_references;
index 253d58f9fe22a7bcf22ff01222f66b4030976365..08ff0ffba03eec9857b50d2d830b92686ddb0aff 100644 (file)
@@ -268,7 +268,7 @@ dns_dyndb_cleanup(bool exiting) {
 isc_result_t
 dns_dyndb_createctx(isc_mem_t *mctx, const void *hashinit, isc_log_t *lctx,
                    dns_view_t *view, dns_zonemgr_t *zmgr, isc_task_t *task,
-                   isc_timermgr_t *tmgr, dns_dyndbctx_t **dctxp) {
+                   isc_loopmgr_t *loopmgr, dns_dyndbctx_t **dctxp) {
        dns_dyndbctx_t *dctx;
 
        REQUIRE(dctxp != NULL && *dctxp == NULL);
@@ -285,7 +285,7 @@ dns_dyndb_createctx(isc_mem_t *mctx, const void *hashinit, isc_log_t *lctx,
        if (task != NULL) {
                isc_task_attach(task, &dctx->task);
        }
-       dctx->timermgr = tmgr;
+       dctx->loopmgr = loopmgr;
        dctx->hashinit = hashinit;
        dctx->lctx = lctx;
        dctx->refvar = &isc_bind9;
@@ -318,7 +318,7 @@ dns_dyndb_destroyctx(dns_dyndbctx_t **dctxp) {
        if (dctx->task != NULL) {
                isc_task_detach(&dctx->task);
        }
-       dctx->timermgr = NULL;
+       dctx->loopmgr = NULL;
        dctx->lctx = NULL;
 
        isc_mem_putanddetach(&dctx->mctx, dctx, sizeof(*dctx));
index 8fc96574d80fd03e04d31a8979ce18d42a02bcc4..d7697ab7b9dfac00a34a48f889cf5c7380f15fb4 100644 (file)
@@ -57,9 +57,9 @@ ISC_LANG_BEGINDECLS
  ***/
 isc_result_t
 dns_cache_create(isc_mem_t *cmctx, isc_mem_t *hmctx, isc_taskmgr_t *taskmgr,
-                isc_timermgr_t *timermgr, dns_rdataclass_t rdclass,
-                const char *cachename, const char *db_type,
-                unsigned int db_argc, char **db_argv, dns_cache_t **cachep);
+                dns_rdataclass_t rdclass, const char *cachename,
+                const char *db_type, unsigned int db_argc, char **db_argv,
+                dns_cache_t **cachep);
 /*%<
  * Create a new DNS cache.
  *
@@ -77,9 +77,8 @@ dns_cache_create(isc_mem_t *cmctx, isc_mem_t *hmctx, isc_taskmgr_t *taskmgr,
  *
  *\li  'cmctx' (and 'hmctx' if applicable) is a valid memory context.
  *
- *\li  'taskmgr' is a valid task manager and 'timermgr' is a valid timer
- *     manager, or both are NULL.  If NULL, no periodic cleaning of the
- *     cache will take place.
+ *\li  'taskmgr' is a valid task manager or are NULL.  If NULL, no periodic
+ *      cleaning of the cache will take place.
  *
  *\li  'cachename' is a valid string.  This must not be NULL.
  *
index 9c74e155846c7fa24ef89ed85cb8ec9b5ab6a63a..68da93d8fdd0f9453246650e6ddfcc7414baca81 100644 (file)
@@ -336,7 +336,7 @@ struct dns_catz_zonemodmethods {
 isc_result_t
 dns_catz_new_zones(dns_catz_zones_t **catzsp, dns_catz_zonemodmethods_t *zmm,
                   isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
-                  isc_timermgr_t *timermgr);
+                  isc_loopmgr_t *loopmgr);
 /*%<
  * Allocate a new catz_zones object, a collection storing all catalog zones
  * for a view.
@@ -415,7 +415,7 @@ dns_catz_dbupdate_callback(dns_db_t *db, void *fn_arg);
  */
 
 void
-dns_catz_update_taskaction(isc_task_t *task, isc_event_t *event);
+dns_catz_update_taskaction(void *arg);
 /*%<
  * Task that launches dns_catz_update_from_db.
  *
index f2cf41def3781a9130b3785df4d1a6e76c3582c0..19ca2e00620ccc60e3cc12125f231e5ee117dd52 100644 (file)
@@ -89,8 +89,8 @@ typedef struct dns_clientresevent {
 } dns_clientresevent_t; /* too long? */
 
 isc_result_t
-dns_client_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, isc_nm_t *nm,
-                 isc_timermgr_t *timermgr, unsigned int options,
+dns_client_create(isc_mem_t *mctx, isc_loopmgr_t *loopmgr,
+                 isc_taskmgr_t *taskmgr, isc_nm_t *nm, unsigned int options,
                  dns_client_t **clientp, const isc_sockaddr_t *localaddr4,
                  const isc_sockaddr_t *localaddr6);
 /*%<
@@ -113,7 +113,7 @@ dns_client_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, isc_nm_t *nm,
  *
  *\li  'nm' is a valid network manager.
  *
- *\li  'timermgr' is a valid timer manager.
+ *\li  'loopmgr' is a valid loop manager.
  *
  *\li  clientp != NULL && *clientp == NULL.
  *
index a219cb9158f84b04eab32613b86bfdaf7d588252..b8490d5f373505bce0cb37cfb4c5438e9990d246 100644 (file)
@@ -33,15 +33,15 @@ ISC_LANG_BEGINDECLS
  * function should detach from them.
  */
 struct dns_dyndbctx {
-       unsigned int    magic;
-       const void     *hashinit;
-       isc_mem_t      *mctx;
-       isc_log_t      *lctx;
-       dns_view_t     *view;
-       dns_zonemgr_t  *zmgr;
-       isc_task_t     *task;
-       isc_timermgr_t *timermgr;
-       const bool     *refvar;
+       unsigned int   magic;
+       const void    *hashinit;
+       isc_mem_t     *mctx;
+       isc_log_t     *lctx;
+       dns_view_t    *view;
+       dns_zonemgr_t *zmgr;
+       isc_task_t    *task;
+       isc_loopmgr_t *loopmgr;
+       const bool    *refvar;
 };
 
 #define DNS_DYNDBCTX_MAGIC    ISC_MAGIC('D', 'd', 'b', 'c')
@@ -134,7 +134,7 @@ dns_dyndb_cleanup(bool exiting);
 isc_result_t
 dns_dyndb_createctx(isc_mem_t *mctx, const void *hashinit, isc_log_t *lctx,
                    dns_view_t *view, dns_zonemgr_t *zmgr, isc_task_t *task,
-                   isc_timermgr_t *tmgr, dns_dyndbctx_t **dctxp);
+                   isc_loopmgr_t *loopmgr, dns_dyndbctx_t **dctxp);
 /*%
  * Create a dyndb initialization context structure, with
  * pointers to structures in the server that the dyndb module will
index eb3f0dce691eaa93ed2c3f3b4ee735ecf55f1d3f..aacbef1608ab35787b92b4db7ddeae5299ea197a 100644 (file)
@@ -45,12 +45,12 @@ ISC_LANG_BEGINDECLS
 
 struct dns_ntatable {
        /* Unlocked. */
-       unsigned int    magic;
-       dns_view_t     *view;
-       isc_rwlock_t    rwlock;
-       isc_taskmgr_t  *taskmgr;
-       isc_timermgr_t *timermgr;
-       isc_task_t     *task;
+       unsigned int   magic;
+       dns_view_t    *view;
+       isc_rwlock_t   rwlock;
+       isc_taskmgr_t *taskmgr;
+       isc_loopmgr_t *loopmgr;
+       isc_task_t    *task;
        /* Protected by atomics */
        isc_refcount_t references;
        /* Locked by rwlock. */
@@ -63,7 +63,7 @@ struct dns_ntatable {
 
 isc_result_t
 dns_ntatable_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
-                   isc_timermgr_t *timermgr, dns_ntatable_t **ntatablep);
+                   isc_loopmgr_t *loopmgr, dns_ntatable_t **ntatablep);
 /*%<
  * Create an NTA table in view 'view'.
  *
index a9c2ce953fa5858ef334628ae9c9d368d520692f..2046f9421a208f8baee2bf4c2ae94dff9fe576a6 100644 (file)
@@ -164,8 +164,8 @@ typedef enum { dns_quotatype_zone = 0, dns_quotatype_server } dns_quotatype_t;
 #define DNS_MAX_LABELS            127
 
 isc_result_t
-dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
-                   unsigned int ndisp, isc_nm_t *nm, isc_timermgr_t *timermgr,
+dns_resolver_create(dns_view_t *view, isc_loopmgr_t *loopmgr,
+                   isc_taskmgr_t *taskmgr, unsigned int ndisp, isc_nm_t *nm,
                    unsigned int options, dns_dispatchmgr_t *dispatchmgr,
                    dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6,
                    dns_resolver_t **resp);
@@ -188,8 +188,6 @@ dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
  *
  *\li  'nm' is a valid network manager.
  *
- *\li  'timermgr' is a valid timer manager.
- *
  *\li  'dispatchv4' is a dispatch with an IPv4 UDP socket, or is NULL.
  *     If not NULL, 'ndisp' clones of it will be created by the resolver.
  *
index c0acc11ba0cad1827758212d78ba8589a233ec76..c46168d5383a6dec3644a683141297e9e1d81893 100644 (file)
@@ -160,7 +160,6 @@ struct dns_rpz_zone {
                                         * on */
        bool         addsoa;            /* add soa to the additional section */
        isc_timer_t *updatetimer;
-       isc_event_t  updateevent;
 };
 
 /*
@@ -247,12 +246,12 @@ struct dns_rpz_zones {
         */
        dns_rpz_triggers_t total_triggers;
 
-       isc_mem_t      *mctx;
-       isc_taskmgr_t  *taskmgr;
-       isc_timermgr_t *timermgr;
-       isc_task_t     *updater;
-       isc_refcount_t  refs;
-       isc_refcount_t  irefs;
+       isc_mem_t     *mctx;
+       isc_loopmgr_t *loopmgr;
+       isc_taskmgr_t *taskmgr;
+       isc_task_t    *updater;
+       isc_refcount_t refs;
+       isc_refcount_t irefs;
        /*
         * One lock for short term read-only search that guarantees the
         * consistency of the pointers.
@@ -386,8 +385,8 @@ dns_rpz_decode_cname(dns_rpz_zone_t *rpz, dns_rdataset_t *rdataset,
 
 isc_result_t
 dns_rpz_new_zones(dns_rpz_zones_t **rpzsp, char *rps_cstr, size_t rps_cstr_size,
-                 isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
-                 isc_timermgr_t *timermgr);
+                 isc_mem_t *mctx, isc_loopmgr_t *loopmgr,
+                 isc_taskmgr_t *taskmgr);
 
 isc_result_t
 dns_rpz_new_zone(dns_rpz_zones_t *rpzs, dns_rpz_zone_t **rpzp);
index 7a9a48c26927bf77368c02f8798846fa9d1ac9f4..fc2ce99beacc07d64b90c131048100a60655b8a9 100644 (file)
@@ -385,9 +385,9 @@ dns_view_createzonetable(dns_view_t *view);
  */
 
 isc_result_t
-dns_view_createresolver(dns_view_t *view, isc_taskmgr_t *taskmgr,
-                       unsigned int ndisp, isc_nm_t *nm,
-                       isc_timermgr_t *timermgr, unsigned int options,
+dns_view_createresolver(dns_view_t *view, isc_loopmgr_t *loopmgr,
+                       isc_taskmgr_t *taskmgr, unsigned int ndisp,
+                       isc_nm_t *netmgr, unsigned int options,
                        dns_dispatchmgr_t *dispatchmgr,
                        dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6);
 /*%<
@@ -400,8 +400,7 @@ dns_view_createresolver(dns_view_t *view, isc_taskmgr_t *taskmgr,
  *\li  'view' does not have a resolver already.
  *
  *\li  The requirements of dns_resolver_create() apply to 'taskmgr',
- *     'ntasks', 'nm', 'timermgr', 'options', 'dispatchv4', and
- *     'dispatchv6'.
+ *     'ndisp', 'netmgr', 'options', 'dispatchv4', and 'dispatchv6'.
  *
  * Returns:
  *
@@ -1006,7 +1005,7 @@ dns_view_iscacheshared(dns_view_t *view);
 
 isc_result_t
 dns_view_initntatable(dns_view_t *view, isc_taskmgr_t *taskmgr,
-                     isc_timermgr_t *timermgr);
+                     isc_loopmgr_t *loopmgr);
 /*%<
  * Initialize the negative trust anchor table for the view.
  *
index 0f035cf5a8c22eed735e97f1d96dcfad78fa52fa..616bf4dd115c999b44bc0939e0d2cdc1213f2793 100644 (file)
@@ -632,16 +632,6 @@ dns_zone_dumptostream(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
  *\li  'fd' to be a stream open for writing.
  */
 
-void
-dns_zone_maintenance(dns_zone_t *zone);
-/*%<
- *     Perform regular maintenance on the zone.  This is called as a
- *     result of a zone being managed.
- *
- * Require
- *\li  'zone' to be a valid zone.
- */
-
 void
 dns_zone_setprimaries(dns_zone_t *zone, const isc_sockaddr_t *primaries,
                      dns_name_t **keynames, dns_name_t **tlsnames,
@@ -1772,8 +1762,8 @@ dns_zone_getdnsseckeys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
  */
 
 isc_result_t
-dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
-                  isc_timermgr_t *timermgr, isc_nm_t *netmgr,
+dns_zonemgr_create(isc_mem_t *mctx, isc_loopmgr_t *loopmgr,
+                  isc_taskmgr_t *taskmgr, isc_nm_t *netmgr,
                   dns_zonemgr_t **zmgrp);
 /*%<
  * Create a zone manager.
@@ -1781,7 +1771,6 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
  * Requires:
  *\li  'mctx' to be a valid memory context.
  *\li  'taskmgr' to be a valid task manager.
- *\li  'timermgr' to be a valid timer manager.
  *\li  'zmgrp' to point to a NULL pointer.
  */
 
index d6a2f61cf583bf05e7f79ca5a20eed192d4e6c0f..5d53f316ac693a8f506944ce68b7c49950a1618a 100644 (file)
@@ -17,7 +17,9 @@
 #include <stdbool.h>
 
 #include <isc/buffer.h>
+#include <isc/event.h>
 #include <isc/log.h>
+#include <isc/loop.h>
 #include <isc/mem.h>
 #include <isc/print.h>
 #include <isc/result.h>
@@ -74,8 +76,7 @@ nta_detach(isc_mem_t *mctx, dns_nta_t **ntap) {
                isc_refcount_destroy(&nta->refcount);
                nta->magic = 0;
                if (nta->timer != NULL) {
-                       (void)isc_timer_reset(
-                               nta->timer, isc_timertype_inactive, NULL, true);
+                       (void)isc_timer_stop(nta->timer);
                        isc_timer_destroy(&nta->timer);
                }
                if (dns_rdataset_isassociated(&nta->rdataset)) {
@@ -102,7 +103,7 @@ free_nta(void *data, void *arg) {
 
 isc_result_t
 dns_ntatable_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
-                   isc_timermgr_t *timermgr, dns_ntatable_t **ntatablep) {
+                   isc_loopmgr_t *loopmgr, dns_ntatable_t **ntatablep) {
        dns_ntatable_t *ntatable;
        isc_result_t result;
 
@@ -127,7 +128,7 @@ dns_ntatable_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
        isc_rwlock_init(&ntatable->rwlock, 0, 0);
 
        ntatable->shuttingdown = false;
-       ntatable->timermgr = timermgr;
+       ntatable->loopmgr = loopmgr;
        ntatable->taskmgr = taskmgr;
 
        ntatable->view = view;
@@ -173,7 +174,7 @@ dns_ntatable_detach(dns_ntatable_t **ntatablep) {
                if (ntatable->task != NULL) {
                        isc_task_detach(&ntatable->task);
                }
-               ntatable->timermgr = NULL;
+               ntatable->loopmgr = NULL;
                ntatable->taskmgr = NULL;
                ntatable->magic = 0;
                isc_mem_put(ntatable->view->mctx, ntatable, sizeof(*ntatable));
@@ -218,9 +219,11 @@ fetch_done(isc_task_t *task, isc_event_t *event) {
        case DNS_R_NXDOMAIN:
        case DNS_R_NCACHENXRRSET:
        case DNS_R_NXRRSET:
+               RWLOCK(&ntatable->rwlock, isc_rwlocktype_write);
                if (nta->expiry > now) {
                        nta->expiry = now;
                }
+               RWUNLOCK(&ntatable->rwlock, isc_rwlocktype_write);
                break;
        default:
                break;
@@ -230,17 +233,19 @@ fetch_done(isc_task_t *task, isc_event_t *event) {
         * If we're expiring before the next recheck, we might
         * as well stop the timer now.
         */
+       RWLOCK(&ntatable->rwlock, isc_rwlocktype_read);
        if (nta->timer != NULL && nta->expiry - now < view->nta_recheck) {
-               (void)isc_timer_reset(nta->timer, isc_timertype_inactive, NULL,
-                                     true);
+               (void)isc_timer_stop(nta->timer);
        }
+       RWUNLOCK(&ntatable->rwlock, isc_rwlocktype_read);
+
        nta_detach(view->mctx, &nta);
        dns_view_weakdetach(&view);
 }
 
 static void
-checkbogus(isc_task_t *task, isc_event_t *event) {
-       dns_nta_t *nta = event->ev_arg;
+checkbogus(void *arg) {
+       dns_nta_t *nta = arg;
        dns_ntatable_t *ntatable = nta->ntatable;
        dns_view_t *view = NULL;
        isc_result_t result;
@@ -256,47 +261,42 @@ checkbogus(isc_task_t *task, isc_event_t *event) {
                dns_rdataset_disassociate(&nta->sigrdataset);
        }
 
-       isc_event_free(&event);
-
        nta_ref(nta);
        dns_view_weakattach(ntatable->view, &view);
        result = dns_resolver_createfetch(
                view->resolver, nta->name, dns_rdatatype_nsec, NULL, NULL, NULL,
-               NULL, 0, DNS_FETCHOPT_NONTA, 0, NULL, task, fetch_done, nta,
-               &nta->rdataset, &nta->sigrdataset, &nta->fetch);
+               NULL, 0, DNS_FETCHOPT_NONTA, 0, NULL, ntatable->task,
+               fetch_done, nta, &nta->rdataset, &nta->sigrdataset,
+               &nta->fetch);
        if (result != ISC_R_SUCCESS) {
                nta_detach(view->mctx, &nta);
                dns_view_weakdetach(&view);
        }
 }
 
-static isc_result_t
+static void
 settimer(dns_ntatable_t *ntatable, dns_nta_t *nta, uint32_t lifetime) {
-       isc_result_t result;
        isc_interval_t interval;
-       dns_view_t *view;
+       dns_view_t *view = NULL;
+       isc_loop_t *loop = NULL;
 
        REQUIRE(VALID_NTATABLE(ntatable));
        REQUIRE(VALID_NTA(nta));
 
-       if (ntatable->timermgr == NULL) {
-               return (ISC_R_SUCCESS);
+       if (ntatable->loopmgr == NULL) {
+               return;
        }
 
        view = ntatable->view;
        if (view->nta_recheck == 0 || lifetime <= view->nta_recheck) {
-               return (ISC_R_SUCCESS);
+               return;
        }
 
-       isc_timer_create(ntatable->timermgr, ntatable->task, checkbogus, nta,
-                        &nta->timer);
+       loop = isc_loop_main(ntatable->loopmgr);
+
+       isc_timer_create(loop, checkbogus, nta, &nta->timer);
        isc_interval_set(&interval, view->nta_recheck, 0);
-       result = isc_timer_reset(nta->timer, isc_timertype_ticker, &interval,
-                                false);
-       if (result != ISC_R_SUCCESS) {
-               isc_timer_destroy(&nta->timer);
-       }
-       return (result);
+       isc_timer_start(nta->timer, isc_timertype_ticker, &interval);
 }
 
 static isc_result_t
@@ -360,7 +360,7 @@ dns_ntatable_add(dns_ntatable_t *ntatable, const dns_name_t *name, bool force,
        result = dns_rbt_addnode(ntatable->table, name, &node);
        if (result == ISC_R_SUCCESS) {
                if (!force) {
-                       (void)settimer(ntatable, nta, lifetime);
+                       settimer(ntatable, nta, lifetime);
                }
                node->data = nta;
                nta = NULL;
@@ -368,7 +368,7 @@ dns_ntatable_add(dns_ntatable_t *ntatable, const dns_name_t *name, bool force,
                dns_nta_t *n = node->data;
                if (n == NULL) {
                        if (!force) {
-                               (void)settimer(ntatable, nta, lifetime);
+                               settimer(ntatable, nta, lifetime);
                        }
                        node->data = nta;
                        nta = NULL;
@@ -479,8 +479,7 @@ again:
                              "deleting expired NTA at %s", nb);
 
                if (nta->timer != NULL) {
-                       (void)isc_timer_reset(
-                               nta->timer, isc_timertype_inactive, NULL, true);
+                       (void)isc_timer_stop(nta->timer);
                        isc_timer_destroy(&nta->timer);
                }
 
@@ -689,9 +688,7 @@ dns_ntatable_shutdown(dns_ntatable_t *ntatable) {
                if (node->data != NULL) {
                        dns_nta_t *nta = (dns_nta_t *)node->data;
                        if (nta->timer != NULL) {
-                               (void)isc_timer_reset(nta->timer,
-                                                     isc_timertype_inactive,
-                                                     NULL, true);
+                               (void)isc_timer_stop(nta->timer);
                        }
                }
                result = dns_rbtnodechain_next(&chain, NULL, NULL);
index 83293f7d675e318f3fd6ccabd2c1f6f001b09a9c..7dfdda343e92241642c427f47de9bb49266a3291 100644 (file)
@@ -21,6 +21,7 @@
 #include <isc/counter.h>
 #include <isc/hash.h>
 #include <isc/log.h>
+#include <isc/loop.h>
 #include <isc/print.h>
 #include <isc/random.h>
 #include <isc/refcount.h>
@@ -29,6 +30,7 @@
 #include <isc/stats.h>
 #include <isc/string.h>
 #include <isc/task.h>
+#include <isc/tid.h>
 #include <isc/timer.h>
 #include <isc/util.h>
 
@@ -351,6 +353,7 @@ struct fetchctx {
        dns_name_t *domain;
        dns_rdataset_t nameservers;
        atomic_uint_fast32_t attributes;
+       isc_loop_t *loop;
        isc_timer_t *timer;
        isc_time_t expires;
        isc_time_t expires_try_stale;
@@ -527,8 +530,8 @@ struct dns_resolver {
        isc_mutex_t lock;
        isc_mutex_t primelock;
        dns_rdataclass_t rdclass;
+       isc_loopmgr_t *loopmgr;
        isc_nm_t *nm;
-       isc_timermgr_t *timermgr;
        isc_taskmgr_t *taskmgr;
        dns_view_t *view;
        bool frozen;
@@ -1260,7 +1263,7 @@ update_edns_stats(resquery_t *query) {
  * trigger if, for example, some ADB or validator dependency
  * loop occurs and causes a fetch to hang.
  */
-static isc_result_t
+static void
 fctx_starttimer(fetchctx_t *fctx) {
        isc_interval_t interval;
        isc_time_t now;
@@ -1276,26 +1279,18 @@ fctx_starttimer(fetchctx_t *fctx) {
                isc_time_subtract(&expires, &now, &interval);
        }
 
-       return (isc_timer_reset(fctx->timer, isc_timertype_once, &interval,
-                               true));
+       isc_timer_start(fctx->timer, isc_timertype_once, &interval);
 }
 
 static void
 fctx_stoptimer(fetchctx_t *fctx) {
-       isc_result_t result;
-
        /*
         * We don't return a result if resetting the timer to inactive fails
         * since there's nothing to be done about it.  Resetting to inactive
         * should never fail anyway, since the code as currently written
         * cannot fail in that case.
         */
-       result = isc_timer_reset(fctx->timer, isc_timertype_inactive, NULL,
-                                true);
-       if (result != ISC_R_SUCCESS) {
-               UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_timer_reset(): %s",
-                                isc_result_totext(result));
-       }
+       isc_timer_stop(fctx->timer);
 }
 
 static void
@@ -1807,10 +1802,8 @@ fctx_sendevents(fetchctx_t *fctx, isc_result_t result, int line) {
                                logit = true;
                        }
                        isc_interval_set(&i, 20 * 60, 0);
-                       result = isc_timer_reset(fctx->res->spillattimer,
-                                                isc_timertype_ticker, &i,
-                                                true);
-                       RUNTIME_CHECK(result == ISC_R_SUCCESS);
+                       isc_timer_start(fctx->res->spillattimer,
+                                       isc_timertype_ticker, &i);
                }
                UNLOCK(&fctx->res->lock);
                if (logit) {
@@ -4529,10 +4522,22 @@ fctx_doshutdown(isc_task_t *task, isc_event_t *event) {
        fctx_detach(&fctx);
 }
 
+static void
+fctx_expired(void *arg) {
+       fetchctx_t *fctx = (fetchctx_t *)arg;
+
+       REQUIRE(VALID_FCTX(fctx));
+
+       isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
+                     DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
+                     "shut down hung fetch while resolving %p(%s)", fctx,
+                     fctx->info);
+       fctx_shutdown(fctx);
+}
+
 static void
 fctx_start(isc_task_t *task, isc_event_t *event) {
        fetchctx_t *fctx = event->ev_arg;
-       isc_result_t result;
 
        REQUIRE(VALID_FCTX(fctx));
 
@@ -4542,6 +4547,13 @@ fctx_start(isc_task_t *task, isc_event_t *event) {
 
        LOCK(&fctx->bucket->lock);
 
+       /*
+        * Create an inactive timer to enforce maximum query
+        * lifetime. It will be made active when the fetch is
+        * started.
+        */
+       isc_timer_create(fctx->loop, fctx_expired, fctx, &fctx->timer);
+
        INSIST(fctx->state == fetchstate_init);
        if (atomic_load_acquire(&fctx->want_shutdown)) {
                /*
@@ -4584,12 +4596,8 @@ fctx_start(isc_task_t *task, isc_event_t *event) {
         * should be enough of a gap to avoid the timer firing
         * while a response is being processed normally.)
         */
-       result = fctx_starttimer(fctx);
-       if (result != ISC_R_SUCCESS) {
-               fctx_done_detach(&fctx, result);
-       } else {
-               fctx_try(fctx, false, false);
-       }
+       fctx_starttimer(fctx);
+       fctx_try(fctx, false, false);
 }
 
 /*
@@ -4664,23 +4672,6 @@ log_ns_ttl(fetchctx_t *fctx, const char *where) {
                      where, namebuf, domainbuf, fctx->ns_ttl_ok, fctx->ns_ttl);
 }
 
-static void
-fctx_expired(isc_task_t *task, isc_event_t *event) {
-       fetchctx_t *fctx = event->ev_arg;
-
-       REQUIRE(VALID_FCTX(fctx));
-
-       UNUSED(task);
-
-       isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
-                     DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
-                     "shut down hung fetch while resolving '%s'", fctx->info);
-       LOCK(&fctx->bucket->lock);
-       fctx_shutdown(fctx);
-       UNLOCK(&fctx->bucket->lock);
-       isc_event_free(&event);
-}
-
 static isc_result_t
 fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
            const dns_name_t *domain, dns_rdataset_t *nameservers,
@@ -4693,14 +4684,10 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
        isc_interval_t interval;
        unsigned int findoptions = 0;
        char buf[DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE + 1];
-       int tid = isc_nm_tid();
+       int tid = isc_tid();
        uint_fast32_t nfctx;
        size_t p;
 
-       if (tid == ISC_NETMGR_TID_UNKNOWN) {
-               tid = 0;
-       }
-
        /*
         * Caller must be holding the lock for 'bucket'
         */
@@ -4720,6 +4707,7 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
                .fwdpolicy = dns_fwdpolicy_none,
                .result = ISC_R_FAILURE,
                .exitline = -1, /* sentinel */
+               .loop = isc_loop_get(res->loopmgr, tid),
        };
 
        dns_resolver_attach(res, &fctx->res);
@@ -4896,14 +4884,6 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
                goto cleanup_qmessage;
        }
 
-       /*
-        * Create an inactive timer to enforce maximum query
-        * lifetime. It will be made active when the fetch is
-        * started.
-        */
-       isc_timer_create(res->timermgr, fctx->restask, fctx_expired, fctx,
-                        &fctx->timer);
-
        /*
         * Default retry interval initialization.  We set the interval
         * now mostly so it won't be uninitialized.  It will be set to
@@ -10163,16 +10143,13 @@ destroy(dns_resolver_t *res) {
 }
 
 static void
-spillattimer_countdown(isc_task_t *task, isc_event_t *event) {
-       dns_resolver_t *res = event->ev_arg;
-       isc_result_t result;
+spillattimer_countdown(void *arg) {
+       dns_resolver_t *res = (dns_resolver_t *)arg;
        unsigned int count;
        bool logit = false;
 
        REQUIRE(VALID_RESOLVER(res));
 
-       UNUSED(task);
-
        LOCK(&res->lock);
        INSIST(!atomic_load_acquire(&res->exiting));
        if (res->spillat > res->spillatmin) {
@@ -10180,9 +10157,7 @@ spillattimer_countdown(isc_task_t *task, isc_event_t *event) {
                logit = true;
        }
        if (res->spillat <= res->spillatmin) {
-               result = isc_timer_reset(res->spillattimer,
-                                        isc_timertype_inactive, NULL, true);
-               RUNTIME_CHECK(result == ISC_R_SUCCESS);
+               isc_timer_stop(res->spillattimer);
        }
        count = res->spillat;
        UNLOCK(&res->lock);
@@ -10191,20 +10166,18 @@ spillattimer_countdown(isc_task_t *task, isc_event_t *event) {
                              DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE,
                              "clients-per-query decreased to %u", count);
        }
-
-       isc_event_free(&event);
 }
 
 isc_result_t
-dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
-                   unsigned int ndisp, isc_nm_t *nm, isc_timermgr_t *timermgr,
+dns_resolver_create(dns_view_t *view, isc_loopmgr_t *loopmgr,
+                   isc_taskmgr_t *taskmgr, unsigned int ndisp, isc_nm_t *nm,
                    unsigned int options, dns_dispatchmgr_t *dispatchmgr,
                    dns_dispatch_t *dispatchv4, dns_dispatch_t *dispatchv6,
                    dns_resolver_t **resp) {
        isc_result_t result = ISC_R_SUCCESS;
        char name[sizeof("res4294967295")];
        dns_resolver_t *res = NULL;
-       isc_task_t *task = NULL;
+       isc_loop_t *loop = NULL;
 
        /*
         * Create a resolver.
@@ -10217,25 +10190,28 @@ dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
        REQUIRE(dispatchv4 != NULL || dispatchv6 != NULL);
 
        RTRACE("create");
+
        res = isc_mem_get(view->mctx, sizeof(*res));
-       *res = (dns_resolver_t){ .rdclass = view->rdclass,
-                                .nm = nm,
-                                .timermgr = timermgr,
-                                .taskmgr = taskmgr,
-                                .dispatchmgr = dispatchmgr,
-                                .options = options,
-                                .ntasks = isc_nm_getnworkers(nm),
-                                .udpsize = DEFAULT_EDNS_BUFSIZE,
-                                .spillatmin = 10,
-                                .spillat = 10,
-                                .spillatmax = 100,
-                                .retryinterval = 10000,
-                                .nonbackofftries = 3,
-                                .query_timeout = DEFAULT_QUERY_TIMEOUT,
-                                .maxdepth = DEFAULT_RECURSION_DEPTH,
-                                .maxqueries = DEFAULT_MAX_QUERIES,
-                                .querydscp4 = -1,
-                                .querydscp6 = -1 };
+       *res = (dns_resolver_t){
+               .loopmgr = loopmgr,
+               .rdclass = view->rdclass,
+               .nm = nm,
+               .taskmgr = taskmgr,
+               .dispatchmgr = dispatchmgr,
+               .options = options,
+               .udpsize = DEFAULT_EDNS_BUFSIZE,
+               .spillatmin = 10,
+               .spillat = 10,
+               .spillatmax = 100,
+               .retryinterval = 10000,
+               .nonbackofftries = 3,
+               .query_timeout = DEFAULT_QUERY_TIMEOUT,
+               .maxdepth = DEFAULT_RECURSION_DEPTH,
+               .maxqueries = DEFAULT_MAX_QUERIES,
+               .ntasks = isc_loopmgr_nloops(loopmgr),
+               .querydscp4 = -1,
+               .querydscp6 = -1,
+       };
 
        dns_view_weakattach(view, &res->view);
        isc_mem_attach(view->mctx, &res->mctx);
@@ -10289,15 +10265,9 @@ dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
        isc_mutex_init(&res->lock);
        isc_mutex_init(&res->primelock);
 
-       result = isc_task_create(taskmgr, 0, &task, 0);
-       if (result != ISC_R_SUCCESS) {
-               goto cleanup_primelock;
-       }
-       isc_task_setname(task, "resolver_task", NULL);
+       loop = isc_loop_main(res->loopmgr);
 
-       isc_timer_create(timermgr, task, spillattimer_countdown, res,
-                        &res->spillattimer);
-       isc_task_detach(&task);
+       isc_timer_create(loop, spillattimer_countdown, res, &res->spillattimer);
 
        res->magic = RES_MAGIC;
 
@@ -10305,23 +10275,6 @@ dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
 
        return (ISC_R_SUCCESS);
 
-cleanup_primelock:
-       isc_mutex_destroy(&res->primelock);
-       isc_mutex_destroy(&res->lock);
-
-       if (res->dispatches6 != NULL) {
-               dns_dispatchset_destroy(&res->dispatches6);
-       }
-       if (res->dispatches4 != NULL) {
-               dns_dispatchset_destroy(&res->dispatches4);
-       }
-
-       isc_rwlock_destroy(&res->zonehash_lock);
-       isc_ht_destroy(&res->zonebuckets);
-
-       isc_rwlock_destroy(&res->hash_lock);
-       isc_ht_destroy(&res->buckets);
-
 cleanup_tasks:
        for (size_t i = 0; i < res->ntasks; i++) {
                if (res->tasks[i] != NULL) {
@@ -10495,9 +10448,7 @@ dns_resolver_shutdown(dns_resolver_t *res) {
                isc_ht_iter_destroy(&it);
                RWUNLOCK(&res->hash_lock, isc_rwlocktype_read);
 
-               result = isc_timer_reset(res->spillattimer,
-                                        isc_timertype_inactive, NULL, true);
-               RUNTIME_CHECK(result == ISC_R_SUCCESS);
+               isc_timer_stop(res->spillattimer);
        }
 }
 
index 62b150f6d87a5e8ece0d5f2937810580b7e99a22..bfbb0795d6dd2016a81ab321f91131667005e452 100644 (file)
@@ -18,6 +18,7 @@
 #include <stdlib.h>
 
 #include <isc/buffer.h>
+#include <isc/loop.h>
 #include <isc/mem.h>
 #include <isc/net.h>
 #include <isc/netaddr.h>
@@ -27,6 +28,7 @@
 #include <isc/string.h>
 #include <isc/task.h>
 #include <isc/util.h>
+#include <isc/work.h>
 
 #include <dns/db.h>
 #include <dns/dbiterator.h>
@@ -92,7 +94,7 @@ static void
 update_from_db(dns_rpz_zone_t *rpz);
 
 static void
-dns_rpz_update_taskaction(isc_task_t *task, isc_event_t *event);
+dns_rpz_update_taskaction(void *);
 
 /*
  * Use a private definition of IPv6 addresses because s6_addr32 is not
@@ -1437,8 +1439,8 @@ rpz_node_deleter(void *nm_data, void *mctx) {
  */
 isc_result_t
 dns_rpz_new_zones(dns_rpz_zones_t **rpzsp, char *rps_cstr, size_t rps_cstr_size,
-                 isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
-                 isc_timermgr_t *timermgr) {
+                 isc_mem_t *mctx, isc_loopmgr_t *loopmgr,
+                 isc_taskmgr_t *taskmgr) {
        dns_rpz_zones_t *rpzs = NULL;
        isc_result_t result = ISC_R_SUCCESS;
 
@@ -1448,7 +1450,7 @@ dns_rpz_new_zones(dns_rpz_zones_t **rpzsp, char *rps_cstr, size_t rps_cstr_size,
        *rpzs = (dns_rpz_zones_t){
                .rps_cstr = rps_cstr,
                .rps_cstr_size = rps_cstr_size,
-               .timermgr = timermgr,
+               .loopmgr = loopmgr,
                .taskmgr = taskmgr,
        };
 
@@ -1516,7 +1518,7 @@ dns_rpz_new_zone(dns_rpz_zones_t *rpzs, dns_rpz_zone_t **rpzp) {
                .addsoa = true,
        };
 
-       isc_timer_create(rpzs->timermgr, rpzs->updater,
+       isc_timer_create(isc_loop_main(rpzs->loopmgr),
                         dns_rpz_update_taskaction, rpz, &rpz->updatetimer);
 
        isc_refcount_init(&rpz->refs, 1);
@@ -1542,9 +1544,6 @@ dns_rpz_new_zone(dns_rpz_zones_t *rpzs, dns_rpz_zone_t **rpzp) {
 
        rpz_attach_rpzs(rpzs, &rpz->rpzs);
 
-       ISC_EVENT_INIT(&rpz->updateevent, sizeof(rpz->updateevent), 0, 0, NULL,
-                      NULL, NULL, NULL, NULL);
-
        rpz->num = rpzs->p.num_zones++;
        rpzs->zones[rpz->num] = rpz;
 
@@ -1585,6 +1584,7 @@ dns_rpz_dbupdate_callback(dns_db_t *db, void *fn_arg) {
 
        if (!rpz->updatepending && !rpz->updaterunning) {
                uint64_t tdiff;
+               isc_interval_t interval;
 
                rpz->updatepending = true;
 
@@ -1592,7 +1592,6 @@ dns_rpz_dbupdate_callback(dns_db_t *db, void *fn_arg) {
                tdiff = isc_time_microdiff(&now, &rpz->lastupdated) / 1000000;
                if (tdiff < rpz->min_update_interval) {
                        uint64_t defer = rpz->min_update_interval - tdiff;
-                       isc_interval_t interval;
                        isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
                                      DNS_LOGMODULE_MASTER, ISC_LOG_INFO,
                                      "rpz: %s: new zone version came "
@@ -1600,22 +1599,12 @@ dns_rpz_dbupdate_callback(dns_db_t *db, void *fn_arg) {
                                      "%" PRIu64 " seconds",
                                      dname, defer);
                        isc_interval_set(&interval, (unsigned int)defer, 0);
-                       dns_db_currentversion(rpz->db, &rpz->dbversion);
-                       result = isc_timer_reset(rpz->updatetimer,
-                                                isc_timertype_once, &interval,
-                                                true);
                } else {
-                       isc_event_t *event = NULL;
-
-                       dns_db_currentversion(rpz->db, &rpz->dbversion);
-                       INSIST(!ISC_LINK_LINKED(&rpz->updateevent, ev_link));
-                       ISC_EVENT_INIT(
-                               &rpz->updateevent, sizeof(rpz->updateevent), 0,
-                               DNS_EVENT_RPZUPDATED, dns_rpz_update_taskaction,
-                               rpz, rpz, NULL, NULL);
-                       event = &rpz->updateevent;
-                       isc_task_send(rpz->rpzs->updater, &event);
+                       isc_interval_set(&interval, 0, 0);
                }
+               dns_db_currentversion(rpz->db, &rpz->dbversion);
+               isc_timer_start(rpz->updatetimer, isc_timertype_once,
+                               &interval);
        } else {
                rpz->updatepending = true;
                isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
@@ -1633,16 +1622,10 @@ dns_rpz_dbupdate_callback(dns_db_t *db, void *fn_arg) {
 }
 
 static void
-dns_rpz_update_taskaction(isc_task_t *task, isc_event_t *event) {
+dns_rpz_update_taskaction(void *arg) {
        isc_result_t result;
-       dns_rpz_zone_t *rpz = NULL;
+       dns_rpz_zone_t *rpz = (dns_rpz_zone_t *)arg;
 
-       REQUIRE(event != NULL);
-       REQUIRE(event->ev_arg != NULL);
-
-       UNUSED(task);
-       rpz = (dns_rpz_zone_t *)event->ev_arg;
-       isc_event_free(&event);
        LOCK(&rpz->rpzs->maint_lock);
        rpz->updatepending = false;
        rpz->updaterunning = true;
@@ -1650,22 +1633,17 @@ dns_rpz_update_taskaction(isc_task_t *task, isc_event_t *event) {
 
        update_from_db(rpz);
 
-       result = isc_timer_reset(rpz->updatetimer, isc_timertype_inactive, NULL,
-                                true);
-       RUNTIME_CHECK(result == ISC_R_SUCCESS);
+       isc_timer_stop(rpz->updatetimer);
        result = isc_time_now(&rpz->lastupdated);
        RUNTIME_CHECK(result == ISC_R_SUCCESS);
        UNLOCK(&rpz->rpzs->maint_lock);
 }
 
 static void
-update_rpz_done_cb(void *data, isc_result_t result) {
+update_rpz_done_cb(void *data) {
        dns_rpz_zone_t *rpz = (dns_rpz_zone_t *)data;
        char dname[DNS_NAME_FORMATSIZE];
-
-       if (result == ISC_R_SUCCESS && rpz->updateresult != ISC_R_SUCCESS) {
-               result = rpz->updateresult;
-       }
+       isc_interval_t interval;
 
        LOCK(&rpz->rpzs->maint_lock);
        rpz->updaterunning = false;
@@ -1680,7 +1658,6 @@ update_rpz_done_cb(void *data, isc_result_t result) {
        /* If there's an update pending, schedule it */
        if (rpz->min_update_interval > 0) {
                uint64_t defer = rpz->min_update_interval;
-               isc_interval_t interval;
 
                isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
                              DNS_LOGMODULE_MASTER, ISC_LOG_INFO,
@@ -1689,29 +1666,23 @@ update_rpz_done_cb(void *data, isc_result_t result) {
                              "%" PRIu64 " seconds",
                              dname, defer);
                isc_interval_set(&interval, (unsigned int)defer, 0);
-               isc_timer_reset(rpz->updatetimer, isc_timertype_once, &interval,
-                               true);
        } else {
-               isc_event_t *event = NULL;
-               INSIST(!ISC_LINK_LINKED(&rpz->updateevent, ev_link));
-               ISC_EVENT_INIT(&rpz->updateevent, sizeof(rpz->updateevent), 0,
-                              DNS_EVENT_RPZUPDATED, dns_rpz_update_taskaction,
-                              rpz, rpz, NULL, NULL);
-               event = &rpz->updateevent;
-               isc_task_send(rpz->rpzs->updater, &event);
+               isc_interval_set(&interval, 0, 0);
        }
 
+       isc_timer_start(rpz->updatetimer, isc_timertype_once, &interval);
+
 done:
        dns_db_closeversion(rpz->updb, &rpz->updbversion, false);
        dns_db_detach(&rpz->updb);
 
        UNLOCK(&rpz->rpzs->maint_lock);
 
-       rpz_detach(&rpz);
-
        isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTER,
                      ISC_LOG_INFO, "rpz: %s: reload done: %s", dname,
-                     isc_result_totext(result));
+                     isc_result_totext(rpz->updateresult));
+
+       rpz_detach(&rpz);
 }
 
 static isc_result_t
@@ -1955,7 +1926,6 @@ update_from_db(dns_rpz_zone_t *rpz) {
        char domain[DNS_NAME_FORMATSIZE];
        dns_rpz_zone_t *rpz_zone = NULL;
 
-       REQUIRE(isc_nm_tid() >= 0);
        REQUIRE(rpz != NULL);
        REQUIRE(DNS_DB_VALID(rpz->db));
        REQUIRE(rpz->updb == NULL);
@@ -1970,8 +1940,8 @@ update_from_db(dns_rpz_zone_t *rpz) {
        isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTER,
                      ISC_LOG_INFO, "rpz: %s: reload start", domain);
 
-       isc_nm_work_offload(isc_task_getnetmgr(rpz->rpzs->updater),
-                           update_rpz_cb, update_rpz_done_cb, rpz_zone);
+       isc_work_enqueue(isc_loop_current(rpz->rpzs->loopmgr), update_rpz_cb,
+                        update_rpz_done_cb, rpz_zone);
 }
 
 /*
index 6c647de98ad0c7eac50451bf08a65cfe5c9b7803..edf4bd756540c792cde6a6a709f9856670ee9dd6 100644 (file)
@@ -523,7 +523,7 @@ destroy(dns_sdb_t *sdb) {
 
        isc_refcount_destroy(&sdb->references);
 
-       if (imp->methods->destroy != NULL) {
+       if (imp != NULL && imp->methods->destroy != NULL) {
                MAYBE_LOCK(sdb);
                imp->methods->destroy(sdb->zone, imp->driverdata, &sdb->dbdata);
                MAYBE_UNLOCK(sdb);
index 3a00a0a46ce1994c5d7ca9844fc04094c9387128..56aeb913cf122c21b27788bf823c9999aa7e247a 100644 (file)
@@ -623,9 +623,9 @@ dns_view_createzonetable(dns_view_t *view) {
 }
 
 isc_result_t
-dns_view_createresolver(dns_view_t *view, isc_taskmgr_t *taskmgr,
-                       unsigned int ndisp, isc_nm_t *nm,
-                       isc_timermgr_t *timermgr, unsigned int options,
+dns_view_createresolver(dns_view_t *view, isc_loopmgr_t *loopmgr,
+                       isc_taskmgr_t *taskmgr, unsigned int ndisp,
+                       isc_nm_t *netmgr, unsigned int options,
                        dns_dispatchmgr_t *dispatchmgr,
                        dns_dispatch_t *dispatchv4,
                        dns_dispatch_t *dispatchv6) {
@@ -642,7 +642,7 @@ dns_view_createresolver(dns_view_t *view, isc_taskmgr_t *taskmgr,
        }
        isc_task_setname(view->task, "view", view);
 
-       result = dns_resolver_create(view, taskmgr, ndisp, nm, timermgr,
+       result = dns_resolver_create(view, loopmgr, taskmgr, ndisp, netmgr,
                                     options, dispatchmgr, dispatchv4,
                                     dispatchv6, &view->resolver);
        if (result != ISC_R_SUCCESS) {
@@ -1659,12 +1659,12 @@ dns_view_freezezones(dns_view_t *view, bool value) {
 
 isc_result_t
 dns_view_initntatable(dns_view_t *view, isc_taskmgr_t *taskmgr,
-                     isc_timermgr_t *timermgr) {
+                     isc_loopmgr_t *loopmgr) {
        REQUIRE(DNS_VIEW_VALID(view));
        if (view->ntatable_priv != NULL) {
                dns_ntatable_detach(&view->ntatable_priv);
        }
-       return (dns_ntatable_create(view, taskmgr, timermgr,
+       return (dns_ntatable_create(view, taskmgr, loopmgr,
                                    &view->ntatable_priv));
 }
 
index 4cc012cf88ee58c96bded562474e2bf4e42c0d18..ab28bf693e0a78d986977739fa21249cdecb0eac 100644 (file)
 #include <inttypes.h>
 #include <stdbool.h>
 
+#include <isc/async.h>
 #include <isc/atomic.h>
 #include <isc/file.h>
 #include <isc/hash.h>
 #include <isc/hex.h>
+#include <isc/loop.h>
 #include <isc/md.h>
 #include <isc/mutex.h>
 #include <isc/print.h>
@@ -238,6 +240,7 @@ struct dns_zone {
        /* Locked */
        dns_zonemgr_t *zmgr;
        ISC_LINK(dns_zone_t) link; /* Used by zmgr. */
+       isc_loop_t *loop;
        isc_timer_t *timer;
        isc_refcount_t irefs;
        dns_name_t origin;
@@ -350,7 +353,6 @@ struct dns_zone {
        uint32_t maxxfrout;
        uint32_t idlein;
        uint32_t idleout;
-       isc_event_t ctlevent;
        dns_ssutable_t *ssutable;
        uint32_t sigvalidityinterval;
        uint32_t keyvalidityinterval;
@@ -593,11 +595,10 @@ struct dns_zonemgr {
        unsigned int magic;
        isc_mem_t *mctx;
        isc_refcount_t refs;
+       isc_loopmgr_t *loopmgr;
        isc_taskmgr_t *taskmgr;
-       isc_timermgr_t *timermgr;
        isc_nm_t *netmgr;
        uint32_t workers;
-       isc_task_t *task;
        isc_task_t **zonetasks;
        isc_task_t **loadtasks;
        isc_mem_t **mctxpool;
@@ -852,9 +853,7 @@ unsigned int dns_zone_mkey_month = MONTH;
 #define SEND_BUFFER_SIZE 2048
 
 static void
-zone_timer_start(dns_zone_t *zone, isc_time_t *next, isc_time_t *now);
-static void
-zone_timer_stop(dns_zone_t *zone);
+zone_timer_set(dns_zone_t *zone, isc_time_t *next, isc_time_t *now);
 
 static void
 zone_settimer(dns_zone_t *, isc_time_t *);
@@ -905,7 +904,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
 static void
 zone_needdump(dns_zone_t *zone, unsigned int delay);
 static void
-zone_shutdown(isc_task_t *, isc_event_t *);
+zone_shutdown(void *arg);
 static void
 zone_loaddone(void *arg, isc_result_t result);
 static isc_result_t
@@ -1211,9 +1210,6 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx, unsigned int tid) {
        /* Must be after magic is set. */
        dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
 
-       ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0,
-                      DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone, NULL,
-                      NULL);
        *zonep = zone;
        return (ISC_R_SUCCESS);
 
@@ -2436,9 +2432,6 @@ zone_asyncload(isc_task_t *task, isc_event_t *event) {
                (asl->loaded)(asl->loaded_arg, zone, task);
        }
 
-       /* Reduce the quantum */
-       isc_task_setquantum(zone->loadtask, 1);
-
        isc_mem_put(zone->mctx, asl, sizeof(*asl));
        dns_zone_idetach(&zone);
 }
@@ -5785,8 +5778,8 @@ dns_zone_detach(dns_zone_t **zonep) {
                         * up synchronously in the context of
                         * its task.
                         */
-                       isc_event_t *ev = &zone->ctlevent;
-                       isc_task_send(zone->task, &ev);
+
+                       isc_async_run(zone->loop, zone_shutdown, zone);
                } else {
                        /*
                         * This zone is not being managed; it has
@@ -6601,22 +6594,6 @@ dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) {
        ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
 }
 
-/*
- * Coordinates the starting of routine jobs.
- */
-void
-dns_zone_maintenance(dns_zone_t *zone) {
-       isc_time_t now;
-
-       REQUIRE(DNS_ZONE_VALID(zone));
-       ENTER;
-
-       LOCK_ZONE(zone);
-       TIME_NOW(&now);
-       zone_settimer(zone, &now);
-       UNLOCK_ZONE(zone);
-}
-
 static bool
 was_dumping(dns_zone_t *zone) {
        REQUIRE(LOCKED_ZONE(zone));
@@ -11556,9 +11533,12 @@ zone_maintenance(dns_zone_t *zone) {
                }
                break;
        case dns_zone_primary:
+               if (zone->rss_event != NULL) {
+                       isc_time_settoepoch(&zone->refreshkeytime);
+                       break;
+               }
                if (!isc_time_isepoch(&zone->refreshkeytime) &&
-                   isc_time_compare(&now, &zone->refreshkeytime) >= 0 &&
-                   zone->rss_event == NULL)
+                   isc_time_compare(&now, &zone->refreshkeytime) >= 0)
                {
                        zone_rekey(zone);
                }
@@ -11574,6 +11554,10 @@ zone_maintenance(dns_zone_t *zone) {
                 * Do we need to sign/resign some RRsets?
                 */
                if (zone->rss_event != NULL) {
+                       isc_time_settoepoch(&zone->signingtime);
+                       isc_time_settoepoch(&zone->resigntime);
+                       isc_time_settoepoch(&zone->nsec3chaintime);
+                       isc_time_settoepoch(&zone->keywarntime);
                        break;
                }
                if (!isc_time_isepoch(&zone->signingtime) &&
@@ -15081,14 +15065,12 @@ unlock:
  * to shut down, it is not a shutdown event in the sense of the task library.
  */
 static void
-zone_shutdown(isc_task_t *task, isc_event_t *event) {
-       dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
+zone_shutdown(void *arg) {
+       dns_zone_t *zone = (dns_zone_t *)arg;
        bool free_needed, linked = false;
        dns_zone_t *raw = NULL, *secure = NULL;
 
-       UNUSED(task);
        REQUIRE(DNS_ZONE_VALID(zone));
-       INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
        INSIST(isc_refcount_current(&zone->erefs) == 0);
 
        zone_debuglog(zone, __func__, 3, "shutting down");
@@ -15210,23 +15192,17 @@ zone_shutdown(isc_task_t *task, isc_event_t *event) {
 }
 
 static void
-zone_timer(isc_task_t *task, isc_event_t *event) {
-       dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
+zone_timer(void *arg) {
+       dns_zone_t *zone = (dns_zone_t *)arg;
 
-       UNUSED(task);
        REQUIRE(DNS_ZONE_VALID(zone));
 
-       ENTER;
-
        zone_maintenance(zone);
-
-       isc_event_free(&event);
 }
 
 static void
-zone_timer_start(dns_zone_t *zone, isc_time_t *next, isc_time_t *now) {
+zone_timer_set(dns_zone_t *zone, isc_time_t *next, isc_time_t *now) {
        isc_interval_t interval;
-       isc_result_t result;
 
        if (isc_time_compare(next, now) <= 0) {
                isc_interval_set(&interval, 0, 1);
@@ -15234,24 +15210,7 @@ zone_timer_start(dns_zone_t *zone, isc_time_t *next, isc_time_t *now) {
                isc_time_subtract(next, now, &interval);
        }
 
-       result = isc_timer_reset(zone->timer, isc_timertype_once, &interval,
-                                true);
-       if (result != ISC_R_SUCCESS) {
-               dns_zone_log(zone, ISC_LOG_ERROR,
-                            "could not reset zone timer: %s",
-                            isc_result_totext(result));
-       }
-}
-
-static void
-zone_timer_stop(dns_zone_t *zone) {
-       isc_result_t result = isc_timer_reset(
-               zone->timer, isc_timertype_inactive, NULL, true);
-       if (result != ISC_R_SUCCESS) {
-               dns_zone_log(zone, ISC_LOG_ERROR,
-                            "could not deactivate zone timer: %s",
-                            isc_result_totext(result));
-       }
+       isc_timer_start(zone->timer, isc_timertype_once, &interval);
 }
 
 static void
@@ -15395,9 +15354,8 @@ zone_settimer(dns_zone_t *zone, isc_time_t *now) {
 
        if (isc_time_isepoch(&next)) {
                zone_debuglog(zone, __func__, 10, "settimer inactive");
-               zone_timer_stop(zone);
        } else {
-               zone_timer_start(zone, &next, now);
+               zone_timer_set(zone, &next, now);
        }
 }
 
@@ -18829,24 +18787,26 @@ zonemgr_keymgmt_find(dns_zonemgr_t *zmgr, dns_zone_t *zone,
 }
 
 isc_result_t
-dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
-                  isc_timermgr_t *timermgr, isc_nm_t *netmgr,
+dns_zonemgr_create(isc_mem_t *mctx, isc_loopmgr_t *loopmgr,
+                  isc_taskmgr_t *taskmgr, isc_nm_t *netmgr,
                   dns_zonemgr_t **zmgrp) {
        dns_zonemgr_t *zmgr;
        isc_result_t result;
+       isc_loop_t *mainloop = isc_loop_main(loopmgr);
 
        REQUIRE(mctx != NULL);
+       REQUIRE(loopmgr != NULL);
        REQUIRE(taskmgr != NULL);
-       REQUIRE(timermgr != NULL);
        REQUIRE(netmgr != NULL);
+       REQUIRE(zmgrp != NULL && *zmgrp == NULL);
 
        zmgr = isc_mem_get(mctx, sizeof(*zmgr));
 
        *zmgr = (dns_zonemgr_t){
+               .loopmgr = loopmgr,
                .taskmgr = taskmgr,
-               .timermgr = timermgr,
                .netmgr = netmgr,
-               .workers = isc_nm_getnworkers(netmgr),
+               .workers = isc_loopmgr_nloops(loopmgr),
                .transfersin = 10,
                .transfersperns = 2,
        };
@@ -18866,39 +18826,32 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
        /* Unreachable lock. */
        isc_rwlock_init(&zmgr->urlock, 0, 0);
 
-       /* Create a single task for queueing of SOA queries. */
-       result = isc_task_create(taskmgr, 1, &zmgr->task, 0);
+       result = isc_ratelimiter_create(mainloop, &zmgr->checkdsrl);
+       INSIST(result == ISC_R_SUCCESS);
        if (result != ISC_R_SUCCESS) {
                goto free_urlock;
        }
 
-       isc_task_setname(zmgr->task, "zmgr", zmgr);
-       result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
-                                       &zmgr->checkdsrl);
-       if (result != ISC_R_SUCCESS) {
-               goto free_task;
-       }
-
-       result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
-                                       &zmgr->notifyrl);
+       result = isc_ratelimiter_create(mainloop, &zmgr->notifyrl);
+       INSIST(result == ISC_R_SUCCESS);
        if (result != ISC_R_SUCCESS) {
                goto free_checkdsrl;
        }
 
-       result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
-                                       &zmgr->refreshrl);
+       result = isc_ratelimiter_create(mainloop, &zmgr->refreshrl);
+       INSIST(result == ISC_R_SUCCESS);
        if (result != ISC_R_SUCCESS) {
                goto free_notifyrl;
        }
 
-       result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
-                                       &zmgr->startupnotifyrl);
+       result = isc_ratelimiter_create(mainloop, &zmgr->startupnotifyrl);
+       INSIST(result == ISC_R_SUCCESS);
        if (result != ISC_R_SUCCESS) {
                goto free_refreshrl;
        }
 
-       result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
-                                       &zmgr->startuprefreshrl);
+       result = isc_ratelimiter_create(mainloop, &zmgr->startuprefreshrl);
+       INSIST(result == ISC_R_SUCCESS);
        if (result != ISC_R_SUCCESS) {
                goto free_startupnotifyrl;
        }
@@ -18909,7 +18862,9 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
        for (size_t i = 0; i < zmgr->workers; i++) {
                result = isc_task_create(zmgr->taskmgr, 2, &zmgr->zonetasks[i],
                                         i);
+               INSIST(result == ISC_R_SUCCESS);
                if (result != ISC_R_SUCCESS) {
+                       INSIST(result == ISC_R_SUCCESS);
                        goto free_zonetasks;
                }
                isc_task_setname(zmgr->zonetasks[i], "zonemgr-zonetasks", NULL);
@@ -18921,6 +18876,7 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
        for (size_t i = 0; i < zmgr->workers; i++) {
                result = isc_task_create(zmgr->taskmgr, UINT_MAX,
                                         &zmgr->loadtasks[i], i);
+               INSIST(result == ISC_R_SUCCESS);
                if (result != ISC_R_SUCCESS) {
                        goto free_loadtasks;
                }
@@ -18983,17 +18939,20 @@ free_zonetasks:
        isc_mem_put(zmgr->mctx, zmgr->zonetasks,
                    zmgr->workers * sizeof(zmgr->zonetasks[0]));
 
-       isc_ratelimiter_detach(&zmgr->startuprefreshrl);
+       isc_ratelimiter_shutdown(zmgr->startuprefreshrl);
+       isc_ratelimiter_destroy(&zmgr->startuprefreshrl);
 free_startupnotifyrl:
-       isc_ratelimiter_detach(&zmgr->startupnotifyrl);
+       isc_ratelimiter_shutdown(zmgr->startupnotifyrl);
+       isc_ratelimiter_destroy(&zmgr->startupnotifyrl);
 free_refreshrl:
-       isc_ratelimiter_detach(&zmgr->refreshrl);
+       isc_ratelimiter_shutdown(zmgr->refreshrl);
+       isc_ratelimiter_destroy(&zmgr->refreshrl);
 free_notifyrl:
-       isc_ratelimiter_detach(&zmgr->notifyrl);
+       isc_ratelimiter_shutdown(zmgr->notifyrl);
+       isc_ratelimiter_destroy(&zmgr->notifyrl);
 free_checkdsrl:
-       isc_ratelimiter_detach(&zmgr->checkdsrl);
-free_task:
-       isc_task_detach(&zmgr->task);
+       isc_ratelimiter_shutdown(zmgr->checkdsrl);
+       isc_ratelimiter_destroy(&zmgr->checkdsrl);
 free_urlock:
        isc_rwlock_destroy(&zmgr->urlock);
        isc_rwlock_destroy(&zmgr->rwlock);
@@ -19058,8 +19017,9 @@ dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
        isc_task_setname(zone->task, "zone", zone);
        isc_task_setname(zone->loadtask, "loadzone", zone);
 
-       isc_timer_create(zmgr->timermgr, zone->task, zone_timer, zone,
-                        &zone->timer);
+       zone->loop = isc_loop_get(zmgr->loopmgr, zone->tid);
+
+       isc_timer_create(zone->loop, zone_timer, zone, &zone->timer);
 
        /*
         * The timer "holds" a iref.
@@ -19133,14 +19093,18 @@ dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
 
 isc_result_t
 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
-       dns_zone_t *p;
-
        REQUIRE(DNS_ZONEMGR_VALID(zmgr));
 
        RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
-       for (p = ISC_LIST_HEAD(zmgr->zones); p != NULL;
-            p = ISC_LIST_NEXT(p, link)) {
-               dns_zone_maintenance(p);
+       for (dns_zone_t *zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL;
+            zone = ISC_LIST_NEXT(zone, link))
+       {
+               isc_time_t now;
+
+               LOCK_ZONE(zone);
+               TIME_NOW(&now);
+               zone_settimer(zone, &now);
+               UNLOCK_ZONE(zone);
        }
        RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
 
@@ -19177,24 +19141,16 @@ dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
        isc_ratelimiter_shutdown(zmgr->startupnotifyrl);
        isc_ratelimiter_shutdown(zmgr->startuprefreshrl);
 
-       if (zmgr->task != NULL) {
-               isc_task_detach(&zmgr->task);
-       }
-
        for (size_t i = 0; i < zmgr->workers; i++) {
                isc_mem_detach(&zmgr->mctxpool[i]);
        }
 
        for (size_t i = 0; i < zmgr->workers; i++) {
-               if (zmgr->loadtasks[i] != NULL) {
-                       isc_task_detach(&zmgr->loadtasks[i]);
-               }
+               isc_task_detach(&zmgr->loadtasks[i]);
        }
 
        for (size_t i = 0; i < zmgr->workers; i++) {
-               if (zmgr->zonetasks[i] != NULL) {
-                       isc_task_detach(&zmgr->zonetasks[i]);
-               }
+               isc_task_detach(&zmgr->zonetasks[i]);
        }
 
        RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
@@ -19210,19 +19166,17 @@ dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
 
 static void
 zonemgr_free(dns_zonemgr_t *zmgr) {
-       isc_mem_t *mctx;
-
-       INSIST(ISC_LIST_EMPTY(zmgr->zones));
+       REQUIRE(ISC_LIST_EMPTY(zmgr->zones));
 
        zmgr->magic = 0;
 
        isc_refcount_destroy(&zmgr->refs);
        isc_mutex_destroy(&zmgr->iolock);
-       isc_ratelimiter_detach(&zmgr->checkdsrl);
-       isc_ratelimiter_detach(&zmgr->notifyrl);
-       isc_ratelimiter_detach(&zmgr->refreshrl);
-       isc_ratelimiter_detach(&zmgr->startupnotifyrl);
-       isc_ratelimiter_detach(&zmgr->startuprefreshrl);
+       isc_ratelimiter_destroy(&zmgr->checkdsrl);
+       isc_ratelimiter_destroy(&zmgr->notifyrl);
+       isc_ratelimiter_destroy(&zmgr->refreshrl);
+       isc_ratelimiter_destroy(&zmgr->startupnotifyrl);
+       isc_ratelimiter_destroy(&zmgr->startuprefreshrl);
 
        isc_mem_put(zmgr->mctx, zmgr->mctxpool,
                    zmgr->workers * sizeof(zmgr->mctxpool[0]));
@@ -19236,12 +19190,10 @@ zonemgr_free(dns_zonemgr_t *zmgr) {
 
        zonemgr_keymgmt_destroy(zmgr);
 
-       mctx = zmgr->mctx;
        if (zmgr->tlsctx_cache != NULL) {
                isc_tlsctx_cache_detach(&zmgr->tlsctx_cache);
        }
-       isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
-       isc_mem_detach(&mctx);
+       isc_mem_putanddetach(&zmgr->mctx, zmgr, sizeof(*zmgr));
 }
 
 void
@@ -19593,7 +19545,6 @@ setrl(isc_ratelimiter_t *rl, unsigned int *rate, unsigned int value) {
        isc_interval_t interval;
        uint32_t s, ns;
        uint32_t pertic;
-       isc_result_t result;
 
        if (value == 0) {
                value = 1;
@@ -19615,8 +19566,7 @@ setrl(isc_ratelimiter_t *rl, unsigned int *rate, unsigned int value) {
 
        isc_interval_set(&interval, s, ns);
 
-       result = isc_ratelimiter_setinterval(rl, &interval);
-       RUNTIME_CHECK(result == ISC_R_SUCCESS);
+       isc_ratelimiter_setinterval(rl, &interval);
        isc_ratelimiter_setpertic(rl, pertic);
 
        *rate = value;
@@ -22487,8 +22437,8 @@ dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) {
        LOCK_ZONE(zone);
        LOCK_ZONE(raw);
 
-       isc_timer_create(zmgr->timermgr, zone->task, zone_timer, raw,
-                        &raw->timer);
+       raw->loop = zone->loop;
+       isc_timer_create(raw->loop, zone_timer, raw, &raw->timer);
 
        /*
         * The timer "holds" a iref.
@@ -22499,7 +22449,7 @@ dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) {
        isc_refcount_increment(&raw->erefs);
        zone->raw = raw;
 
-       /* dns_zone_iattach(zone,  &raw->secure); */
+       /* dns_zone_iattach(zone, &raw->secure); */
        zone_iattach(zone, &raw->secure);
 
        isc_task_attach(zone->task, &raw->task);
index 78fbddbc8c5932c9205b7e2f7449c2fa3af7cf68..d0822ff73b2a2b17951bf33c5081995a3ce646a9 100644 (file)
@@ -169,7 +169,6 @@ libisc_la_SOURCES =         \
        mutexblock.c            \
        net.c                   \
        netaddr.c               \
-       netmgr_p.h              \
        netscope.c              \
        nonce.c                 \
        openssl_shim.c          \
@@ -199,12 +198,10 @@ libisc_la_SOURCES =               \
        symtab.c                \
        syslog.c                \
        task.c                  \
-       task_p.h                \
        thread.c                \
        tid.c                   \
        time.c                  \
        timer.c                 \
-       timer_p.h               \
        tls.c                   \
        tls_p.h                 \
        tm.c                    \
index 774ed30a329b638c043b278968ecd041b0dad71b..3a0f4b4ddd595fe74513198377f7cf316df5b7b0 100644 (file)
@@ -22,9 +22,9 @@ typedef struct isc_managers isc_managers_t;
 
 isc_result_t
 isc_managers_create(isc_mem_t *mctx, size_t workers, size_t quantum,
-                   isc_nm_t **netmgrp, isc_taskmgr_t **taskmgrp,
-                   isc_timermgr_t **timermgrp);
+                   isc_loopmgr_t **loopmgrp, isc_nm_t **netmgrp,
+                   isc_taskmgr_t **taskmgrp);
 
 void
-isc_managers_destroy(isc_nm_t **netmgrp, isc_taskmgr_t **taskmgrp,
-                    isc_timermgr_t **timermgrp);
+isc_managers_destroy(isc_loopmgr_t **loopmgr, isc_nm_t **netmgrp,
+                    isc_taskmgr_t **taskmgrp);
index 828665418c2821cf5ec06c00cfe95bd0cafb43dc..b99e509ff67c6cd0d6ff6e3e4cab91fbc0be2da0 100644 (file)
@@ -31,6 +31,7 @@
 #include <stdbool.h>
 
 #include <isc/lang.h>
+#include <isc/loop.h>
 #include <isc/time.h>
 #include <isc/types.h>
 
@@ -41,13 +42,12 @@ ISC_LANG_BEGINDECLS
 *****/
 
 isc_result_t
-isc_ratelimiter_create(isc_mem_t *mctx, isc_timermgr_t *timermgr,
-                      isc_task_t *task, isc_ratelimiter_t **ratelimiterp);
+isc_ratelimiter_create(isc_loop_t *loop, isc_ratelimiter_t **ratelimiterp);
 /*%<
  * Create a rate limiter.  The execution interval is initially undefined.
  */
 
-isc_result_t
+void
 isc_ratelimiter_setinterval(isc_ratelimiter_t *rl, isc_interval_t *interval);
 /*!<
  * Set the minimum interval between event executions.
@@ -110,37 +110,19 @@ isc_ratelimiter_shutdown(isc_ratelimiter_t *ratelimiter);
  *
  * Ensures:
  *\li  All events that have not yet been
- *     dispatched to the task are dispatched immediately with
+ *     dispatched to the task are dispatched immediately with
  *     the #ISC_EVENTATTR_CANCELED bit set in ev_attributes.
  *
  *\li  Further attempts to enqueue events will fail with
- *     #ISC_R_SHUTTINGDOWN.
+ *     #ISC_R_SHUTTINGDOWN.
  *
  *\li  The rate limiter is no longer attached to its task.
  */
 
 void
-isc_ratelimiter_attach(isc_ratelimiter_t *source, isc_ratelimiter_t **target);
-/*%<
- * Attach to a rate limiter.
- */
-
-void
-isc_ratelimiter_detach(isc_ratelimiter_t **ratelimiterp);
-/*%<
- * Detach from a rate limiter.
- */
-
-isc_result_t
-isc_ratelimiter_stall(isc_ratelimiter_t *rl);
-/*%<
- * Stall event processing.
- */
-
-isc_result_t
-isc_ratelimiter_release(isc_ratelimiter_t *rl);
+isc_ratelimiter_destroy(isc_ratelimiter_t **ratelimiterp);
 /*%<
- * Release a stalled rate limiter.
+ * Destroy the rate limiter.
  */
 
 ISC_LANG_ENDDECLS
index 132cc67bf64b40e81d908db7397287efa36c2b26..45bc317bbb7ddf87f583de96a3e57db92befebc5 100644 (file)
 /*! \file isc/timer.h
  * \brief Provides timers which are event sources in the task system.
  *
- * Three types of timers are supported:
+ * Two types of timers are supported:
  *
  *\li  'ticker' timers generate a periodic tick event.
  *
  *\li  'once' timers generate an timeout event if the time reaches
  *      the set interval.
  *
- *\li  'inactive' timers generate no events.
- *
- * Timers can change type.  It is typical to create a timer as
- * an 'inactive' timer and then change it into a 'ticker' or
- * 'once' timer.
- *
  *\li MP:
  *     The module ensures appropriate synchronization of data structures it
  *     creates and manipulates.
@@ -61,8 +55,7 @@
 
 #include <stdbool.h>
 
-#include <isc/event.h>
-#include <isc/eventclass.h>
+#include <isc/job.h>
 #include <isc/lang.h>
 #include <isc/time.h>
 #include <isc/types.h>
@@ -78,20 +71,8 @@ typedef enum {
        isc_timertype_undefined = -1, /*%< Undefined */
        isc_timertype_ticker = 0,     /*%< Ticker */
        isc_timertype_once = 1,       /*%< Once */
-       isc_timertype_inactive = 3    /*%< Inactive */
 } isc_timertype_t;
 
-typedef struct isc_timerevent isc_timerevent_t;
-
-struct isc_timerevent {
-       struct isc_event common;
-       isc_time_t       due;
-       ISC_LINK(isc_timerevent_t) ev_timerlink;
-};
-
-#define ISC_TIMEREVENT_TICK (ISC_EVENTCLASS_TIMER + 0)
-#define ISC_TIMEREVENT_ONCE (ISC_EVENTCLASS_TIMER + 1)
-
 /***
  *** Timer and Timer Manager Functions
  ***
@@ -100,55 +81,40 @@ struct isc_timerevent {
  ***/
 
 void
-isc_timer_create(isc_timermgr_t *manager, isc_task_t *task,
-                isc_taskaction_t action, void *arg, isc_timer_t **timerp);
+isc_timer_create(isc_loop_t *loop, isc_job_cb cb, void *cbarg,
+                isc_timer_t **timerp);
 /*%<
- * Create a new 'type' timer managed by 'manager'.  The timers parameters
- * are specified by 'expires' and 'interval'.  Events will be posted to
- * 'task' and when dispatched 'action' will be called with 'arg' as the
- * arg value.  The new timer is returned in 'timerp'.
+ * Create a new 'type' timer managed by 'loop'.  The timers parameters are
+ * specified by 'expires' and 'interval'.  Events will be posted on the isc
+ * event loop and when dispatched 'cb' will be called with 'cbarg' as the arg
+ * value.  The new timer is returned in 'timerp'.
  *
  * Requires:
  *
- *\li  'manager' is a valid manager
- *
- *\li  'task' is a valid task
- *
- *\li  'action' is a valid action
- *
- *\li  'expires' points to a valid time, or is NULL.
- *
- *\li  'interval' points to a valid interval, or is NULL.
- *
- *\li  type == isc_timertype_inactive ||
- *     ('expires' and 'interval' are not both 0)
- *
+ *\li  'loop' is a valid manager
+ *\li  'cb' is a valid job
  *\li  'timerp' is a valid pointer, and *timerp == NULL
  *
  * Ensures:
  *
  *\li  '*timerp' is attached to the newly created timer
+ */
+
+void
+isc_timer_stop(isc_timer_t *timer);
+/*%<
+ * Stop the timer.
  *
- *\li  The timer is attached to the task
- *
- *\li  An idle timeout will not be generated until at least Now + the
- *     timer's interval if 'timer' is a once timer with a non-zero
- *     interval.
- *
- * Returns:
+ * Requires:
  *
- *\li  Success
- *\li  No memory
- *\li  Unexpected error
+ *\li  'timer' is a valid timer
  */
 
-isc_result_t
-isc_timer_reset(isc_timer_t *timer, isc_timertype_t type,
-               const isc_interval_t *interval, bool purge);
+void
+isc_timer_start(isc_timer_t *timer, isc_timertype_t type,
+               const isc_interval_t *interval);
 /*%<
- * Change the timer's type, and interval values to the given
- * values.  If 'purge' is TRUE, any pending events from this timer
- * are purged from its task's event queue.
+ * Start the timer.
  *
  * Notes:
  *
@@ -156,35 +122,28 @@ isc_timer_reset(isc_timer_t *timer, isc_timertype_t type,
  *     'interval' seconds.
  *
  *\li  For once timers, 'interval' specifies how long the timer
- *     can be idle before it generates an idle timeout.  If 0, then no
- *     idle timeout will be generated.
+ *     can be idle before it generates an idle timeout.  If 0, then
+ *     the timer will be run immediately.
  *
  *\li  If 'interval' is NULL, the zero interval will be used.
  *
  * Requires:
  *
  *\li  'timer' is a valid timer
- *
+ *\li  'type' is either 'isc_timertype_ticker' or 'isc_timertype_once'
  *\li  'interval' points to a valid interval, or is NULL.
  *
- *
  * Ensures:
  *
  *\li  An idle timeout will not be generated until at least Now + the
  *     timer's interval if 'timer' is a once timer with a non-zero
  *     interval.
- *
- * Returns:
- *
- *\li  Success
- *\li  No memory
- *\li  Unexpected error
  */
 
 void
 isc_timer_destroy(isc_timer_t **timerp);
 /*%<
- * Destroy *timerp.
+ * Destroy the timer *timerp.
  *
  * Requires:
  *
@@ -193,33 +152,6 @@ isc_timer_destroy(isc_timer_t **timerp);
  * Ensures:
  *
  *\li  *timerp is NULL.
- *
- *\code
- *             The timer will be shutdown
- *
- *             The timer will detach from its task
- *
- *             All resources used by the timer have been freed
- *
- *             Any events already posted by the timer will be purged.
- *             Therefore, if isc_timer_destroy() is called in the context
- *             of the timer's task, it is guaranteed that no more
- *             timer event callbacks will run after the call.
- *
- *             If this function is called from the timer event callback
- *             the event itself must be destroyed before the timer
- *             itself.
- *\endcode
- */
-
-isc_timertype_t
-isc_timer_gettype(isc_timer_t *timer);
-/*%<
- * Return the timer type.
- *
- * Requires:
- *
- *\li  'timer' to be a valid timer.
  */
 
 ISC_LANG_ENDDECLS
index 63ef09e5b40585e60af1b337ecdcdb20144a6bba..b24115da22a6360bf49620d525642272c91197c6 100644 (file)
  * information regarding copyright ownership.
  */
 
+#include <isc/loop.h>
 #include <isc/managers.h>
 #include <isc/util.h>
 
 #include "netmgr_p.h"
 #include "task_p.h"
-#include "timer_p.h"
 
 isc_result_t
 isc_managers_create(isc_mem_t *mctx, size_t workers, size_t quantum,
-                   isc_nm_t **netmgrp, isc_taskmgr_t **taskmgrp,
-                   isc_timermgr_t **timermgrp) {
+                   isc_loopmgr_t **loopmgrp, isc_nm_t **netmgrp,
+                   isc_taskmgr_t **taskmgrp) {
        isc_result_t result;
        isc_nm_t *netmgr = NULL;
        isc_taskmgr_t *taskmgr = NULL;
-       isc_timermgr_t *timermgr = NULL;
 
        REQUIRE(netmgrp != NULL && *netmgrp == NULL);
        isc__netmgr_create(mctx, workers, &netmgr);
@@ -45,28 +44,18 @@ isc_managers_create(isc_mem_t *mctx, size_t workers, size_t quantum,
                *taskmgrp = taskmgr;
        }
 
-       REQUIRE(timermgrp == NULL || *timermgrp == NULL);
-       if (timermgrp != NULL) {
-               result = isc__timermgr_create(mctx, &timermgr);
-               if (result != ISC_R_SUCCESS) {
-                       UNEXPECTED_ERROR(__FILE__, __LINE__,
-                                        "isc_timermgr_create() failed: %s",
-                                        isc_result_totext(result));
-                       goto fail;
-               }
-               *timermgrp = timermgr;
-       }
+       isc_loopmgr_create(mctx, workers, loopmgrp);
 
        return (ISC_R_SUCCESS);
 fail:
-       isc_managers_destroy(netmgrp, taskmgrp, timermgrp);
+       isc_managers_destroy(loopmgrp, netmgrp, taskmgrp);
 
        return (result);
 }
 
 void
-isc_managers_destroy(isc_nm_t **netmgrp, isc_taskmgr_t **taskmgrp,
-                    isc_timermgr_t **timermgrp) {
+isc_managers_destroy(isc_loopmgr_t **loopmgrp, isc_nm_t **netmgrp,
+                    isc_taskmgr_t **taskmgrp) {
        /*
         * If we have a taskmgr to clean up, then we must also have a netmgr.
         */
@@ -109,11 +98,5 @@ isc_managers_destroy(isc_nm_t **netmgrp, isc_taskmgr_t **taskmgrp,
                isc__netmgr_destroy(netmgrp);
        }
 
-       /*
-        * 5. Clean up the remaining managers.
-        */
-       if (timermgrp != NULL) {
-               INSIST(*timermgrp != NULL);
-               isc__timermgr_destroy(timermgrp);
-       }
+       isc_loopmgr_destroy(loopmgrp);
 }
index 138761720559913eab5edcbe38963a726c9c0332..d263b255f3d60e20138d8f69fdc52934a035fef0 100644 (file)
@@ -16,6 +16,9 @@
 #include <inttypes.h>
 #include <stdbool.h>
 
+#include <isc/async.h>
+#include <isc/event.h>
+#include <isc/loop.h>
 #include <isc/mem.h>
 #include <isc/ratelimiter.h>
 #include <isc/refcount.h>
 #include <isc/util.h>
 
 typedef enum {
-       isc_ratelimiter_stalled = 0,
-       isc_ratelimiter_ratelimited = 1,
-       isc_ratelimiter_idle = 2,
-       isc_ratelimiter_shuttingdown = 3
+       isc_ratelimiter_ratelimited = 0,
+       isc_ratelimiter_idle = 1,
+       isc_ratelimiter_shuttingdown = 2
 } isc_ratelimiter_state_t;
 
 struct isc_ratelimiter {
        isc_mem_t *mctx;
        isc_mutex_t lock;
-       isc_refcount_t references;
-       isc_task_t *task;
+       isc_loopmgr_t *loopmgr;
        isc_timer_t *timer;
        isc_interval_t interval;
        uint32_t pertic;
        bool pushpop;
        isc_ratelimiter_state_t state;
-       isc_event_t shutdownevent;
        ISC_LIST(isc_event_t) pending;
 };
 
-#define ISC_RATELIMITEREVENT_SHUTDOWN (ISC_EVENTCLASS_RATELIMITER + 1)
-
-static void
-ratelimiter_tick(isc_task_t *task, isc_event_t *event);
-
 static void
-ratelimiter_shutdowncomplete(isc_task_t *task, isc_event_t *event);
+ratelimiter_tick(void *arg);
 
 isc_result_t
-isc_ratelimiter_create(isc_mem_t *mctx, isc_timermgr_t *timermgr,
-                      isc_task_t *task, isc_ratelimiter_t **ratelimiterp) {
-       isc_ratelimiter_t *rl;
+isc_ratelimiter_create(isc_loop_t *loop, isc_ratelimiter_t **ratelimiterp) {
+       isc_ratelimiter_t *rl = NULL;
+       isc_mem_t *mctx = isc_loop_getmctx(loop);
+
        INSIST(ratelimiterp != NULL && *ratelimiterp == NULL);
 
        rl = isc_mem_get(mctx, sizeof(*rl));
        *rl = (isc_ratelimiter_t){
-               .mctx = mctx,
-               .task = task,
                .pertic = 1,
                .state = isc_ratelimiter_idle,
        };
 
-       isc_refcount_init(&rl->references, 1);
+       isc_mem_attach(mctx, &rl->mctx);
        isc_interval_set(&rl->interval, 0, 0);
        ISC_LIST_INIT(rl->pending);
 
        isc_mutex_init(&rl->lock);
 
-       isc_timer_create(timermgr, rl->task, ratelimiter_tick, rl, &rl->timer);
-
-       /*
-        * Increment the reference count to indicate that we may
-        * (soon) have events outstanding.
-        */
-       isc_refcount_increment(&rl->references);
-
-       ISC_EVENT_INIT(&rl->shutdownevent, sizeof(isc_event_t), 0,
-                      ISC_RATELIMITEREVENT_SHUTDOWN,
-                      ratelimiter_shutdowncomplete, rl, rl, NULL, NULL);
+       isc_timer_create(loop, ratelimiter_tick, rl, &rl->timer);
 
        *ratelimiterp = rl;
        return (ISC_R_SUCCESS);
 }
 
-isc_result_t
+void
 isc_ratelimiter_setinterval(isc_ratelimiter_t *rl, isc_interval_t *interval) {
-       isc_result_t result = ISC_R_SUCCESS;
-
        REQUIRE(rl != NULL);
        REQUIRE(interval != NULL);
 
@@ -102,63 +84,63 @@ isc_ratelimiter_setinterval(isc_ratelimiter_t *rl, isc_interval_t *interval) {
         * If the timer is currently running, change its rate.
         */
        if (rl->state == isc_ratelimiter_ratelimited) {
-               result = isc_timer_reset(rl->timer, isc_timertype_ticker,
-                                        &rl->interval, false);
+               isc_timer_start(rl->timer, isc_timertype_ticker, &rl->interval);
        }
        UNLOCK(&rl->lock);
-       return (result);
 }
 
 void
 isc_ratelimiter_setpertic(isc_ratelimiter_t *rl, uint32_t pertic) {
        REQUIRE(rl != NULL);
+       REQUIRE(pertic > 0);
 
-       if (pertic == 0) {
-               pertic = 1;
-       }
+       LOCK(&rl->lock);
        rl->pertic = pertic;
+       UNLOCK(&rl->lock);
 }
 
 void
 isc_ratelimiter_setpushpop(isc_ratelimiter_t *rl, bool pushpop) {
        REQUIRE(rl != NULL);
 
+       LOCK(&rl->lock);
        rl->pushpop = pushpop;
+       UNLOCK(&rl->lock);
 }
 
 isc_result_t
 isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_task_t *task,
                        isc_event_t **eventp) {
        isc_result_t result = ISC_R_SUCCESS;
-       isc_event_t *ev;
+       isc_event_t *event;
 
        REQUIRE(rl != NULL);
        REQUIRE(task != NULL);
        REQUIRE(eventp != NULL && *eventp != NULL);
-       ev = *eventp;
-       REQUIRE(ev->ev_sender == NULL);
+       event = *eventp;
+       REQUIRE(event->ev_sender == NULL);
 
        LOCK(&rl->lock);
-       if (rl->state == isc_ratelimiter_ratelimited ||
-           rl->state == isc_ratelimiter_stalled)
-       {
-               ev->ev_sender = task;
+       switch (rl->state) {
+       case isc_ratelimiter_shuttingdown:
+               result = ISC_R_SHUTTINGDOWN;
+               break;
+       case isc_ratelimiter_ratelimited:
+               event->ev_sender = task;
                *eventp = NULL;
                if (rl->pushpop) {
-                       ISC_LIST_PREPEND(rl->pending, ev, ev_ratelink);
+                       ISC_LIST_PREPEND(rl->pending, event, ev_ratelink);
                } else {
-                       ISC_LIST_APPEND(rl->pending, ev, ev_ratelink);
-               }
-       } else if (rl->state == isc_ratelimiter_idle) {
-               result = isc_timer_reset(rl->timer, isc_timertype_ticker,
-                                        &rl->interval, false);
-               if (result == ISC_R_SUCCESS) {
-                       ev->ev_sender = task;
-                       rl->state = isc_ratelimiter_ratelimited;
+                       ISC_LIST_APPEND(rl->pending, event, ev_ratelink);
                }
-       } else {
-               INSIST(rl->state == isc_ratelimiter_shuttingdown);
-               result = ISC_R_SHUTTINGDOWN;
+               break;
+       case isc_ratelimiter_idle:
+               isc_timer_start(rl->timer, isc_timertype_ticker, &rl->interval);
+               event->ev_sender = task;
+               rl->state = isc_ratelimiter_ratelimited;
+               break;
+       default:
+               UNREACHABLE();
        }
        UNLOCK(&rl->lock);
        if (*eventp != NULL && result == ISC_R_SUCCESS) {
@@ -181,114 +163,73 @@ isc_ratelimiter_dequeue(isc_ratelimiter_t *rl, isc_event_t *event) {
        } else {
                result = ISC_R_NOTFOUND;
        }
+
+       if (ISC_LIST_EMPTY(rl->pending)) {
+               /* No work left to do.  Stop the timer. */
+               isc_timer_stop(rl->timer);
+               rl->state = isc_ratelimiter_idle;
+       }
        UNLOCK(&rl->lock);
+
        return (result);
 }
 
 static void
-ratelimiter_tick(isc_task_t *task, isc_event_t *event) {
-       isc_ratelimiter_t *rl = (isc_ratelimiter_t *)event->ev_arg;
-       isc_event_t *p;
+ratelimiter_tick(void *arg) {
+       isc_ratelimiter_t *rl = (isc_ratelimiter_t *)arg;
+       isc_event_t *event;
        uint32_t pertic;
 
-       UNUSED(task);
-
-       isc_event_free(&event);
-
        pertic = rl->pertic;
        while (pertic != 0) {
                pertic--;
                LOCK(&rl->lock);
-               p = ISC_LIST_HEAD(rl->pending);
-               if (p != NULL) {
+               event = ISC_LIST_HEAD(rl->pending);
+               if (event != NULL) {
                        /*
                         * There is work to do.  Let's do it after unlocking.
                         */
-                       ISC_LIST_UNLINK(rl->pending, p, ev_ratelink);
+                       ISC_LIST_UNLINK(rl->pending, event, ev_ratelink);
                } else {
-                       /*
-                        * No work left to do.  Stop the timer so that we don't
-                        * waste resources by having it fire periodically.
-                        */
-                       isc_result_t result = isc_timer_reset(
-                               rl->timer, isc_timertype_inactive, NULL, false);
-                       RUNTIME_CHECK(result == ISC_R_SUCCESS);
+                       /* No work left to do.  Stop the timer. */
+                       isc_timer_stop(rl->timer);
                        rl->state = isc_ratelimiter_idle;
                        pertic = 0; /* Force the loop to exit. */
                }
                UNLOCK(&rl->lock);
-               if (p != NULL) {
-                       isc_task_t *evtask = p->ev_sender;
-                       isc_task_send(evtask, &p);
+               if (event != NULL) {
+                       isc_task_send(event->ev_sender, &event);
                }
-               INSIST(p == NULL);
+               INSIST(event == NULL);
        }
 }
 
 void
 isc_ratelimiter_shutdown(isc_ratelimiter_t *rl) {
-       isc_event_t *ev;
-       isc_task_t *task;
-       isc_result_t result;
+       isc_event_t *event;
 
        REQUIRE(rl != NULL);
 
        LOCK(&rl->lock);
        rl->state = isc_ratelimiter_shuttingdown;
-       (void)isc_timer_reset(rl->timer, isc_timertype_inactive, NULL, false);
-       while ((ev = ISC_LIST_HEAD(rl->pending)) != NULL) {
-               task = ev->ev_sender;
-               ISC_LIST_UNLINK(rl->pending, ev, ev_ratelink);
-               ev->ev_attributes |= ISC_EVENTATTR_CANCELED;
-               isc_task_send(task, &ev);
-       }
-       task = NULL;
-       isc_task_attach(rl->task, &task);
-
-       result = isc_timer_reset(rl->timer, isc_timertype_inactive, NULL,
-                                false);
-       RUNTIME_CHECK(result == ISC_R_SUCCESS);
+       isc_timer_stop(rl->timer);
        isc_timer_destroy(&rl->timer);
 
-       /*
-        * Send an event to our task.  The delivery of this event
-        * indicates that no more timer events will be delivered.
-        */
-       ev = &rl->shutdownevent;
-       isc_task_send(rl->task, &ev);
-
-       UNLOCK(&rl->lock);
-}
-
-static void
-ratelimiter_shutdowncomplete(isc_task_t *task, isc_event_t *event) {
-       isc_ratelimiter_t *rl = (isc_ratelimiter_t *)event->ev_arg;
-
-       UNUSED(task);
-
-       isc_ratelimiter_detach(&rl);
-       isc_task_detach(&task);
-}
-
-static void
-ratelimiter_free(isc_ratelimiter_t *rl) {
-       isc_refcount_destroy(&rl->references);
-       isc_mutex_destroy(&rl->lock);
-       isc_mem_put(rl->mctx, rl, sizeof(*rl));
-}
+       while ((event = ISC_LIST_HEAD(rl->pending)) != NULL) {
+               ISC_LIST_UNLINK(rl->pending, event, ev_ratelink);
+               UNLOCK(&rl->lock);
 
-void
-isc_ratelimiter_attach(isc_ratelimiter_t *source, isc_ratelimiter_t **target) {
-       REQUIRE(source != NULL);
-       REQUIRE(target != NULL && *target == NULL);
+               event->ev_attributes |= ISC_EVENTATTR_CANCELED;
+               isc_task_send(event->ev_sender, &event);
 
-       isc_refcount_increment(&source->references);
+               LOCK(&rl->lock);
+       }
 
-       *target = source;
+       UNLOCK(&rl->lock);
 }
 
 void
-isc_ratelimiter_detach(isc_ratelimiter_t **rlp) {
+isc_ratelimiter_destroy(isc_ratelimiter_t **rlp) {
        isc_ratelimiter_t *rl;
 
        REQUIRE(rlp != NULL && *rlp != NULL);
@@ -296,63 +237,10 @@ isc_ratelimiter_detach(isc_ratelimiter_t **rlp) {
        rl = *rlp;
        *rlp = NULL;
 
-       if (isc_refcount_decrement(&rl->references) == 1) {
-               ratelimiter_free(rl);
-       }
-}
-
-isc_result_t
-isc_ratelimiter_stall(isc_ratelimiter_t *rl) {
-       isc_result_t result = ISC_R_SUCCESS;
-
-       REQUIRE(rl != NULL);
-
        LOCK(&rl->lock);
-       switch (rl->state) {
-       case isc_ratelimiter_shuttingdown:
-               result = ISC_R_SHUTTINGDOWN;
-               break;
-       case isc_ratelimiter_ratelimited:
-               result = isc_timer_reset(rl->timer, isc_timertype_inactive,
-                                        NULL, false);
-               RUNTIME_CHECK(result == ISC_R_SUCCESS);
-               FALLTHROUGH;
-       case isc_ratelimiter_idle:
-       case isc_ratelimiter_stalled:
-               rl->state = isc_ratelimiter_stalled;
-               break;
-       }
+       REQUIRE(rl->state == isc_ratelimiter_shuttingdown);
        UNLOCK(&rl->lock);
-       return (result);
-}
-
-isc_result_t
-isc_ratelimiter_release(isc_ratelimiter_t *rl) {
-       isc_result_t result = ISC_R_SUCCESS;
 
-       REQUIRE(rl != NULL);
-
-       LOCK(&rl->lock);
-       switch (rl->state) {
-       case isc_ratelimiter_shuttingdown:
-               result = ISC_R_SHUTTINGDOWN;
-               break;
-       case isc_ratelimiter_stalled:
-               if (!ISC_LIST_EMPTY(rl->pending)) {
-                       result = isc_timer_reset(rl->timer,
-                                                isc_timertype_ticker,
-                                                &rl->interval, false);
-                       if (result == ISC_R_SUCCESS) {
-                               rl->state = isc_ratelimiter_ratelimited;
-                       }
-               } else {
-                       rl->state = isc_ratelimiter_idle;
-               }
-               break;
-       case isc_ratelimiter_ratelimited:
-       case isc_ratelimiter_idle:
-               break;
-       }
-       UNLOCK(&rl->lock);
-       return (result);
+       isc_mutex_destroy(&rl->lock);
+       isc_mem_putanddetach(&rl->mctx, rl, sizeof(*rl));
 }
index d05abe99a4c0089bb4b044e1634b7d20363ea570..54df9684d27678ffe416c23a8683a287e3b4c2c1 100644 (file)
 
 #include <stdbool.h>
 
-#include <isc/app.h>
+#include <isc/async.h>
 #include <isc/condition.h>
 #include <isc/heap.h>
+#include <isc/job.h>
 #include <isc/log.h>
 #include <isc/magic.h>
 #include <isc/mem.h>
 #include <isc/time.h>
 #include <isc/timer.h>
 #include <isc/util.h>
+#include <isc/uv.h>
 
-#include "timer_p.h"
-
-#ifdef ISC_TIMER_TRACE
-#define XTRACE(s)      fprintf(stderr, "%s\n", (s))
-#define XTRACEID(s, t) fprintf(stderr, "%s %p\n", (s), (t))
-#define XTRACETIME(s, d) \
-       fprintf(stderr, "%s %u.%09u\n", (s), (d).seconds, (d).nanoseconds)
-#define XTRACETIME2(s, d, n)                                      \
-       fprintf(stderr, "%s %u.%09u %u.%09u\n", (s), (d).seconds, \
-               (d).nanoseconds, (n).seconds, (n).nanoseconds)
-#define XTRACETIMER(s, t, d)                                      \
-       fprintf(stderr, "%s %p %u.%09u\n", (s), (t), (d).seconds, \
-               (d).nanoseconds)
-#else /* ifdef ISC_TIMER_TRACE */
-#define XTRACE(s)
-#define XTRACEID(s, t)
-#define XTRACETIME(s, d)
-#define XTRACETIME2(s, d, n)
-#define XTRACETIMER(s, t, d)
-#endif /* ISC_TIMER_TRACE */
+#include "loop_p.h"
 
 #define TIMER_MAGIC    ISC_MAGIC('T', 'I', 'M', 'R')
 #define VALID_TIMER(t) ISC_MAGIC_VALID(t, TIMER_MAGIC)
 
 struct isc_timer {
-       /*! Not locked. */
        unsigned int magic;
-       isc_timermgr_t *manager;
-       isc_mutex_t lock;
-       /*! Locked by timer lock. */
-       isc_time_t idle;
-       ISC_LIST(isc_timerevent_t) active;
-       /*! Locked by manager lock. */
-       isc_timertype_t type;
-       isc_interval_t interval;
-       isc_task_t *task;
-       isc_taskaction_t action;
-       void *arg;
-       unsigned int index;
-       isc_time_t due;
-       LINK(isc_timer_t) link;
-};
-
-#define TIMER_MANAGER_MAGIC ISC_MAGIC('T', 'I', 'M', 'M')
-#define VALID_MANAGER(m)    ISC_MAGIC_VALID(m, TIMER_MANAGER_MAGIC)
-
-struct isc_timermgr {
-       /* Not locked. */
-       unsigned int magic;
-       isc_mem_t *mctx;
-       isc_mutex_t lock;
-       /* Locked by manager lock. */
-       bool done;
-       LIST(isc_timer_t) timers;
-       unsigned int nscheduled;
-       isc_time_t due;
-       isc_condition_t wakeup;
-       isc_thread_t thread;
-       isc_heap_t *heap;
-};
-
-static isc_result_t
-schedule(isc_timer_t *timer, isc_time_t *now, bool signal_ok) {
-       isc_timermgr_t *manager;
-       isc_time_t due;
-       isc_result_t result = ISC_R_SUCCESS;
-
-       /*!
-        * Note: the caller must ensure locking.
-        */
-
-       manager = timer->manager;
-
-       /*
-        * Compute the new due time.
-        */
-       switch (timer->type) {
-       case isc_timertype_ticker:
-               result = isc_time_add(now, &timer->interval, &due);
-               if (result != ISC_R_SUCCESS) {
-                       return (result);
-               }
-               break;
-       case isc_timertype_once:
-               due = timer->idle;
-               break;
-       default:
-               UNREACHABLE();
-       }
+       isc_refcount_t references;
+       isc_loop_t *loop;
+       uv_timer_t timer;
+       isc_job_cb cb;
+       void *cbarg;
 
        /*
-        * Schedule the timer.
+        * We are locking the values here for now, but this needs to go away
+        * when the timers are pinned to the respective loops.
         */
-
-       if (timer->index > 0) {
-               /*
-                * Already scheduled.
-                */
-               int cmp = isc_time_compare(&due, &timer->due);
-               timer->due = due;
-               switch (cmp) {
-               case -1:
-                       isc_heap_increased(manager->heap, timer->index);
-                       break;
-               case 1:
-                       isc_heap_decreased(manager->heap, timer->index);
-                       break;
-               case 0:
-                       /* Nothing to do. */
-                       break;
-               }
-       } else {
-               timer->due = due;
-               isc_heap_insert(manager->heap, timer);
-               manager->nscheduled++;
-       }
-
-       XTRACETIMER("schedule", timer, due);
-
-       /*
-        * If this timer is at the head of the queue, we need to ensure
-        * that we won't miss it if it has a more recent due time than
-        * the current "next" timer.  We do this either by waking up the
-        * run thread, or explicitly setting the value in the manager.
-        */
-
-       if (timer->index == 1 && signal_ok) {
-               XTRACE("signal (schedule)");
-               SIGNAL(&manager->wakeup);
-       }
-
-       return (result);
-}
-
-static void
-deschedule(isc_timer_t *timer) {
-       isc_timermgr_t *manager;
-
-       /*
-        * The caller must ensure locking.
-        */
-
-       manager = timer->manager;
-       if (timer->index > 0) {
-               bool need_wakeup = false;
-               if (timer->index == 1) {
-                       need_wakeup = true;
-               }
-               isc_heap_delete(manager->heap, timer->index);
-               timer->index = 0;
-               INSIST(manager->nscheduled > 0);
-               manager->nscheduled--;
-               if (need_wakeup) {
-                       XTRACE("signal (deschedule)");
-                       SIGNAL(&manager->wakeup);
-               }
-       }
-}
-
-static void
-timerevent_unlink(isc_timer_t *timer, isc_timerevent_t *event) {
-       REQUIRE(ISC_LINK_LINKED(event, ev_timerlink));
-       ISC_LIST_UNLINK(timer->active, event, ev_timerlink);
-}
+       isc_mutex_t lock;
+       uint64_t timeout;
+       uint64_t repeat;
+};
 
 static void
-timerevent_destroy(isc_event_t *event0) {
-       isc_timer_t *timer = event0->ev_destroy_arg;
-       isc_timerevent_t *event = (isc_timerevent_t *)event0;
-
-       LOCK(&timer->lock);
-       if (ISC_LINK_LINKED(event, ev_timerlink)) {
-               /* The event was unlinked via timer_purge() */
-               timerevent_unlink(timer, event);
-       }
-       UNLOCK(&timer->lock);
+isc__timer_detach(isc_timer_t **timerp);
 
-       isc_mem_put(timer->manager->mctx, event, event0->ev_size);
-}
+void
+isc_timer_create(isc_loop_t *loop, isc_job_cb cb, void *cbarg,
+                isc_timer_t **timerp) {
+       int r;
+       isc_timer_t *timer = NULL;
+       isc_loopmgr_t *loopmgr = NULL;
 
-static void
-timer_purge(isc_timer_t *timer) {
-       isc_timerevent_t *event = NULL;
-
-       while ((event = ISC_LIST_HEAD(timer->active)) != NULL) {
-               timerevent_unlink(timer, event);
-               UNLOCK(&timer->lock);
-               (void)isc_task_purgeevent(timer->task, (isc_event_t *)event);
-               LOCK(&timer->lock);
-       }
-}
+       REQUIRE(cb != NULL);
+       REQUIRE(timerp != NULL && *timerp == NULL);
 
-void
-isc_timer_create(isc_timermgr_t *manager, isc_task_t *task,
-                isc_taskaction_t action, void *arg, isc_timer_t **timerp) {
-       REQUIRE(VALID_MANAGER(manager));
-       REQUIRE(task != NULL);
-       REQUIRE(action != NULL);
+       REQUIRE(VALID_LOOP(loop));
 
-       isc_timer_t *timer;
-       isc_time_t now;
+       loopmgr = loop->loopmgr;
 
-       REQUIRE(timerp != NULL && *timerp == NULL);
+       REQUIRE(VALID_LOOPMGR(loopmgr));
 
-       /*
-        * Get current time.
-        */
-       TIME_NOW(&now);
+       REQUIRE(loop == isc_loop_current(loopmgr) ||
+               !atomic_load(&loopmgr->running) ||
+               atomic_load(&loopmgr->paused) > 0);
 
-       timer = isc_mem_get(manager->mctx, sizeof(*timer));
+       timer = isc_mem_get(loop->mctx, sizeof(*timer));
        *timer = (isc_timer_t){
-               .manager = manager,
-               .type = isc_timertype_inactive,
-               .interval = *isc_interval_zero,
-               .action = action,
-               .arg = arg,
+               .cb = cb,
+               .cbarg = cbarg,
        };
 
-       isc_time_settoepoch(&timer->idle);
+       isc_loop_attach(loop, &timer->loop);
 
-       isc_task_attach(task, &timer->task);
+       isc_refcount_init(&timer->references, 1);
 
        isc_mutex_init(&timer->lock);
-       ISC_LINK_INIT(timer, link);
-
-       ISC_LIST_INIT(timer->active);
 
        timer->magic = TIMER_MAGIC;
 
-       /*
-        * Note we don't have to lock the timer like we normally would because
-        * there are no external references to it yet.
-        */
+       r = uv_timer_init(&timer->loop->loop, &timer->timer);
+       UV_RUNTIME_CHECK(uv_timer_init, r);
+       uv_handle_set_data(&timer->timer, timer);
 
        *timerp = timer;
-
-       LOCK(&manager->lock);
-       APPEND(manager->timers, timer, link);
-       UNLOCK(&manager->lock);
 }
 
-isc_result_t
-isc_timer_reset(isc_timer_t *timer, isc_timertype_t type,
-               const isc_interval_t *interval, bool purge) {
-       isc_time_t now;
-       isc_timermgr_t *manager;
-       isc_result_t result;
-
-       /*
-        * Change the timer's type, expires, and interval values to the given
-        * values.  If 'purge' is true, any pending events from this timer
-        * are purged from its task's event queue.
-        */
+static void
+isc__timer_stop(void *arg) {
+       isc_timer_t *timer = (isc_timer_t *)arg;
+       uv_timer_stop(&timer->timer);
+       isc__timer_detach(&timer);
+}
 
+void
+isc_timer_stop(isc_timer_t *timer) {
        REQUIRE(VALID_TIMER(timer));
-       manager = timer->manager;
-       REQUIRE(VALID_MANAGER(manager));
 
-       if (interval == NULL) {
-               interval = isc_interval_zero;
-       }
-       REQUIRE(type == isc_timertype_inactive ||
-               !isc_interval_iszero(interval));
-
-       /*
-        * Get current time.
-        */
-       if (type != isc_timertype_inactive) {
-               TIME_NOW(&now);
-       } else {
-               /*
-                * We don't have to do this, but it keeps the compiler from
-                * complaining about "now" possibly being used without being
-                * set, even though it will never actually happen.
-                */
-               isc_time_settoepoch(&now);
-       }
-
-       LOCK(&manager->lock);
-       LOCK(&timer->lock);
-
-       if (purge) {
-               timer_purge(timer);
-       }
-       timer->type = type;
-       timer->interval = *interval;
-       if (type == isc_timertype_once && !isc_interval_iszero(interval)) {
-               result = isc_time_add(&now, interval, &timer->idle);
+       isc_refcount_increment(&timer->references);
+       if (timer->loop == isc_loop_current(timer->loop->loopmgr)) {
+               isc__timer_stop(timer);
        } else {
-               isc_time_settoepoch(&timer->idle);
-               result = ISC_R_SUCCESS;
+               isc_async_run(timer->loop, isc__timer_stop, timer);
        }
+}
 
-       if (result == ISC_R_SUCCESS) {
-               if (type == isc_timertype_inactive) {
-                       deschedule(timer);
-                       result = ISC_R_SUCCESS;
-               } else {
-                       result = schedule(timer, &now, true);
-               }
-       }
+static void
+timer_cb(uv_timer_t *handle) {
+       isc_timer_t *timer = uv_handle_get_data(handle);
 
-       UNLOCK(&timer->lock);
-       UNLOCK(&manager->lock);
+       REQUIRE(VALID_TIMER(timer));
 
-       return (result);
+       timer->cb(timer->cbarg);
 }
 
-isc_timertype_t
-isc_timer_gettype(isc_timer_t *timer) {
-       isc_timertype_t t;
-
-       REQUIRE(VALID_TIMER(timer));
+static void
+isc__timer_start(void *arg) {
+       isc_timer_t *timer = (isc_timer_t *)arg;
 
        LOCK(&timer->lock);
-       t = timer->type;
+       int r = uv_timer_start(&timer->timer, timer_cb, timer->timeout,
+                              timer->repeat);
+       UV_RUNTIME_CHECK(uv_timer_start, r);
        UNLOCK(&timer->lock);
 
-       return (t);
+       isc__timer_detach(&timer);
 }
 
 void
-isc_timer_destroy(isc_timer_t **timerp) {
-       isc_timer_t *timer = NULL;
-       isc_timermgr_t *manager = NULL;
+isc_timer_start(isc_timer_t *timer, isc_timertype_t type,
+               const isc_interval_t *interval) {
+       isc_loopmgr_t *loopmgr = NULL;
+       isc_loop_t *loop = NULL;
 
-       REQUIRE(timerp != NULL && VALID_TIMER(*timerp));
+       REQUIRE(VALID_TIMER(timer));
+       REQUIRE(type == isc_timertype_ticker || type == isc_timertype_once);
 
-       timer = *timerp;
-       *timerp = NULL;
+       loop = timer->loop;
 
-       manager = timer->manager;
+       REQUIRE(VALID_LOOP(loop));
 
-       LOCK(&manager->lock);
+       loopmgr = loop->loopmgr;
+
+       REQUIRE(VALID_LOOPMGR(loopmgr));
 
        LOCK(&timer->lock);
-       timer_purge(timer);
-       deschedule(timer);
+       switch (type) {
+       case isc_timertype_once:
+               timer->timeout = isc_interval_ms(interval);
+               timer->repeat = 0;
+               break;
+       case isc_timertype_ticker:
+               timer->timeout = timer->repeat = isc_interval_ms(interval);
+               break;
+       default:
+               UNREACHABLE();
+       }
        UNLOCK(&timer->lock);
 
-       UNLINK(manager->timers, timer, link);
-
-       UNLOCK(&manager->lock);
-
-       isc_task_detach(&timer->task);
-       isc_mutex_destroy(&timer->lock);
-       timer->magic = 0;
-       isc_mem_put(manager->mctx, timer, sizeof(*timer));
+       isc_refcount_increment(&timer->references);
+       if (timer->loop == isc_loop_current(timer->loop->loopmgr)) {
+               isc__timer_start(timer);
+       } else {
+               isc_async_run(timer->loop, isc__timer_start, timer);
+       }
 }
 
 static void
-post_event(isc_timermgr_t *manager, isc_timer_t *timer, isc_eventtype_t type) {
-       isc_timerevent_t *event;
-       XTRACEID("posting", timer);
+timer_destroy(uv_handle_t *handle) {
+       isc_timer_t *timer = uv_handle_get_data(handle);
+       isc_loop_t *loop;
 
-       event = (isc_timerevent_t *)isc_event_allocate(
-               manager->mctx, timer, type, timer->action, timer->arg,
-               sizeof(*event));
+       REQUIRE(VALID_TIMER(timer));
 
-       ISC_LINK_INIT(event, ev_timerlink);
-       ((isc_event_t *)event)->ev_destroy = timerevent_destroy;
-       ((isc_event_t *)event)->ev_destroy_arg = timer;
+       loop = timer->loop;
 
-       event->due = timer->due;
+       isc_refcount_destroy(&timer->references);
+       isc_mutex_destroy(&timer->lock);
 
-       LOCK(&timer->lock);
-       ISC_LIST_APPEND(timer->active, event, ev_timerlink);
-       UNLOCK(&timer->lock);
+       isc_mem_put(loop->mctx, timer, sizeof(*timer));
 
-       isc_task_send(timer->task, ISC_EVENT_PTR(&event));
+       isc_loop_detach(&loop);
 }
 
 static void
-dispatch(isc_timermgr_t *manager, isc_time_t *now) {
-       bool need_schedule;
-       isc_eventtype_t type = 0;
-       isc_timer_t *timer;
-       isc_result_t result;
-
-       /*!
-        * The caller must be holding the manager lock.
-        */
-
-       while (manager->nscheduled > 0) {
-               timer = isc_heap_element(manager->heap, 1);
-               INSIST(timer != NULL && timer->type != isc_timertype_inactive);
-
-               if (isc_time_compare(now, &timer->due) < 0) {
-                       manager->due = timer->due;
-                       break;
-               }
+isc__timer_destroy(void *arg) {
+       isc_timer_t *timer = (isc_timer_t *)arg;
 
-               switch (timer->type) {
-               case isc_timertype_ticker:
-                       type = ISC_TIMEREVENT_TICK;
-                       post_event(manager, timer, type);
-                       need_schedule = true;
-                       break;
-               case isc_timertype_once:
-                       type = ISC_TIMEREVENT_ONCE;
-                       post_event(manager, timer, type);
-                       need_schedule = false;
-                       break;
-               default:
-                       UNREACHABLE();
-               }
-
-               timer->index = 0;
-               isc_heap_delete(manager->heap, 1);
-               manager->nscheduled--;
-
-               if (need_schedule) {
-                       result = schedule(timer, now, false);
-                       if (result != ISC_R_SUCCESS) {
-                               UNEXPECTED_ERROR(__FILE__, __LINE__, "%s: %u",
-                                                "couldn't schedule "
-                                                "timer",
-                                                result);
-                       }
-               }
-       }
+       uv_timer_stop(&timer->timer);
+       uv_close(&timer->timer, timer_destroy);
 }
 
-static isc_threadresult_t
-run(void *uap) {
-       isc_timermgr_t *manager = uap;
-       isc_time_t now;
-       isc_result_t result;
-
-       LOCK(&manager->lock);
-       while (!manager->done) {
-               TIME_NOW(&now);
+static void
+isc__timer_detach(isc_timer_t **timerp) {
+       isc_timer_t *timer = NULL;
 
-               XTRACETIME("running", now);
+       REQUIRE(timerp != NULL && VALID_TIMER(*timerp));
 
-               dispatch(manager, &now);
+       timer = *timerp;
+       *timerp = NULL;
 
-               if (manager->nscheduled > 0) {
-                       XTRACETIME2("waituntil", manager->due, now);
-                       result = WAITUNTIL(&manager->wakeup, &manager->lock,
-                                          &manager->due);
-                       INSIST(result == ISC_R_SUCCESS ||
-                              result == ISC_R_TIMEDOUT);
+       if (isc_refcount_decrement(&timer->references) == 1) {
+               if (timer->loop == isc_loop_current(timer->loop->loopmgr)) {
+                       isc__timer_destroy(timer);
                } else {
-                       XTRACETIME("wait", now);
-                       WAIT(&manager->wakeup, &manager->lock);
+                       isc_async_run(timer->loop, isc__timer_destroy, timer);
                }
-               XTRACE("wakeup");
-       }
-       UNLOCK(&manager->lock);
-
-       return ((isc_threadresult_t)0);
-}
-
-static bool
-sooner(void *v1, void *v2) {
-       isc_timer_t *t1, *t2;
-
-       t1 = v1;
-       t2 = v2;
-       REQUIRE(VALID_TIMER(t1));
-       REQUIRE(VALID_TIMER(t2));
-
-       if (isc_time_compare(&t1->due, &t2->due) < 0) {
-               return (true);
        }
-       return (false);
-}
-
-static void
-set_index(void *what, unsigned int index) {
-       isc_timer_t *timer;
-
-       REQUIRE(VALID_TIMER(what));
-       timer = what;
-
-       timer->index = index;
-}
-
-isc_result_t
-isc__timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) {
-       isc_timermgr_t *manager;
-
-       /*
-        * Create a timer manager.
-        */
-
-       REQUIRE(managerp != NULL && *managerp == NULL);
-
-       manager = isc_mem_get(mctx, sizeof(*manager));
-
-       manager->magic = TIMER_MANAGER_MAGIC;
-       manager->mctx = NULL;
-       manager->done = false;
-       INIT_LIST(manager->timers);
-       manager->nscheduled = 0;
-       isc_time_settoepoch(&manager->due);
-       manager->heap = NULL;
-       isc_heap_create(mctx, sooner, set_index, 0, &manager->heap);
-       isc_mutex_init(&manager->lock);
-       isc_mem_attach(mctx, &manager->mctx);
-       isc_condition_init(&manager->wakeup);
-       isc_thread_create(run, manager, &manager->thread);
-       isc_thread_setname(manager->thread, "isc-timer");
-
-       *managerp = manager;
-
-       return (ISC_R_SUCCESS);
 }
 
 void
-isc__timermgr_destroy(isc_timermgr_t **managerp) {
-       isc_timermgr_t *manager;
-
-       /*
-        * Destroy a timer manager.
-        */
-
-       REQUIRE(managerp != NULL);
-       manager = *managerp;
-       REQUIRE(VALID_MANAGER(manager));
-
-       LOCK(&manager->lock);
-
-       REQUIRE(EMPTY(manager->timers));
-       manager->done = true;
-
-       XTRACE("signal (destroy)");
-       SIGNAL(&manager->wakeup);
-
-       UNLOCK(&manager->lock);
-
-       /*
-        * Wait for thread to exit.
-        */
-       isc_thread_join(manager->thread, NULL);
-
-       /*
-        * Clean up.
-        */
-       isc_condition_destroy(&manager->wakeup);
-       isc_mutex_destroy(&manager->lock);
-       isc_heap_destroy(&manager->heap);
-       manager->magic = 0;
-       isc_mem_putanddetach(&manager->mctx, manager, sizeof(*manager));
-
-       *managerp = NULL;
+isc_timer_destroy(isc_timer_t **timerp) {
+       isc__timer_detach(timerp);
 }
diff --git a/lib/isc/timer_p.h b/lib/isc/timer_p.h
deleted file mode 100644 (file)
index ab9bf9c..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
- *
- * SPDX-License-Identifier: MPL-2.0
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, you can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * See the COPYRIGHT file distributed with this work for additional
- * information regarding copyright ownership.
- */
-
-#pragma once
-
-#include <isc/mem.h>
-#include <isc/result.h>
-#include <isc/timer.h>
-
-isc_result_t
-isc__timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp);
-/*%<
- * Create a timer manager.
- *
- * Notes:
- *
- *\li  All memory will be allocated in memory context 'mctx'.
- *
- * Requires:
- *
- *\li  'mctx' is a valid memory context.
- *
- *\li  'managerp' points to a NULL isc_timermgr_t.
- *
- * Ensures:
- *
- *\li  '*managerp' is a valid isc_timermgr_t.
- *
- * Returns:
- *
- *\li  Success
- *\li  No memory
- *\li  Unexpected error
- */
-
-void
-isc__timermgr_destroy(isc_timermgr_t **managerp);
-/*%<
- * Destroy a timer manager.
- *
- * Notes:
- *
- *\li  This routine blocks until there are no timers left in the manager,
- *     so if the caller holds any timer references using the manager, it
- *     must detach them before calling isc_timermgr_destroy() or it will
- *     block forever.
- *
- * Requires:
- *
- *\li  '*managerp' is a valid isc_timermgr_t.
- *
- * Ensures:
- *
- *\li  *managerp == NULL
- *
- *\li  All resources used by the manager have been freed.
- */
index 436cc19a89c955277c77773b45a1159655731c1b..5e82e6393685d5447b249b565da919fb109e19e4 100644 (file)
@@ -34,7 +34,6 @@
 #include <isc/string.h>
 #include <isc/task.h>
 #include <isc/thread.h>
-#include <isc/timer.h>
 #include <isc/util.h>
 
 #include <dns/adb.h>
@@ -2407,7 +2406,7 @@ clientmgr_destroy(ns_clientmgr_t *manager) {
 
 isc_result_t
 ns_clientmgr_create(ns_server_t *sctx, isc_taskmgr_t *taskmgr,
-                   isc_timermgr_t *timermgr, dns_aclenv_t *aclenv, int tid,
+                   isc_loopmgr_t *loopmgr, dns_aclenv_t *aclenv, int tid,
                    ns_clientmgr_t **managerp) {
        ns_clientmgr_t *manager = NULL;
        isc_mem_t *mctx = NULL;
@@ -2422,7 +2421,7 @@ ns_clientmgr_create(ns_server_t *sctx, isc_taskmgr_t *taskmgr,
        isc_mutex_init(&manager->reclock);
 
        manager->taskmgr = taskmgr;
-       manager->timermgr = timermgr;
+       manager->loopmgr = loopmgr;
        manager->tid = tid;
 
        dns_aclenv_attach(aclenv, &manager->aclenv);
index fd4378757becfde399ac6f0f1f4c701e67937f2e..3dfb6c81c9bebebe26f8e19cfced753ccadc282c 100644 (file)
@@ -143,12 +143,12 @@ struct ns_clientmgr {
        /* Unlocked. */
        unsigned int magic;
 
-       isc_mem_t      *mctx;
-       ns_server_t    *sctx;
-       isc_taskmgr_t  *taskmgr;
-       isc_timermgr_t *timermgr;
-       isc_refcount_t  references;
-       int             tid;
+       isc_mem_t     *mctx;
+       ns_server_t   *sctx;
+       isc_taskmgr_t *taskmgr;
+       isc_loopmgr_t *loopmgr;
+       isc_refcount_t references;
+       int            tid;
 
        /* Attached by clients, needed for e.g. recursion */
        isc_task_t *task;
@@ -323,7 +323,7 @@ ns_client_settimeout(ns_client_t *client, unsigned int seconds);
 
 isc_result_t
 ns_clientmgr_create(ns_server_t *sctx, isc_taskmgr_t *taskmgr,
-                   isc_timermgr_t *timermgr, dns_aclenv_t *aclenv, int tid,
+                   isc_loopmgr_t *loopmgr, dns_aclenv_t *aclenv, int tid,
                    ns_clientmgr_t **managerp);
 /*%<
  * Create a client manager.
index ac94c7957af159da5ae9778af742aa71fc790722..cbbc6794e449f2485e4dc0c07817a53803d124dd 100644 (file)
@@ -99,7 +99,7 @@ struct ns_interface {
 
 isc_result_t
 ns_interfacemgr_create(isc_mem_t *mctx, ns_server_t *sctx,
-                      isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr,
+                      isc_taskmgr_t *taskmgr, isc_loopmgr_t *loopmgr,
                       isc_nm_t *nm, dns_dispatchmgr_t *dispatchmgr,
                       isc_task_t *task, dns_geoip_databases_t *geoip,
                       bool scan, ns_interfacemgr_t **mgrp);
index aff010cc7e87f48f84dca51e2a3112242e2435bf..ce21aa39a8129a1bf19ecbf7f1983aeb05df0bc5 100644 (file)
@@ -71,13 +71,13 @@ struct ns_interfacemgr {
        unsigned int magic; /*%< Magic number */
        isc_refcount_t references;
        isc_mutex_t lock;
-       isc_mem_t *mctx;          /*%< Memory context */
-       ns_server_t *sctx;        /*%< Server context */
-       isc_taskmgr_t *taskmgr;   /*%< Task manager */
-       isc_task_t *task;         /*%< Task */
-       isc_timermgr_t *timermgr; /*%< Timer manager */
-       isc_nm_t *nm;             /*%< Net manager */
-       uint32_t ncpus;           /*%< Number of workers */
+       isc_mem_t *mctx;        /*%< Memory context */
+       ns_server_t *sctx;      /*%< Server context */
+       isc_taskmgr_t *taskmgr; /*%< Task manager */
+       isc_task_t *task;       /*%< Task */
+       isc_loopmgr_t *loopmgr; /*%< Loop manager */
+       isc_nm_t *nm;           /*%< Net manager */
+       uint32_t ncpus;         /*%< Number of workers */
        dns_dispatchmgr_t *dispatchmgr;
        unsigned int generation; /*%< Current generation no */
        ns_listenlist_t *listenon4;
@@ -274,7 +274,7 @@ route_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
 
 isc_result_t
 ns_interfacemgr_create(isc_mem_t *mctx, ns_server_t *sctx,
-                      isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr,
+                      isc_taskmgr_t *taskmgr, isc_loopmgr_t *loopmgr,
                       isc_nm_t *nm, dns_dispatchmgr_t *dispatchmgr,
                       isc_task_t *task, dns_geoip_databases_t *geoip,
                       bool scan, ns_interfacemgr_t **mgrp) {
@@ -290,7 +290,7 @@ ns_interfacemgr_create(isc_mem_t *mctx, ns_server_t *sctx,
        mgr = isc_mem_get(mctx, sizeof(*mgr));
        *mgr = (ns_interfacemgr_t){
                .taskmgr = taskmgr,
-               .timermgr = timermgr,
+               .loopmgr = loopmgr,
                .nm = nm,
                .dispatchmgr = dispatchmgr,
                .generation = 1,
@@ -339,7 +339,7 @@ ns_interfacemgr_create(isc_mem_t *mctx, ns_server_t *sctx,
                                      mgr->ncpus * sizeof(mgr->clientmgrs[0]));
        for (size_t i = 0; i < mgr->ncpus; i++) {
                result = ns_clientmgr_create(mgr->sctx, mgr->taskmgr,
-                                            mgr->timermgr, mgr->aclenv, (int)i,
+                                            mgr->loopmgr, mgr->aclenv, (int)i,
                                             &mgr->clientmgrs[i]);
                RUNTIME_CHECK(result == ISC_R_SUCCESS);
        }
index 6a80102ab938a43de6024523c32d530269e1667a..7205d54e3d2ee33f0b526147be486fd7f92d87db 100644 (file)
 #include <isc/atomic.h>
 #include <isc/commandline.h>
 #include <isc/condition.h>
+#include <isc/job.h>
+#include <isc/loop.h>
 #include <isc/mem.h>
+#include <isc/os.h>
 #include <isc/print.h>
-#include <isc/task.h>
 #include <isc/time.h>
 #include <isc/timer.h>
 #include <isc/util.h>
@@ -45,8 +47,6 @@ static bool verbose = false;
 #define FUDGE_NANOSECONDS 500000000 /* in absence of clock_getres() */
 
 static isc_timer_t *timer = NULL;
-static isc_condition_t cv;
-static isc_mutex_t mx;
 static isc_time_t endtime;
 static isc_mutex_t lasttime_mx;
 static isc_time_t lasttime;
@@ -56,77 +56,48 @@ static atomic_int_fast32_t eventcnt;
 static atomic_uint_fast32_t errcnt;
 static int nevents;
 
-static int
-_setup(void **state) {
-       atomic_init(&errcnt, ISC_R_SUCCESS);
+typedef struct setup_test_arg {
+       isc_timertype_t timertype;
+       isc_interval_t *interval;
+       isc_job_cb action;
+} setup_test_arg_t;
 
-       setup_managers(state);
-
-       return (0);
-}
-
-static int
-_teardown(void **state) {
-       teardown_managers(state);
+static void
+setup_test_run(void *data) {
+       isc_timertype_t timertype = ((setup_test_arg_t *)data)->timertype;
+       isc_interval_t *interval = ((setup_test_arg_t *)data)->interval;
+       isc_job_cb action = ((setup_test_arg_t *)data)->action;
+       isc_result_t result;
 
-       return (0);
-}
+       isc_mutex_lock(&lasttime_mx);
+       result = isc_time_now(&lasttime);
+       UNLOCK(&lasttime_mx);
+       assert_int_equal(result, ISC_R_SUCCESS);
 
-static void
-test_shutdown(void) {
-       /*
-        * Signal shutdown processing complete.
-        */
-       LOCK(&mx);
-       SIGNAL(&cv);
-       UNLOCK(&mx);
+       isc_timer_create(mainloop, action, (void *)timertype, &timer);
+       isc_timer_start(timer, timertype, interval);
 }
 
 static void
 setup_test(isc_timertype_t timertype, isc_interval_t *interval,
-          void (*action)(isc_task_t *, isc_event_t *)) {
-       isc_result_t result;
-       isc_task_t *task = NULL;
+          isc_job_cb action) {
+       setup_test_arg_t arg = { .timertype = timertype,
+                                .interval = interval,
+                                .action = action };
+
        isc_time_settoepoch(&endtime);
        atomic_init(&eventcnt, 0);
 
-       isc_mutex_init(&mx);
        isc_mutex_init(&lasttime_mx);
 
-       isc_condition_init(&cv);
-
        atomic_store(&errcnt, ISC_R_SUCCESS);
 
-       LOCK(&mx);
-
-       result = isc_task_create(taskmgr, 0, &task, 0);
-       assert_int_equal(result, ISC_R_SUCCESS);
-
-       LOCK(&lasttime_mx);
-       result = isc_time_now(&lasttime);
-       UNLOCK(&lasttime_mx);
-       assert_int_equal(result, ISC_R_SUCCESS);
-
-       isc_timer_create(timermgr, task, action, (void *)timertype, &timer);
-       result = isc_timer_reset(timer, timertype, interval, false);
-       assert_int_equal(result, ISC_R_SUCCESS);
-
-       /*
-        * Wait for shutdown processing to complete.
-        */
-       while (atomic_load(&eventcnt) != nevents) {
-               WAIT(&cv, &mx);
-               assert_int_equal(result, ISC_R_SUCCESS);
-       }
-
-       UNLOCK(&mx);
+       isc_loop_setup(mainloop, setup_test_run, &arg);
+       isc_loopmgr_run(loopmgr);
 
        assert_int_equal(atomic_load(&errcnt), ISC_R_SUCCESS);
 
-       isc_task_detach(&task);
-       isc_mutex_destroy(&mx);
        isc_mutex_destroy(&lasttime_mx);
-       isc_condition_destroy(&cv);
 }
 
 static void
@@ -145,18 +116,6 @@ subthread_assert_true(bool expected, const char *file, unsigned int line) {
 #define subthread_assert_true(expected) \
        subthread_assert_true(expected, __FILE__, __LINE__)
 
-static void
-subthread_assert_int_equal(int observed, int expected, const char *file,
-                          unsigned int line) {
-       if (observed != expected) {
-               printf("# %s:%u subthread_assert_int_equal(%d != %d)\n", file,
-                      line, observed, expected);
-               set_global_error(ISC_R_UNEXPECTED);
-       }
-}
-#define subthread_assert_int_equal(observed, expected) \
-       subthread_assert_int_equal(observed, expected, __FILE__, __LINE__)
-
 static void
 subthread_assert_result_equal(isc_result_t result, isc_result_t expected,
                              const char *file, unsigned int line) {
@@ -171,33 +130,21 @@ subthread_assert_result_equal(isc_result_t result, isc_result_t expected,
        subthread_assert_result_equal(observed, expected, __FILE__, __LINE__)
 
 static void
-ticktock(isc_task_t *task, isc_event_t *event) {
+ticktock(void *arg) {
        isc_result_t result;
        isc_time_t now;
        isc_time_t base;
        isc_time_t ulim;
        isc_time_t llim;
        isc_interval_t interval;
-       isc_eventtype_t expected_event_type;
-
-       UNUSED(task);
-
        int tick = atomic_fetch_add(&eventcnt, 1);
 
+       UNUSED(arg);
+
        if (verbose) {
                print_message("# tick %d\n", tick);
        }
 
-       expected_event_type = ISC_TIMEREVENT_ONCE;
-       if ((uintptr_t)event->ev_arg == isc_timertype_ticker) {
-               expected_event_type = ISC_TIMEREVENT_TICK;
-       }
-
-       if (event->ev_type != expected_event_type) {
-               print_error("# expected event type %u, got %u\n",
-                           expected_event_type, event->ev_type);
-       }
-
        result = isc_time_now(&now);
        subthread_assert_result_equal(result, ISC_R_SUCCESS);
 
@@ -223,13 +170,11 @@ ticktock(isc_task_t *task, isc_event_t *event) {
        isc_mutex_unlock(&lasttime_mx);
        subthread_assert_result_equal(result, ISC_R_SUCCESS);
 
-       isc_event_free(&event);
-
        if (atomic_load(&eventcnt) == nevents) {
                result = isc_time_now(&endtime);
                subthread_assert_result_equal(result, ISC_R_SUCCESS);
                isc_timer_destroy(&timer);
-               test_shutdown();
+               isc_loopmgr_shutdown(loopmgr);
        }
 }
 
@@ -253,18 +198,17 @@ ISC_RUN_TEST_IMPL(ticker) {
 }
 
 static void
-test_idle(isc_task_t *task, isc_event_t *event) {
+test_idle(void *arg) {
        isc_result_t result;
        isc_time_t now;
        isc_time_t base;
        isc_time_t ulim;
        isc_time_t llim;
        isc_interval_t interval;
-
-       UNUSED(task);
-
        int tick = atomic_fetch_add(&eventcnt, 1);
 
+       UNUSED(arg);
+
        if (verbose) {
                print_message("# tick %d\n", tick);
        }
@@ -293,12 +237,8 @@ test_idle(isc_task_t *task, isc_event_t *event) {
        isc_time_add(&now, &interval, &lasttime);
        isc_mutex_unlock(&lasttime_mx);
 
-       subthread_assert_int_equal(event->ev_type, ISC_TIMEREVENT_ONCE);
-
-       isc_event_free(&event);
-
        isc_timer_destroy(&timer);
-       test_shutdown();
+       isc_loopmgr_shutdown(loopmgr);
 }
 
 /* timer type once idles out */
@@ -318,18 +258,17 @@ ISC_RUN_TEST_IMPL(once_idle) {
 
 /* timer reset */
 static void
-test_reset(isc_task_t *task, isc_event_t *event) {
+test_reset(void *arg) {
        isc_result_t result;
        isc_time_t now;
        isc_time_t base;
        isc_time_t ulim;
        isc_time_t llim;
        isc_interval_t interval;
-
-       UNUSED(task);
-
        int tick = atomic_fetch_add(&eventcnt, 1);
 
+       UNUSED(arg);
+
        if (verbose) {
                print_message("# tick %d\n", tick);
        }
@@ -362,24 +301,14 @@ test_reset(isc_task_t *task, isc_event_t *event) {
        isc_time_add(&now, &interval, &lasttime);
        isc_mutex_unlock(&lasttime_mx);
 
-       int _eventcnt = atomic_load(&eventcnt);
-
-       if (_eventcnt < 3) {
-               subthread_assert_int_equal(event->ev_type, ISC_TIMEREVENT_TICK);
-               if (_eventcnt == 2) {
+       if (tick < 2) {
+               if (tick == 1) {
                        isc_interval_set(&interval, seconds, nanoseconds);
-                       result = isc_timer_reset(timer, isc_timertype_once,
-                                                &interval, false);
-                       subthread_assert_result_equal(result, ISC_R_SUCCESS);
+                       isc_timer_start(timer, isc_timertype_once, &interval);
                }
-
-               isc_event_free(&event);
        } else {
-               subthread_assert_int_equal(event->ev_type, ISC_TIMEREVENT_ONCE);
-
-               isc_event_free(&event);
                isc_timer_destroy(&timer);
-               test_shutdown();
+               isc_loopmgr_shutdown(loopmgr);
        }
 }
 
@@ -398,58 +327,38 @@ ISC_RUN_TEST_IMPL(reset) {
 }
 
 static atomic_bool startflag;
-static atomic_bool shutdownflag;
 static isc_timer_t *tickertimer = NULL;
 static isc_timer_t *oncetimer = NULL;
-static isc_task_t *task1 = NULL;
-static isc_task_t *task2 = NULL;
-
-/*
- * task1 blocks on mx while events accumulate
- * in its queue, until signaled by task2.
- */
 
 static void
-tick_event(isc_task_t *task, isc_event_t *event) {
-       isc_result_t result;
-       isc_time_t expires;
-       isc_interval_t interval;
+tick_event(void *arg) {
+       int tick;
 
-       UNUSED(task);
+       UNUSED(arg);
 
        if (!atomic_load(&startflag)) {
                if (verbose) {
                        print_message("# tick_event %d\n", -1);
                }
-               isc_event_free(&event);
                return;
        }
 
-       int tick = atomic_fetch_add(&eventcnt, 1);
+       tick = atomic_fetch_add(&eventcnt, 1);
        if (verbose) {
                print_message("# tick_event %d\n", tick);
        }
 
        /*
-        * On the first tick, purge all remaining tick events
-        * and then shut down the task.
+        * On the first tick, purge all remaining tick events.
         */
        if (tick == 0) {
-               isc_time_settoepoch(&expires);
-               isc_interval_set(&interval, seconds, 0);
-               result = isc_timer_reset(tickertimer, isc_timertype_ticker,
-                                        &interval, true);
-               subthread_assert_result_equal(result, ISC_R_SUCCESS);
-
-               atomic_store(&shutdownflag, 1);
+               isc_timer_destroy(&tickertimer);
        }
-
-       isc_event_free(&event);
 }
 
 static void
-once_event(isc_task_t *task, isc_event_t *event) {
-       UNUSED(task);
+once_event(void *arg) {
+       UNUSED(arg);
 
        if (verbose) {
                print_message("# once_event\n");
@@ -460,67 +369,54 @@ once_event(isc_task_t *task, isc_event_t *event) {
         */
        atomic_store(&startflag, true);
 
-       isc_event_free(&event);
+       isc_loopmgr_shutdown(loopmgr);
+       isc_timer_destroy(&oncetimer);
+}
+
+ISC_LOOP_SETUP_IMPL(purge) {
+       atomic_init(&eventcnt, 0);
+       atomic_store(&errcnt, ISC_R_SUCCESS);
+}
+
+ISC_LOOP_TEARDOWN_IMPL(purge) {
+       assert_int_equal(atomic_load(&errcnt), ISC_R_SUCCESS);
+       assert_int_equal(atomic_load(&eventcnt), 1);
 }
 
 /* timer events purged */
-ISC_RUN_TEST_IMPL(purge) {
-       isc_result_t result;
+ISC_LOOP_TEST_SETUP_TEARDOWN_IMPL(purge) {
        isc_interval_t interval;
 
-       UNUSED(state);
+       UNUSED(arg);
+
+       if (verbose) {
+               print_message("# purge_run\n");
+       }
 
        atomic_init(&startflag, 0);
-       atomic_init(&shutdownflag, 0);
-       atomic_init(&eventcnt, 0);
        seconds = 1;
        nanoseconds = 0;
 
-       result = isc_task_create(taskmgr, 0, &task1, 0);
-       assert_int_equal(result, ISC_R_SUCCESS);
-
-       result = isc_task_create(taskmgr, 0, &task2, 0);
-       assert_int_equal(result, ISC_R_SUCCESS);
-
        isc_interval_set(&interval, seconds, 0);
 
        tickertimer = NULL;
-       isc_timer_create(timermgr, task1, tick_event, NULL, &tickertimer);
-       result = isc_timer_reset(tickertimer, isc_timertype_ticker, &interval,
-                                false);
-       assert_int_equal(result, ISC_R_SUCCESS);
+       isc_timer_create(mainloop, tick_event, NULL, &tickertimer);
+       isc_timer_start(tickertimer, isc_timertype_ticker, &interval);
 
        oncetimer = NULL;
 
        isc_interval_set(&interval, (seconds * 2) + 1, 0);
 
-       isc_timer_create(timermgr, task2, once_event, NULL, &oncetimer);
-       result = isc_timer_reset(oncetimer, isc_timertype_once, &interval,
-                                false);
-       assert_int_equal(result, ISC_R_SUCCESS);
-
-       /*
-        * Wait for shutdown processing to complete.
-        */
-       while (!atomic_load(&shutdownflag)) {
-               uv_sleep(1);
-       }
-
-       assert_int_equal(atomic_load(&errcnt), ISC_R_SUCCESS);
-
-       assert_int_equal(atomic_load(&eventcnt), 1);
-
-       isc_timer_destroy(&tickertimer);
-       isc_timer_destroy(&oncetimer);
-       isc_task_detach(&task1);
-       isc_task_detach(&task2);
+       isc_timer_create(mainloop, once_event, NULL, &oncetimer);
+       isc_timer_start(oncetimer, isc_timertype_once, &interval);
 }
 
 ISC_TEST_LIST_START
 
-ISC_TEST_ENTRY_CUSTOM(once_idle, _setup, _teardown)
-ISC_TEST_ENTRY_CUSTOM(reset, _setup, _teardown)
-ISC_TEST_ENTRY_CUSTOM(purge, _setup, _teardown)
+ISC_TEST_ENTRY_CUSTOM(ticker, setup_loopmgr, teardown_loopmgr)
+ISC_TEST_ENTRY_CUSTOM(once_idle, setup_loopmgr, teardown_loopmgr)
+ISC_TEST_ENTRY_CUSTOM(reset, setup_loopmgr, teardown_loopmgr)
+ISC_TEST_ENTRY_CUSTOM(purge, setup_loopmgr, teardown_loopmgr)
 
 ISC_TEST_LIST_END