From: Ondřej Surý Date: Tue, 26 Jul 2022 11:03:40 +0000 (+0200) Subject: Update isc_timer to use isc_loopmgr X-Git-Tag: v9.19.5~23^2~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=49b149f5fd34951c0d995766a97750c3796bf693;p=thirdparty%2Fbind9.git Update isc_timer to use isc_loopmgr * 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. --- diff --git a/bin/delv/delv.c b/bin/delv/delv.c index f83501578cd..5c3240c5744 100644 --- a/bin/delv/delv.c +++ b/bin/delv/delv.c @@ -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); diff --git a/bin/dig/dig.c b/bin/dig/dig.c index 04ca4001c71..a416f3fd476 100644 --- a/bin/dig/dig.c +++ b/bin/dig/dig.c @@ -19,9 +19,9 @@ #include #include -#include #include #include +#include #include #include #include @@ -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 */ diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index d9dac0e15cf..f0771b2d8b8 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -34,12 +34,12 @@ #include #endif /* HAVE_LIBIDN2 */ -#include #include #include #include #include #include +#include #include #include #include @@ -53,7 +53,6 @@ #include #include #include -#include #include #include @@ -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 diff --git a/bin/dig/dighost.h b/bin/dig/dighost.h index 00158ac6f94..f2ba9239e41 100644 --- a/bin/dig/dighost.h +++ b/bin/dig/dighost.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -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); diff --git a/bin/dig/host.c b/bin/dig/host.c index 436e9d77413..abc2e7bc0f4 100644 --- a/bin/dig/host.c +++ b/bin/dig/host.c @@ -19,9 +19,9 @@ #include #include -#include #include #include +#include #include #include #include @@ -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); } diff --git a/bin/dig/nslookup.c b/bin/dig/nslookup.c index 92bc2c2fa93..5896055c3f0 100644 --- a/bin/dig/nslookup.c +++ b/bin/dig/nslookup.c @@ -16,17 +16,20 @@ #include #include -#include #include #include #include +#include #include +#include +#include #include #include #include #include #include #include +#include #include #include @@ -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); } diff --git a/bin/dnssec/dnssec-signzone.c b/bin/dnssec/dnssec-signzone.c index 1780a93ae81..b63a2b9632a 100644 --- a/bin/dnssec/dnssec-signzone.c +++ b/bin/dnssec/dnssec-signzone.c @@ -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); diff --git a/bin/named/include/named/globals.h b/bin/named/include/named/globals.h index 5467d287364..ebacca1524d 100644 --- a/bin/named/include/named/globals.h +++ b/bin/named/include/named/globals.h @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -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); diff --git a/bin/named/include/named/main.h b/bin/named/include/named/main.h index 42fd138314d..bed5dd9787c 100644 --- a/bin/named/include/named/main.h +++ b/bin/named/include/named/main.h @@ -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); diff --git a/bin/named/main.c b/bin/named/main.c index ddf002dd967..b57b608211f 100644 --- a/bin/named/main.c +++ b/bin/named/main.c @@ -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 diff --git a/bin/named/server.c b/bin/named/server.c index a2d3beef2d9..73f85bf5350 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -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"); diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c index b57fe20bb27..fe3a7d1ce8e 100644 --- a/bin/nsupdate/nsupdate.c +++ b/bin/nsupdate/nsupdate.c @@ -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) { diff --git a/bin/rndc/rndc.c b/bin/rndc/rndc.c index bd9afeac1a0..50de03175ba 100644 --- a/bin/rndc/rndc.c +++ b/bin/rndc/rndc.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -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 diff --git a/bin/tests/test_client.c b/bin/tests/test_client.c index c7615e27d99..45afc4c3712 100644 --- a/bin/tests/test_client.c +++ b/bin/tests/test_client.c @@ -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); diff --git a/bin/tests/test_server.c b/bin/tests/test_server.c index 728927e3555..3c315902444 100644 --- a/bin/tests/test_server.c +++ b/bin/tests/test_server.c @@ -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); diff --git a/bin/tools/mdig.c b/bin/tools/mdig.c index ad4139ffee3..eb72c62f08e 100644 --- a/bin/tools/mdig.c +++ b/bin/tools/mdig.c @@ -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(); diff --git a/lib/dns/cache.c b/lib/dns/cache.c index 011338e9977..6c856d0a169 100644 --- a/lib/dns/cache.c +++ b/lib/dns/cache.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -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__, diff --git a/lib/dns/catz.c b/lib/dns/catz.c index 8cf4e1cb938..e53df3b7fa8 100644 --- a/lib/dns/catz.c +++ b/lib/dns/catz.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -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), diff --git a/lib/dns/client.c b/lib/dns/client.c index 586be89103a..af34beba055 100644 --- a/lib/dns/client.c +++ b/lib/dns/client.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include @@ -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; diff --git a/lib/dns/dyndb.c b/lib/dns/dyndb.c index 253d58f9fe2..08ff0ffba03 100644 --- a/lib/dns/dyndb.c +++ b/lib/dns/dyndb.c @@ -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)); diff --git a/lib/dns/include/dns/cache.h b/lib/dns/include/dns/cache.h index 8fc96574d80..d7697ab7b9d 100644 --- a/lib/dns/include/dns/cache.h +++ b/lib/dns/include/dns/cache.h @@ -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. * diff --git a/lib/dns/include/dns/catz.h b/lib/dns/include/dns/catz.h index 9c74e155846..68da93d8fdd 100644 --- a/lib/dns/include/dns/catz.h +++ b/lib/dns/include/dns/catz.h @@ -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. * diff --git a/lib/dns/include/dns/client.h b/lib/dns/include/dns/client.h index f2cf41def37..19ca2e00620 100644 --- a/lib/dns/include/dns/client.h +++ b/lib/dns/include/dns/client.h @@ -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. * diff --git a/lib/dns/include/dns/dyndb.h b/lib/dns/include/dns/dyndb.h index a219cb9158f..b8490d5f373 100644 --- a/lib/dns/include/dns/dyndb.h +++ b/lib/dns/include/dns/dyndb.h @@ -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 diff --git a/lib/dns/include/dns/nta.h b/lib/dns/include/dns/nta.h index eb3f0dce691..aacbef1608a 100644 --- a/lib/dns/include/dns/nta.h +++ b/lib/dns/include/dns/nta.h @@ -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'. * diff --git a/lib/dns/include/dns/resolver.h b/lib/dns/include/dns/resolver.h index a9c2ce953fa..2046f9421a2 100644 --- a/lib/dns/include/dns/resolver.h +++ b/lib/dns/include/dns/resolver.h @@ -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. * diff --git a/lib/dns/include/dns/rpz.h b/lib/dns/include/dns/rpz.h index c0acc11ba0c..c46168d5383 100644 --- a/lib/dns/include/dns/rpz.h +++ b/lib/dns/include/dns/rpz.h @@ -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); diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h index 7a9a48c2692..fc2ce99beac 100644 --- a/lib/dns/include/dns/view.h +++ b/lib/dns/include/dns/view.h @@ -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. * diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index 0f035cf5a8c..616bf4dd115 100644 --- a/lib/dns/include/dns/zone.h +++ b/lib/dns/include/dns/zone.h @@ -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. */ diff --git a/lib/dns/nta.c b/lib/dns/nta.c index d6a2f61cf58..5d53f316ac6 100644 --- a/lib/dns/nta.c +++ b/lib/dns/nta.c @@ -17,7 +17,9 @@ #include #include +#include #include +#include #include #include #include @@ -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); diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 83293f7d675..7dfdda343e9 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -29,6 +30,7 @@ #include #include #include +#include #include #include @@ -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); } } diff --git a/lib/dns/rpz.c b/lib/dns/rpz.c index 62b150f6d87..bfbb0795d6d 100644 --- a/lib/dns/rpz.c +++ b/lib/dns/rpz.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -27,6 +28,7 @@ #include #include #include +#include #include #include @@ -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); } /* diff --git a/lib/dns/sdb.c b/lib/dns/sdb.c index 6c647de98ad..edf4bd75654 100644 --- a/lib/dns/sdb.c +++ b/lib/dns/sdb.c @@ -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); diff --git a/lib/dns/view.c b/lib/dns/view.c index 3a00a0a46ce..56aeb913cf1 100644 --- a/lib/dns/view.c +++ b/lib/dns/view.c @@ -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)); } diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 4cc012cf88e..ab28bf693e0 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -17,10 +17,12 @@ #include #include +#include #include #include #include #include +#include #include #include #include @@ -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); diff --git a/lib/isc/Makefile.am b/lib/isc/Makefile.am index 78fbddbc8c5..d0822ff73b2 100644 --- a/lib/isc/Makefile.am +++ b/lib/isc/Makefile.am @@ -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 \ diff --git a/lib/isc/include/isc/managers.h b/lib/isc/include/isc/managers.h index 774ed30a329..3a0f4b4ddd5 100644 --- a/lib/isc/include/isc/managers.h +++ b/lib/isc/include/isc/managers.h @@ -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); diff --git a/lib/isc/include/isc/ratelimiter.h b/lib/isc/include/isc/ratelimiter.h index 828665418c2..b99e509ff67 100644 --- a/lib/isc/include/isc/ratelimiter.h +++ b/lib/isc/include/isc/ratelimiter.h @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -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 diff --git a/lib/isc/include/isc/timer.h b/lib/isc/include/isc/timer.h index 132cc67bf64..45bc317bbb7 100644 --- a/lib/isc/include/isc/timer.h +++ b/lib/isc/include/isc/timer.h @@ -20,19 +20,13 @@ /*! \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 -#include -#include +#include #include #include #include @@ -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 diff --git a/lib/isc/managers.c b/lib/isc/managers.c index 63ef09e5b40..b24115da22a 100644 --- a/lib/isc/managers.c +++ b/lib/isc/managers.c @@ -11,21 +11,20 @@ * information regarding copyright ownership. */ +#include #include #include #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); } diff --git a/lib/isc/ratelimiter.c b/lib/isc/ratelimiter.c index 13876172055..d263b255f3d 100644 --- a/lib/isc/ratelimiter.c +++ b/lib/isc/ratelimiter.c @@ -16,6 +16,9 @@ #include #include +#include +#include +#include #include #include #include @@ -25,74 +28,53 @@ #include 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)); } diff --git a/lib/isc/timer.c b/lib/isc/timer.c index d05abe99a4c..54df9684d27 100644 --- a/lib/isc/timer.c +++ b/lib/isc/timer.c @@ -15,9 +15,10 @@ #include -#include +#include #include #include +#include #include #include #include @@ -29,552 +30,198 @@ #include #include #include +#include -#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 index ab9bf9c5ff7..00000000000 --- a/lib/isc/timer_p.h +++ /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 -#include -#include - -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. - */ diff --git a/lib/ns/client.c b/lib/ns/client.c index 436cc19a89c..5e82e639368 100644 --- a/lib/ns/client.c +++ b/lib/ns/client.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include @@ -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); diff --git a/lib/ns/include/ns/client.h b/lib/ns/include/ns/client.h index fd4378757be..3dfb6c81c9b 100644 --- a/lib/ns/include/ns/client.h +++ b/lib/ns/include/ns/client.h @@ -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. diff --git a/lib/ns/include/ns/interfacemgr.h b/lib/ns/include/ns/interfacemgr.h index ac94c7957af..cbbc6794e44 100644 --- a/lib/ns/include/ns/interfacemgr.h +++ b/lib/ns/include/ns/interfacemgr.h @@ -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); diff --git a/lib/ns/interfacemgr.c b/lib/ns/interfacemgr.c index aff010cc7e8..ce21aa39a81 100644 --- a/lib/ns/interfacemgr.c +++ b/lib/ns/interfacemgr.c @@ -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); } diff --git a/tests/isc/timer_test.c b/tests/isc/timer_test.c index 6a80102ab93..7205d54e3d2 100644 --- a/tests/isc/timer_test.c +++ b/tests/isc/timer_test.c @@ -26,9 +26,11 @@ #include #include #include +#include +#include #include +#include #include -#include #include #include #include @@ -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