mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-03 22:08:25 -04:00
Merge branch '2654-create-isc_managers-api' into 'main'
Destroy netmgr before destroying taskmgr Closes #2654 See merge request isc-projects/bind9!4983
This commit is contained in:
commit
0e92060833
62 changed files with 1697 additions and 1295 deletions
14
CHANGES
14
CHANGES
|
|
@ -1,3 +1,17 @@
|
|||
5638. [bug] Improvements related to network manager/task manager
|
||||
integration:
|
||||
- added isc_managers_create() and _destroy() functions
|
||||
to handle setup and teardown of netmgr, taskmgr,
|
||||
timermgr and socketmgr since these require a
|
||||
precise order of operations now.
|
||||
- event queue processing is now quantized to prevent
|
||||
infinite looping.
|
||||
- the netmgr can now be paused from within a netmgr
|
||||
thread.
|
||||
- fixed deadlocks due to conflict between netmgr
|
||||
pause/resume and listen/stoplistening operations.
|
||||
[GL #2654]
|
||||
|
||||
5637. [placeholder]
|
||||
|
||||
5636. [bug] Check that zone files for 'dnssec-policy' zones are
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include <isc/hex.h>
|
||||
#include <isc/lib.h>
|
||||
#include <isc/log.h>
|
||||
#include <isc/managers.h>
|
||||
#include <isc/md.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/netmgr.h>
|
||||
|
|
@ -1761,10 +1762,8 @@ main(int argc, char *argv[]) {
|
|||
isc_mem_create(&mctx);
|
||||
|
||||
CHECK(isc_appctx_create(mctx, &actx));
|
||||
netmgr = isc_nm_start(mctx, 1);
|
||||
CHECK(isc_taskmgr_create(mctx, 0, netmgr, &taskmgr));
|
||||
CHECK(isc_socketmgr_create(mctx, &socketmgr));
|
||||
CHECK(isc_timermgr_create(mctx, &timermgr));
|
||||
isc_managers_create(mctx, 1, 0, 0, &netmgr, &taskmgr, &timermgr,
|
||||
&socketmgr);
|
||||
|
||||
parse_args(argc, argv);
|
||||
|
||||
|
|
@ -1867,18 +1866,7 @@ cleanup:
|
|||
if (client != NULL) {
|
||||
dns_client_destroy(&client);
|
||||
}
|
||||
if (taskmgr != NULL) {
|
||||
isc_taskmgr_destroy(&taskmgr);
|
||||
}
|
||||
if (netmgr != NULL) {
|
||||
isc_nm_destroy(&netmgr);
|
||||
}
|
||||
if (timermgr != NULL) {
|
||||
isc_timermgr_destroy(&timermgr);
|
||||
}
|
||||
if (socketmgr != NULL) {
|
||||
isc_socketmgr_destroy(&socketmgr);
|
||||
}
|
||||
isc_managers_destroy(&netmgr, &taskmgr, &timermgr, &socketmgr);
|
||||
if (actx != NULL) {
|
||||
isc_appctx_destroy(&actx);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
#include <isc/hex.h>
|
||||
#include <isc/lang.h>
|
||||
#include <isc/log.h>
|
||||
#include <isc/managers.h>
|
||||
#include <isc/netaddr.h>
|
||||
#include <isc/netdb.h>
|
||||
#include <isc/nonce.h>
|
||||
|
|
@ -106,9 +107,9 @@ unsigned int timeout = 0;
|
|||
unsigned int extrabytes;
|
||||
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_nm_t *netmgr = NULL;
|
||||
isc_sockaddr_t localaddr;
|
||||
isc_refcount_t sendcount = ATOMIC_VAR_INIT(0);
|
||||
isc_refcount_t recvcount = ATOMIC_VAR_INIT(0);
|
||||
|
|
@ -226,8 +227,9 @@ void (*dighost_shutdown)(void);
|
|||
|
||||
/* forward declarations */
|
||||
|
||||
#define cancel_lookup(l) _cancel_lookup(l, __FILE__, __LINE__)
|
||||
static void
|
||||
cancel_lookup(dig_lookup_t *lookup);
|
||||
_cancel_lookup(dig_lookup_t *lookup, const char *file, unsigned int line);
|
||||
|
||||
static void
|
||||
recv_done(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
|
||||
|
|
@ -1360,10 +1362,7 @@ setup_libs(void) {
|
|||
|
||||
isc_log_setdebuglevel(lctx, 0);
|
||||
|
||||
netmgr = isc_nm_start(mctx, 1);
|
||||
|
||||
result = isc_taskmgr_create(mctx, 0, netmgr, &taskmgr);
|
||||
check_result(result, "isc_taskmgr_create");
|
||||
isc_managers_create(mctx, 1, 0, 0, &netmgr, &taskmgr, NULL, NULL);
|
||||
|
||||
result = isc_task_create(taskmgr, 0, &global_task);
|
||||
check_result(result, "isc_task_create");
|
||||
|
|
@ -1696,6 +1695,9 @@ _query_detach(dig_query_t **queryp, const char *file, unsigned int line) {
|
|||
isc_refcount_current(&query->references) - 1);
|
||||
|
||||
if (isc_refcount_decrement(&query->references) == 1) {
|
||||
INSIST(query->readhandle == NULL);
|
||||
INSIST(query->sendhandle == NULL);
|
||||
|
||||
if (ISC_LINK_LINKED(query, link)) {
|
||||
ISC_LIST_UNLINK(lookup->q, query, link);
|
||||
}
|
||||
|
|
@ -1752,13 +1754,18 @@ start_lookup(void) {
|
|||
* decremented, current_lookup will not be set to NULL.)
|
||||
*/
|
||||
static void
|
||||
clear_current_lookup() {
|
||||
clear_current_lookup(void) {
|
||||
dig_lookup_t *lookup = current_lookup;
|
||||
|
||||
INSIST(!free_now);
|
||||
|
||||
debug("clear_current_lookup()");
|
||||
|
||||
if (lookup == NULL) {
|
||||
debug("current_lookup is already detached");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ISC_LIST_HEAD(lookup->q) != NULL) {
|
||||
debug("still have a worker");
|
||||
return;
|
||||
|
|
@ -2671,11 +2678,12 @@ send_done(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
|
|||
/*%
|
||||
* Cancel a lookup, sending canceling reads on all existing sockets.
|
||||
*/
|
||||
|
||||
static void
|
||||
cancel_lookup(dig_lookup_t *lookup) {
|
||||
_cancel_lookup(dig_lookup_t *lookup, const char *file, unsigned int line) {
|
||||
dig_query_t *query, *next;
|
||||
|
||||
debug("cancel_lookup()");
|
||||
debug("%s:%u:%s()", file, line, __func__);
|
||||
query = ISC_LIST_HEAD(lookup->q);
|
||||
while (query != NULL) {
|
||||
REQUIRE(DIG_VALID_QUERY(query));
|
||||
|
|
@ -2904,6 +2912,7 @@ udp_ready(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
|
|||
isc_result_totext(eresult));
|
||||
}
|
||||
|
||||
cancel_lookup(l);
|
||||
lookup_detach(&l);
|
||||
query_detach(&query);
|
||||
return;
|
||||
|
|
@ -2941,6 +2950,7 @@ static void
|
|||
start_udp(dig_query_t *query) {
|
||||
isc_result_t result;
|
||||
dig_query_t *next = NULL;
|
||||
dig_query_t *connectquery = NULL;
|
||||
|
||||
REQUIRE(DIG_VALID_QUERY(query));
|
||||
|
||||
|
|
@ -2992,8 +3002,10 @@ start_udp(dig_query_t *query) {
|
|||
}
|
||||
}
|
||||
|
||||
query_attach(query, &connectquery);
|
||||
isc_nm_udpconnect(netmgr, (isc_nmiface_t *)&localaddr,
|
||||
(isc_nmiface_t *)&query->sockaddr, udp_ready, query,
|
||||
(isc_nmiface_t *)&query->sockaddr, udp_ready,
|
||||
connectquery,
|
||||
(timeout ? timeout : UDP_TIMEOUT) * 1000, 0);
|
||||
}
|
||||
|
||||
|
|
@ -3568,16 +3580,19 @@ recv_done(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
|
|||
region, arg);
|
||||
|
||||
LOCK_LOOKUP;
|
||||
lookup_attach(query->lookup, &l);
|
||||
|
||||
isc_refcount_decrement0(&recvcount);
|
||||
debug("recvcount=%" PRIuFAST32, isc_refcount_current(&recvcount));
|
||||
|
||||
if (eresult == ISC_R_CANCELED) {
|
||||
debug("recv_done: cancel");
|
||||
goto detach_query;
|
||||
isc_nmhandle_detach(&query->readhandle);
|
||||
query_detach(&query);
|
||||
return;
|
||||
}
|
||||
|
||||
lookup_attach(query->lookup, &l);
|
||||
|
||||
if (query->lookup->use_usec) {
|
||||
TIME_NOW_HIRES(&query->time_recv);
|
||||
} else {
|
||||
|
|
@ -4188,19 +4203,23 @@ cancel_all(void) {
|
|||
return;
|
||||
}
|
||||
atomic_store(&cancel_now, true);
|
||||
if (current_lookup != NULL) {
|
||||
while (current_lookup != NULL) {
|
||||
for (q = ISC_LIST_HEAD(current_lookup->q); q != NULL; q = nq) {
|
||||
nq = ISC_LIST_NEXT(q, link);
|
||||
debug("canceling pending query %p, belonging to %p", q,
|
||||
current_lookup);
|
||||
if (q->readhandle != NULL) {
|
||||
isc_refcount_decrement0(&recvcount);
|
||||
debug("recvcount=%" PRIuFAST32,
|
||||
isc_refcount_current(&recvcount));
|
||||
isc_nm_cancelread(q->readhandle);
|
||||
}
|
||||
query_detach(&q);
|
||||
}
|
||||
lookup_detach(¤t_lookup);
|
||||
|
||||
/*
|
||||
* current_lookup could have been detached via query_detach().
|
||||
*/
|
||||
if (current_lookup != NULL) {
|
||||
lookup_detach(¤t_lookup);
|
||||
}
|
||||
}
|
||||
l = ISC_LIST_HEAD(lookup_list);
|
||||
while (l != NULL) {
|
||||
|
|
@ -4226,20 +4245,8 @@ destroy_libs(void) {
|
|||
debug("freeing task");
|
||||
isc_task_detach(&global_task);
|
||||
}
|
||||
/*
|
||||
* The taskmgr_destroy() and isc_nm_destroy() calls block until
|
||||
* all events are cleared.
|
||||
*/
|
||||
if (taskmgr != NULL) {
|
||||
debug("freeing taskmgr");
|
||||
isc_taskmgr_destroy(&taskmgr);
|
||||
}
|
||||
|
||||
debug("closing down netmgr");
|
||||
isc_nm_closedown(netmgr);
|
||||
|
||||
debug("destroy netmgr");
|
||||
isc_nm_destroy(&netmgr);
|
||||
isc_managers_destroy(&netmgr, &taskmgr, NULL, NULL);
|
||||
|
||||
LOCK_LOOKUP;
|
||||
isc_refcount_destroy(&recvcount);
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#include <isc/file.h>
|
||||
#include <isc/hash.h>
|
||||
#include <isc/hex.h>
|
||||
#include <isc/managers.h>
|
||||
#include <isc/md.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/mutex.h>
|
||||
|
|
@ -3963,13 +3964,7 @@ main(int argc, char *argv[]) {
|
|||
print_time(outfp);
|
||||
print_version(outfp);
|
||||
|
||||
netmgr = isc_nm_start(mctx, ntasks);
|
||||
|
||||
result = isc_taskmgr_create(mctx, 0, netmgr, &taskmgr);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
fatal("failed to create task manager: %s",
|
||||
isc_result_totext(result));
|
||||
}
|
||||
isc_managers_create(mctx, ntasks, 0, 0, &netmgr, &taskmgr, NULL, NULL);
|
||||
|
||||
master = NULL;
|
||||
result = isc_task_create(taskmgr, 0, &master);
|
||||
|
|
@ -4020,8 +4015,7 @@ main(int argc, char *argv[]) {
|
|||
for (i = 0; i < (int)ntasks; i++) {
|
||||
isc_task_detach(&tasks[i]);
|
||||
}
|
||||
isc_taskmgr_destroy(&taskmgr);
|
||||
isc_nm_destroy(&netmgr);
|
||||
isc_managers_destroy(&netmgr, &taskmgr, NULL, NULL);
|
||||
isc_mem_put(mctx, tasks, ntasks * sizeof(isc_task_t *));
|
||||
postsign();
|
||||
TIME_NOW(&sign_finish);
|
||||
|
|
|
|||
|
|
@ -1164,10 +1164,10 @@ add_listener(named_controls_t *cp, controllistener_t **listenerp,
|
|||
}
|
||||
#endif
|
||||
|
||||
CHECK(isc_nm_listentcp(named_g_nm, (isc_nmiface_t *)&listener->address,
|
||||
control_newconn, listener,
|
||||
sizeof(controlconnection_t), 5, NULL,
|
||||
&listener->sock));
|
||||
CHECK(isc_nm_listentcp(
|
||||
named_g_netmgr, (isc_nmiface_t *)&listener->address,
|
||||
control_newconn, listener, sizeof(controlconnection_t), 5, NULL,
|
||||
&listener->sock));
|
||||
#if 0
|
||||
/* XXX: no unix socket support yet */
|
||||
if (type == isc_socktype_unix) {
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ EXTERN bool named_g_run_done INIT(false);
|
|||
*/
|
||||
EXTERN isc_timermgr_t *named_g_timermgr INIT(NULL);
|
||||
EXTERN isc_socketmgr_t *named_g_socketmgr INIT(NULL);
|
||||
EXTERN isc_nm_t *named_g_nm 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);
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include <isc/hash.h>
|
||||
#include <isc/hp.h>
|
||||
#include <isc/httpd.h>
|
||||
#include <isc/managers.h>
|
||||
#include <isc/netmgr.h>
|
||||
#include <isc/os.h>
|
||||
#include <isc/platform.h>
|
||||
|
|
@ -937,45 +938,17 @@ create_managers(void) {
|
|||
"using %u UDP listener%s per interface", named_g_udpdisp,
|
||||
named_g_udpdisp == 1 ? "" : "s");
|
||||
|
||||
/*
|
||||
* We have ncpus network threads, ncpus worker threads, ncpus
|
||||
* old network threads - make it 4x just to be safe. The memory
|
||||
* impact is negligible.
|
||||
*/
|
||||
isc_hp_init(4 * named_g_cpus);
|
||||
named_g_nm = isc_nm_start(named_g_mctx, named_g_cpus);
|
||||
if (named_g_nm == NULL) {
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_nm_start() failed");
|
||||
return (ISC_R_UNEXPECTED);
|
||||
result = isc_managers_create(named_g_mctx, named_g_cpus,
|
||||
0 /* quantum */, maxsocks, &named_g_netmgr,
|
||||
&named_g_taskmgr, &named_g_timermgr,
|
||||
&named_g_socketmgr);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
|
||||
result = isc_taskmgr_create(named_g_mctx, 0, named_g_nm,
|
||||
&named_g_taskmgr);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"isc_taskmgr_create() failed: %s",
|
||||
isc_result_totext(result));
|
||||
return (ISC_R_UNEXPECTED);
|
||||
}
|
||||
|
||||
result = isc_timermgr_create(named_g_mctx, &named_g_timermgr);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"isc_timermgr_create() failed: %s",
|
||||
isc_result_totext(result));
|
||||
return (ISC_R_UNEXPECTED);
|
||||
}
|
||||
|
||||
result = isc_socketmgr_create2(named_g_mctx, &named_g_socketmgr,
|
||||
maxsocks, named_g_cpus);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"isc_socketmgr_create() failed: %s",
|
||||
isc_result_totext(result));
|
||||
return (ISC_R_UNEXPECTED);
|
||||
}
|
||||
isc_socketmgr_maxudp(named_g_socketmgr, maxudp);
|
||||
isc_nm_maxudp(named_g_nm, maxudp);
|
||||
isc_nm_maxudp(named_g_netmgr, maxudp);
|
||||
|
||||
result = isc_socketmgr_getmaxsockets(named_g_socketmgr, &socks);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
|
||||
|
|
@ -988,21 +961,8 @@ create_managers(void) {
|
|||
|
||||
static void
|
||||
destroy_managers(void) {
|
||||
/*
|
||||
* isc_nm_closedown() closes all active connections, freeing
|
||||
* attached clients and other resources and preventing new
|
||||
* connections from being established, but it not does not
|
||||
* stop all processing or destroy the netmgr yet.
|
||||
*/
|
||||
isc_nm_closedown(named_g_nm);
|
||||
|
||||
/*
|
||||
* isc_taskmgr_destroy() will block until all tasks have exited.
|
||||
*/
|
||||
isc_taskmgr_destroy(&named_g_taskmgr);
|
||||
isc_nm_destroy(&named_g_nm);
|
||||
isc_timermgr_destroy(&named_g_timermgr);
|
||||
isc_socketmgr_destroy(&named_g_socketmgr);
|
||||
isc_managers_destroy(&named_g_netmgr, &named_g_taskmgr,
|
||||
&named_g_timermgr, &named_g_socketmgr);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -8840,7 +8840,8 @@ load_configuration(const char *filename, named_server_t *server,
|
|||
advertised = MAX_ADVERTISED_TIMEOUT;
|
||||
}
|
||||
|
||||
isc_nm_settimeouts(named_g_nm, initial, idle, keepalive, advertised);
|
||||
isc_nm_settimeouts(named_g_netmgr, initial, idle, keepalive,
|
||||
advertised);
|
||||
|
||||
/*
|
||||
* Configure sets of UDP query source ports.
|
||||
|
|
@ -9844,6 +9845,12 @@ view_loaded(void *arg) {
|
|||
"all zones loaded");
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear taskmgr privileged mode now that zones are loaded.
|
||||
*/
|
||||
isc_taskmgr_setmode(dns_zonemgr_gettaskmgr(server->zonemgr),
|
||||
isc_taskmgrmode_normal);
|
||||
|
||||
CHECKFATAL(dns_zonemgr_forcemaint(server->zonemgr),
|
||||
"forcing zone maintenance");
|
||||
|
||||
|
|
@ -9866,7 +9873,7 @@ view_loaded(void *arg) {
|
|||
}
|
||||
|
||||
static isc_result_t
|
||||
load_zones(named_server_t *server, bool reconfig) {
|
||||
load_zones(named_server_t *server, bool init, bool reconfig) {
|
||||
isc_result_t result;
|
||||
dns_view_t *view;
|
||||
ns_zoneload_t *zl;
|
||||
|
|
@ -9923,6 +9930,19 @@ cleanup:
|
|||
isc_mem_put(server->mctx, zl, sizeof(*zl));
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're setting up the server for the first time,
|
||||
* set the task manager into privileged mode; this ensures
|
||||
* that no other tasks will begin to run until after
|
||||
* zone loading is complete.
|
||||
*
|
||||
* We do *not* want to do this in the case of reload or
|
||||
* reconfig, as loading a large zone could cause the server
|
||||
* to be inactive for too long a time.
|
||||
*/
|
||||
isc_taskmgr_setmode(named_g_taskmgr, init ? isc_taskmgrmode_privileged
|
||||
: isc_taskmgrmode_normal);
|
||||
|
||||
isc_task_endexclusive(server->task);
|
||||
return (result);
|
||||
}
|
||||
|
|
@ -9950,7 +9970,7 @@ run_server(isc_task_t *task, isc_event_t *event) {
|
|||
|
||||
CHECKFATAL(ns_interfacemgr_create(
|
||||
named_g_mctx, server->sctx, named_g_taskmgr,
|
||||
named_g_timermgr, named_g_socketmgr, named_g_nm,
|
||||
named_g_timermgr, named_g_socketmgr, named_g_netmgr,
|
||||
named_g_dispatchmgr, server->task, named_g_udpdisp,
|
||||
geoip, named_g_cpus, &server->interfacemgr),
|
||||
"creating interface manager");
|
||||
|
|
@ -9988,7 +10008,7 @@ run_server(isc_task_t *task, isc_event_t *event) {
|
|||
CHECKFATAL(load_configuration(named_g_conffile, server, true),
|
||||
"loading configuration");
|
||||
|
||||
CHECKFATAL(load_zones(server, false), "loading zones");
|
||||
CHECKFATAL(load_zones(server, true, false), "loading zones");
|
||||
#ifdef ENABLE_AFL
|
||||
named_g_run_done = true;
|
||||
#endif /* ifdef ENABLE_AFL */
|
||||
|
|
@ -10181,7 +10201,7 @@ named_server_create(isc_mem_t *mctx, named_server_t **serverp) {
|
|||
* startup and shutdown of the server, as well as all exclusive
|
||||
* tasks.
|
||||
*/
|
||||
CHECKFATAL(isc_task_create(named_g_taskmgr, 0, &server->task),
|
||||
CHECKFATAL(isc_task_create_bound(named_g_taskmgr, 0, &server->task, 0),
|
||||
"creating server task");
|
||||
isc_task_setname(server->task, "server", server);
|
||||
isc_taskmgr_setexcltask(named_g_taskmgr, server->task);
|
||||
|
|
@ -10220,7 +10240,7 @@ named_server_create(isc_mem_t *mctx, named_server_t **serverp) {
|
|||
|
||||
CHECKFATAL(dns_zonemgr_create(named_g_mctx, named_g_taskmgr,
|
||||
named_g_timermgr, named_g_socketmgr,
|
||||
named_g_nm, &server->zonemgr),
|
||||
named_g_netmgr, &server->zonemgr),
|
||||
"dns_zonemgr_create");
|
||||
CHECKFATAL(dns_zonemgr_setsize(server->zonemgr, 1000), "dns_zonemgr_"
|
||||
"setsize");
|
||||
|
|
@ -10260,7 +10280,7 @@ named_server_create(isc_mem_t *mctx, named_server_t **serverp) {
|
|||
isc_sockstatscounter_max),
|
||||
"isc_stats_create");
|
||||
isc_socketmgr_setstats(named_g_socketmgr, server->sockstats);
|
||||
isc_nm_setstats(named_g_nm, server->sockstats);
|
||||
isc_nm_setstats(named_g_netmgr, server->sockstats);
|
||||
|
||||
CHECKFATAL(isc_stats_create(named_g_mctx, &server->zonestats,
|
||||
dns_zonestatscounter_max),
|
||||
|
|
@ -10501,7 +10521,7 @@ reload(named_server_t *server) {
|
|||
|
||||
CHECK(loadconfig(server));
|
||||
|
||||
result = load_zones(server, false);
|
||||
result = load_zones(server, false, false);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
|
||||
NAMED_LOGMODULE_SERVER, ISC_LOG_INFO,
|
||||
|
|
@ -10870,7 +10890,7 @@ named_server_reconfigcommand(named_server_t *server) {
|
|||
|
||||
CHECK(loadconfig(server));
|
||||
|
||||
result = load_zones(server, true);
|
||||
result = load_zones(server, false, true);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
|
||||
NAMED_LOGMODULE_SERVER, ISC_LOG_INFO,
|
||||
|
|
@ -16342,7 +16362,7 @@ named_server_tcptimeouts(isc_lex_t *lex, isc_buffer_t **text) {
|
|||
return (ISC_R_UNEXPECTEDEND);
|
||||
}
|
||||
|
||||
isc_nm_gettimeouts(named_g_nm, &initial, &idle, &keepalive,
|
||||
isc_nm_gettimeouts(named_g_netmgr, &initial, &idle, &keepalive,
|
||||
&advertised);
|
||||
|
||||
/* Look for optional arguments. */
|
||||
|
|
@ -16396,7 +16416,7 @@ named_server_tcptimeouts(isc_lex_t *lex, isc_buffer_t **text) {
|
|||
result = isc_task_beginexclusive(named_g_server->task);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
isc_nm_settimeouts(named_g_nm, initial, idle, keepalive,
|
||||
isc_nm_settimeouts(named_g_netmgr, initial, idle, keepalive,
|
||||
advertised);
|
||||
|
||||
isc_task_endexclusive(named_g_server->task);
|
||||
|
|
|
|||
|
|
@ -3612,7 +3612,7 @@ add_listener(named_server_t *server, named_statschannel_t **listenerp,
|
|||
CHECK(ISC_R_FAMILYNOSUPPORT);
|
||||
}
|
||||
|
||||
CHECK(isc_httpdmgr_create(named_g_nm, server->mctx, addr, client_ok,
|
||||
CHECK(isc_httpdmgr_create(named_g_netmgr, server->mctx, addr, client_ok,
|
||||
destroy_listener, listener,
|
||||
&listener->httpdmgr));
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include <isc/hash.h>
|
||||
#include <isc/lex.h>
|
||||
#include <isc/log.h>
|
||||
#include <isc/managers.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/nonce.h>
|
||||
#include <isc/parseint.h>
|
||||
|
|
@ -923,16 +924,8 @@ setup_system(void) {
|
|||
result = dns_dispatchmgr_create(gmctx, &dispatchmgr);
|
||||
check_result(result, "dns_dispatchmgr_create");
|
||||
|
||||
result = isc_socketmgr_create(gmctx, &socketmgr);
|
||||
check_result(result, "dns_socketmgr_create");
|
||||
|
||||
result = isc_timermgr_create(gmctx, &timermgr);
|
||||
check_result(result, "dns_timermgr_create");
|
||||
|
||||
netmgr = isc_nm_start(gmctx, 1);
|
||||
|
||||
result = isc_taskmgr_create(gmctx, 0, netmgr, &taskmgr);
|
||||
check_result(result, "isc_taskmgr_create");
|
||||
isc_managers_create(gmctx, 1, 0, 0, &netmgr, &taskmgr, &timermgr,
|
||||
&socketmgr);
|
||||
|
||||
result = isc_task_create(taskmgr, 0, &global_task);
|
||||
check_result(result, "isc_task_create");
|
||||
|
|
@ -3325,21 +3318,12 @@ cleanup(void) {
|
|||
dst_key_free(&sig0key);
|
||||
}
|
||||
|
||||
ddebug("Shutting down task manager");
|
||||
isc_taskmgr_destroy(&taskmgr);
|
||||
|
||||
ddebug("Shutting down network manager");
|
||||
isc_nm_destroy(&netmgr);
|
||||
ddebug("Shutting down managers");
|
||||
isc_managers_destroy(&netmgr, &taskmgr, &timermgr, &socketmgr);
|
||||
|
||||
ddebug("Destroying event");
|
||||
isc_event_free(&global_event);
|
||||
|
||||
ddebug("Shutting down socket manager");
|
||||
isc_socketmgr_destroy(&socketmgr);
|
||||
|
||||
ddebug("Shutting down timer manager");
|
||||
isc_timermgr_destroy(&timermgr);
|
||||
|
||||
#ifdef HAVE_GSSAPI
|
||||
/*
|
||||
* Cleanup GSSAPI resources after taskmgr has been destroyed.
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include <isc/commandline.h>
|
||||
#include <isc/file.h>
|
||||
#include <isc/log.h>
|
||||
#include <isc/managers.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/net.h>
|
||||
#include <isc/netmgr.h>
|
||||
|
|
@ -59,6 +60,7 @@
|
|||
const char *progname = NULL;
|
||||
bool verbose;
|
||||
|
||||
static isc_nm_t *netmgr = NULL;
|
||||
static isc_taskmgr_t *taskmgr = NULL;
|
||||
static isc_task_t *rndc_task = NULL;
|
||||
|
||||
|
|
@ -72,7 +74,6 @@ static bool local4set = false, local6set = false;
|
|||
static int nserveraddrs;
|
||||
static int currentaddr = 0;
|
||||
static unsigned int remoteport = 0;
|
||||
static isc_nm_t *netmgr = NULL;
|
||||
static isc_buffer_t *databuf = NULL;
|
||||
static isccc_ccmsg_t rndc_ccmsg;
|
||||
static uint32_t algorithm;
|
||||
|
|
@ -1030,9 +1031,7 @@ main(int argc, char **argv) {
|
|||
serial = isc_random32();
|
||||
|
||||
isc_mem_create(&rndc_mctx);
|
||||
netmgr = isc_nm_start(rndc_mctx, 1);
|
||||
DO("create task manager",
|
||||
isc_taskmgr_create(rndc_mctx, 0, netmgr, &taskmgr));
|
||||
isc_managers_create(rndc_mctx, 1, 0, 0, &netmgr, &taskmgr, NULL, NULL);
|
||||
DO("create task", isc_task_create(taskmgr, 0, &rndc_task));
|
||||
isc_log_create(rndc_mctx, &log, &logconfig);
|
||||
isc_log_setcontext(log);
|
||||
|
|
@ -1089,9 +1088,7 @@ main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
isc_task_detach(&rndc_task);
|
||||
isc_taskmgr_destroy(&taskmgr);
|
||||
|
||||
isc_nm_closedown(netmgr);
|
||||
isc_managers_destroy(&netmgr, &taskmgr, NULL, NULL);
|
||||
|
||||
/*
|
||||
* Note: when TCP connections are shut down, there will be a final
|
||||
|
|
@ -1101,8 +1098,6 @@ main(int argc, char **argv) {
|
|||
*/
|
||||
isccc_ccmsg_invalidate(&rndc_ccmsg);
|
||||
|
||||
isc_nm_destroy(&netmgr);
|
||||
|
||||
isc_log_destroy(&log);
|
||||
isc_log_setcontext(NULL);
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include <isc/commandline.h>
|
||||
#include <isc/hash.h>
|
||||
#include <isc/log.h>
|
||||
#include <isc/managers.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/net.h>
|
||||
#include <isc/parseint.h>
|
||||
|
|
@ -208,10 +209,10 @@ main(int argc, char *argv[]) {
|
|||
isc_logconfig_t *lcfg;
|
||||
isc_nm_t *netmgr = NULL;
|
||||
isc_taskmgr_t *taskmgr = NULL;
|
||||
isc_task_t *task;
|
||||
isc_timermgr_t *timermgr;
|
||||
isc_socketmgr_t *socketmgr;
|
||||
dns_dispatchmgr_t *dispatchmgr;
|
||||
isc_task_t *task = NULL;
|
||||
isc_timermgr_t *timermgr = NULL;
|
||||
isc_socketmgr_t *socketmgr = NULL;
|
||||
dns_dispatchmgr_t *dispatchmgr = NULL;
|
||||
unsigned int attrs, attrmask;
|
||||
dns_dispatch_t *dispatchv4;
|
||||
dns_view_t *view;
|
||||
|
|
@ -277,17 +278,10 @@ main(int argc, char *argv[]) {
|
|||
|
||||
RUNCHECK(dst_lib_init(mctx, NULL));
|
||||
|
||||
netmgr = isc_nm_start(mctx, 1);
|
||||
isc_managers_create(mctx, 1, 0, 0, &netmgr, &taskmgr, &timermgr,
|
||||
&socketmgr);
|
||||
|
||||
RUNCHECK(isc_taskmgr_create(mctx, 0, netmgr, &taskmgr));
|
||||
task = NULL;
|
||||
RUNCHECK(isc_task_create(taskmgr, 0, &task));
|
||||
timermgr = NULL;
|
||||
|
||||
RUNCHECK(isc_timermgr_create(mctx, &timermgr));
|
||||
socketmgr = NULL;
|
||||
RUNCHECK(isc_socketmgr_create(mctx, &socketmgr));
|
||||
dispatchmgr = NULL;
|
||||
RUNCHECK(dns_dispatchmgr_create(mctx, &dispatchmgr));
|
||||
|
||||
attrs = DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_MAKEQUERY |
|
||||
|
|
@ -318,13 +312,10 @@ main(int argc, char *argv[]) {
|
|||
dns_dispatch_detach(&dispatchv4);
|
||||
dns_dispatchmgr_destroy(&dispatchmgr);
|
||||
|
||||
isc_socketmgr_destroy(&socketmgr);
|
||||
isc_timermgr_destroy(&timermgr);
|
||||
|
||||
isc_task_shutdown(task);
|
||||
isc_task_detach(&task);
|
||||
isc_taskmgr_destroy(&taskmgr);
|
||||
isc_nm_destroy(&netmgr);
|
||||
|
||||
isc_managers_destroy(&netmgr, &taskmgr, &timermgr, &socketmgr);
|
||||
|
||||
dst_lib_destroy();
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include <isc/buffer.h>
|
||||
#include <isc/commandline.h>
|
||||
#include <isc/lib.h>
|
||||
#include <isc/managers.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/print.h>
|
||||
#include <isc/sockaddr.h>
|
||||
|
|
@ -66,25 +67,8 @@ isc_timermgr_t *ctxs_timermgr = NULL;
|
|||
|
||||
static void
|
||||
ctxs_destroy(void) {
|
||||
if (ctxs_netmgr != NULL) {
|
||||
isc_nm_closedown(ctxs_netmgr);
|
||||
}
|
||||
|
||||
if (ctxs_taskmgr != NULL) {
|
||||
isc_taskmgr_destroy(&ctxs_taskmgr);
|
||||
}
|
||||
|
||||
if (ctxs_netmgr != NULL) {
|
||||
isc_nm_destroy(&ctxs_netmgr);
|
||||
}
|
||||
|
||||
if (ctxs_timermgr != NULL) {
|
||||
isc_timermgr_destroy(&ctxs_timermgr);
|
||||
}
|
||||
|
||||
if (ctxs_socketmgr != NULL) {
|
||||
isc_socketmgr_destroy(&ctxs_socketmgr);
|
||||
}
|
||||
isc_managers_destroy(&ctxs_netmgr, &ctxs_taskmgr, &ctxs_timermgr,
|
||||
&ctxs_socketmgr);
|
||||
|
||||
if (ctxs_actx != NULL) {
|
||||
isc_appctx_destroy(&ctxs_actx);
|
||||
|
|
@ -106,22 +90,8 @@ ctxs_init(void) {
|
|||
goto fail;
|
||||
}
|
||||
|
||||
ctxs_netmgr = isc_nm_start(ctxs_mctx, 1);
|
||||
|
||||
result = isc_taskmgr_create(ctxs_mctx, 0, ctxs_netmgr, &ctxs_taskmgr);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
result = isc_socketmgr_create(ctxs_mctx, &ctxs_socketmgr);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
result = isc_timermgr_create(ctxs_mctx, &ctxs_timermgr);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto fail;
|
||||
}
|
||||
isc_managers_create(ctxs_mctx, 1, 0, 0, &ctxs_netmgr, &ctxs_taskmgr,
|
||||
&ctxs_timermgr, &ctxs_socketmgr);
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include <isc/base64.h>
|
||||
#include <isc/hash.h>
|
||||
#include <isc/log.h>
|
||||
#include <isc/managers.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/nonce.h>
|
||||
#include <isc/print.h>
|
||||
|
|
@ -191,21 +192,21 @@ sendquery(isc_task_t *task, isc_event_t *event) {
|
|||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
char *ourkeyname;
|
||||
char *ourkeyname = NULL;
|
||||
isc_nm_t *netmgr = NULL;
|
||||
isc_taskmgr_t *taskmgr = NULL;
|
||||
isc_timermgr_t *timermgr;
|
||||
isc_socketmgr_t *socketmgr;
|
||||
isc_socket_t *sock;
|
||||
isc_timermgr_t *timermgr = NULL;
|
||||
isc_socketmgr_t *socketmgr = NULL;
|
||||
isc_socket_t *sock = NULL;
|
||||
unsigned int attrs, attrmask;
|
||||
isc_sockaddr_t bind_any;
|
||||
dns_dispatchmgr_t *dispatchmgr;
|
||||
dns_dispatch_t *dispatchv4;
|
||||
dns_view_t *view;
|
||||
dns_tkeyctx_t *tctx;
|
||||
isc_log_t *log;
|
||||
isc_logconfig_t *logconfig;
|
||||
isc_task_t *task;
|
||||
dns_dispatchmgr_t *dispatchmgr = NULL;
|
||||
dns_dispatch_t *dispatchv4 = NULL;
|
||||
dns_view_t *view = NULL;
|
||||
dns_tkeyctx_t *tctx = NULL;
|
||||
isc_log_t *log = NULL;
|
||||
isc_logconfig_t *logconfig = NULL;
|
||||
isc_task_t *task = NULL;
|
||||
isc_result_t result;
|
||||
int type;
|
||||
|
||||
|
|
@ -235,17 +236,12 @@ main(int argc, char *argv[]) {
|
|||
|
||||
RUNCHECK(dst_lib_init(mctx, NULL));
|
||||
|
||||
netmgr = isc_nm_start(mctx, 1);
|
||||
isc_managers_create(mctx, 1, 0, 0, &netmgr, &taskmgr, &timermgr,
|
||||
&socketmgr);
|
||||
|
||||
RUNCHECK(isc_taskmgr_create(mctx, 0, netmgr, &taskmgr));
|
||||
task = NULL;
|
||||
RUNCHECK(isc_task_create(taskmgr, 0, &task));
|
||||
timermgr = NULL;
|
||||
RUNCHECK(isc_timermgr_create(mctx, &timermgr));
|
||||
socketmgr = NULL;
|
||||
RUNCHECK(isc_socketmgr_create(mctx, &socketmgr));
|
||||
dispatchmgr = NULL;
|
||||
RUNCHECK(dns_dispatchmgr_create(mctx, &dispatchmgr));
|
||||
|
||||
isc_sockaddr_any(&bind_any);
|
||||
attrs = DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_MAKEQUERY |
|
||||
DNS_DISPATCHATTR_IPV4;
|
||||
|
|
@ -293,11 +289,8 @@ main(int argc, char *argv[]) {
|
|||
dns_dispatchmgr_destroy(&dispatchmgr);
|
||||
isc_task_shutdown(task);
|
||||
isc_task_detach(&task);
|
||||
isc_taskmgr_destroy(&taskmgr);
|
||||
isc_nm_destroy(&netmgr);
|
||||
isc_socket_detach(&sock);
|
||||
isc_socketmgr_destroy(&socketmgr);
|
||||
isc_timermgr_destroy(&timermgr);
|
||||
isc_managers_destroy(&netmgr, &taskmgr, &timermgr, &socketmgr);
|
||||
|
||||
dst_key_free(&ourkey);
|
||||
dns_tsigkey_detach(&initialkey);
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include <isc/base64.h>
|
||||
#include <isc/hash.h>
|
||||
#include <isc/log.h>
|
||||
#include <isc/managers.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/netmgr.h>
|
||||
#include <isc/print.h>
|
||||
|
|
@ -135,22 +136,22 @@ sendquery(isc_task_t *task, isc_event_t *event) {
|
|||
|
||||
int
|
||||
main(int argc, char **argv) {
|
||||
char *keyname;
|
||||
isc_nm_t *netmgr;
|
||||
char *keyname = NULL;
|
||||
isc_nm_t *netmgr = NULL;
|
||||
isc_taskmgr_t *taskmgr = NULL;
|
||||
isc_timermgr_t *timermgr;
|
||||
isc_socketmgr_t *socketmgr;
|
||||
isc_socket_t *sock;
|
||||
isc_timermgr_t *timermgr = NULL;
|
||||
isc_socketmgr_t *socketmgr = NULL;
|
||||
isc_socket_t *sock = NULL;
|
||||
unsigned int attrs, attrmask;
|
||||
isc_sockaddr_t bind_any;
|
||||
dns_dispatchmgr_t *dispatchmgr;
|
||||
dns_dispatch_t *dispatchv4;
|
||||
dns_view_t *view;
|
||||
dns_tkeyctx_t *tctx;
|
||||
dst_key_t *dstkey;
|
||||
isc_log_t *log;
|
||||
isc_logconfig_t *logconfig;
|
||||
isc_task_t *task;
|
||||
dns_dispatchmgr_t *dispatchmgr = NULL;
|
||||
dns_dispatch_t *dispatchv4 = NULL;
|
||||
dns_view_t *view = NULL;
|
||||
dns_tkeyctx_t *tctx = NULL;
|
||||
dst_key_t *dstkey = NULL;
|
||||
isc_log_t *log = NULL;
|
||||
isc_logconfig_t *logconfig = NULL;
|
||||
isc_task_t *task = NULL;
|
||||
isc_result_t result;
|
||||
int type;
|
||||
|
||||
|
|
@ -179,16 +180,10 @@ main(int argc, char **argv) {
|
|||
|
||||
RUNCHECK(dst_lib_init(mctx, NULL));
|
||||
|
||||
netmgr = isc_nm_start(mctx, 1);
|
||||
isc_managers_create(mctx, 1, 0, 0, &netmgr, &taskmgr, &timermgr,
|
||||
&socketmgr);
|
||||
|
||||
RUNCHECK(isc_taskmgr_create(mctx, 0, netmgr, &taskmgr));
|
||||
task = NULL;
|
||||
RUNCHECK(isc_task_create(taskmgr, 0, &task));
|
||||
timermgr = NULL;
|
||||
RUNCHECK(isc_timermgr_create(mctx, &timermgr));
|
||||
socketmgr = NULL;
|
||||
RUNCHECK(isc_socketmgr_create(mctx, &socketmgr));
|
||||
dispatchmgr = NULL;
|
||||
RUNCHECK(dns_dispatchmgr_create(mctx, &dispatchmgr));
|
||||
isc_sockaddr_any(&bind_any);
|
||||
attrs = DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_MAKEQUERY |
|
||||
|
|
@ -237,11 +232,8 @@ main(int argc, char **argv) {
|
|||
dns_dispatchmgr_destroy(&dispatchmgr);
|
||||
isc_task_shutdown(task);
|
||||
isc_task_detach(&task);
|
||||
isc_taskmgr_destroy(&taskmgr);
|
||||
isc_nm_destroy(&netmgr);
|
||||
isc_socket_detach(&sock);
|
||||
isc_socketmgr_destroy(&socketmgr);
|
||||
isc_timermgr_destroy(&timermgr);
|
||||
isc_managers_destroy(&netmgr, &taskmgr, &timermgr, &socketmgr);
|
||||
|
||||
dns_tsigkeyring_detach(&ring);
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <isc/managers.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/netaddr.h>
|
||||
#include <isc/netmgr.h>
|
||||
|
|
@ -307,7 +308,7 @@ setup(void) {
|
|||
|
||||
isc_mem_create(&mctx);
|
||||
|
||||
netmgr = isc_nm_start(mctx, workers);
|
||||
isc_managers_create(mctx, workers, 0, 0, &netmgr, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -316,7 +317,7 @@ teardown(void) {
|
|||
close(out);
|
||||
}
|
||||
|
||||
isc_nm_destroy(&netmgr);
|
||||
isc_managers_destroy(&netmgr, NULL, NULL, NULL);
|
||||
isc_mem_destroy(&mctx);
|
||||
if (tls_ctx) {
|
||||
isc_tlsctx_free(&tls_ctx);
|
||||
|
|
@ -464,8 +465,6 @@ run(void) {
|
|||
}
|
||||
|
||||
waitforsignal();
|
||||
|
||||
isc_nm_closedown(netmgr);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include <isc/managers.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/netaddr.h>
|
||||
#include <isc/netmgr.h>
|
||||
|
|
@ -188,12 +189,12 @@ setup(void) {
|
|||
|
||||
isc_mem_create(&mctx);
|
||||
|
||||
netmgr = isc_nm_start(mctx, workers);
|
||||
isc_managers_create(mctx, workers, 0, 0, &netmgr, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
teardown(void) {
|
||||
isc_nm_destroy(&netmgr);
|
||||
isc_managers_destroy(&netmgr, NULL, NULL, NULL);
|
||||
isc_mem_destroy(&mctx);
|
||||
if (tls_ctx) {
|
||||
isc_tlsctx_free(&tls_ctx);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include <isc/hash.h>
|
||||
#include <isc/hex.h>
|
||||
#include <isc/log.h>
|
||||
#include <isc/managers.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/net.h>
|
||||
#include <isc/nonce.h>
|
||||
|
|
@ -2070,10 +2071,10 @@ main(int argc, char *argv[]) {
|
|||
isc_logconfig_t *lcfg;
|
||||
isc_nm_t *netmgr = NULL;
|
||||
isc_taskmgr_t *taskmgr = NULL;
|
||||
isc_task_t *task;
|
||||
isc_timermgr_t *timermgr;
|
||||
isc_socketmgr_t *socketmgr;
|
||||
dns_dispatchmgr_t *dispatchmgr;
|
||||
isc_task_t *task = NULL;
|
||||
isc_timermgr_t *timermgr = NULL;
|
||||
isc_socketmgr_t *socketmgr = NULL;
|
||||
dns_dispatchmgr_t *dispatchmgr = NULL;
|
||||
unsigned int attrs, attrmask;
|
||||
dns_dispatch_t *dispatchvx;
|
||||
dns_view_t *view;
|
||||
|
|
@ -2130,17 +2131,11 @@ main(int argc, char *argv[]) {
|
|||
fatal("can't choose between IPv4 and IPv6");
|
||||
}
|
||||
|
||||
netmgr = isc_nm_start(mctx, 1);
|
||||
isc_managers_create(mctx, 1, 0, 0, &netmgr, &taskmgr, &timermgr,
|
||||
&socketmgr);
|
||||
|
||||
RUNCHECK(isc_taskmgr_create(mctx, 0, netmgr, &taskmgr));
|
||||
task = NULL;
|
||||
RUNCHECK(isc_task_create(taskmgr, 0, &task));
|
||||
timermgr = NULL;
|
||||
|
||||
RUNCHECK(isc_timermgr_create(mctx, &timermgr));
|
||||
socketmgr = NULL;
|
||||
RUNCHECK(isc_socketmgr_create(mctx, &socketmgr));
|
||||
dispatchmgr = NULL;
|
||||
RUNCHECK(dns_dispatchmgr_create(mctx, &dispatchmgr));
|
||||
|
||||
attrs = DNS_DISPATCHATTR_UDP | DNS_DISPATCHATTR_MAKEQUERY;
|
||||
|
|
@ -2206,13 +2201,10 @@ main(int argc, char *argv[]) {
|
|||
dns_dispatch_detach(&dispatchvx);
|
||||
dns_dispatchmgr_destroy(&dispatchmgr);
|
||||
|
||||
isc_socketmgr_destroy(&socketmgr);
|
||||
isc_timermgr_destroy(&timermgr);
|
||||
|
||||
isc_task_shutdown(task);
|
||||
isc_task_detach(&task);
|
||||
isc_taskmgr_destroy(&taskmgr);
|
||||
isc_nm_destroy(&netmgr);
|
||||
|
||||
isc_managers_destroy(&netmgr, &taskmgr, &timermgr, &socketmgr);
|
||||
|
||||
dst_lib_destroy();
|
||||
|
||||
|
|
|
|||
|
|
@ -1735,6 +1735,12 @@ dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone);
|
|||
*\li 'zone->zmgr' == NULL;
|
||||
*/
|
||||
|
||||
isc_taskmgr_t *
|
||||
dns_zonemgr_gettaskmgr(dns_zonemgr_t *zmgr);
|
||||
/*%
|
||||
* Get the tasmkgr object attached to 'zmgr'.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, uint32_t value);
|
||||
/*%<
|
||||
|
|
@ -1746,7 +1752,7 @@ dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, uint32_t value);
|
|||
*/
|
||||
|
||||
uint32_t
|
||||
dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr);
|
||||
dns_zonemgr_gettransfersin(dns_zonemgr_t *zmgr);
|
||||
/*%<
|
||||
* Return the maximum number of simultaneous transfers in allowed.
|
||||
*
|
||||
|
|
@ -1764,7 +1770,7 @@ dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, uint32_t value);
|
|||
*/
|
||||
|
||||
uint32_t
|
||||
dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr);
|
||||
dns_zonemgr_gettransfersperns(dns_zonemgr_t *zmgr);
|
||||
/*%<
|
||||
* Return the number of transfers allowed per nameserver.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include <isc/hash.h>
|
||||
#include <isc/hex.h>
|
||||
#include <isc/lex.h>
|
||||
#include <isc/managers.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/os.h>
|
||||
#include <isc/print.h>
|
||||
|
|
@ -95,18 +96,10 @@ cleanup_managers(void) {
|
|||
isc_task_shutdown(maintask);
|
||||
isc_task_destroy(&maintask);
|
||||
}
|
||||
if (socketmgr != NULL) {
|
||||
isc_socketmgr_destroy(&socketmgr);
|
||||
}
|
||||
if (taskmgr != NULL) {
|
||||
isc_taskmgr_destroy(&taskmgr);
|
||||
}
|
||||
if (netmgr != NULL) {
|
||||
isc_nm_destroy(&netmgr);
|
||||
}
|
||||
if (timermgr != NULL) {
|
||||
isc_timermgr_destroy(&timermgr);
|
||||
}
|
||||
isc_managers_destroy(netmgr == NULL ? NULL : &netmgr,
|
||||
taskmgr == NULL ? NULL : &taskmgr,
|
||||
timermgr == NULL ? NULL : &timermgr,
|
||||
socketmgr == NULL ? NULL : &socketmgr);
|
||||
if (app_running) {
|
||||
isc_app_finish();
|
||||
}
|
||||
|
|
@ -117,10 +110,8 @@ create_managers(void) {
|
|||
isc_result_t result;
|
||||
ncpus = isc_os_ncpus();
|
||||
|
||||
netmgr = isc_nm_start(dt_mctx, ncpus);
|
||||
CHECK(isc_taskmgr_create(dt_mctx, 0, netmgr, &taskmgr));
|
||||
CHECK(isc_timermgr_create(dt_mctx, &timermgr));
|
||||
CHECK(isc_socketmgr_create(dt_mctx, &socketmgr));
|
||||
isc_managers_create(dt_mctx, ncpus, 0, 0, &netmgr, &taskmgr, &timermgr,
|
||||
&socketmgr);
|
||||
CHECK(isc_task_create(taskmgr, 0, &maintask));
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
|
|
|
|||
|
|
@ -1389,8 +1389,9 @@ dns_zonemgr_getiolimit
|
|||
dns_zonemgr_getnotifyrate
|
||||
dns_zonemgr_getserialqueryrate
|
||||
dns_zonemgr_getstartupnotifyrate
|
||||
dns_zonemgr_getttransfersin
|
||||
dns_zonemgr_getttransfersperns
|
||||
dns_zonemgr_gettaskmgr
|
||||
dns_zonemgr_gettransfersin
|
||||
dns_zonemgr_gettransfersperns
|
||||
dns_zonemgr_managezone
|
||||
dns_zonemgr_releasezone
|
||||
dns_zonemgr_resumexfrs
|
||||
|
|
|
|||
|
|
@ -18478,7 +18478,7 @@ dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, uint32_t value) {
|
|||
}
|
||||
|
||||
uint32_t
|
||||
dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) {
|
||||
dns_zonemgr_gettransfersin(dns_zonemgr_t *zmgr) {
|
||||
REQUIRE(DNS_ZONEMGR_VALID(zmgr));
|
||||
|
||||
return (zmgr->transfersin);
|
||||
|
|
@ -18492,12 +18492,19 @@ dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, uint32_t value) {
|
|||
}
|
||||
|
||||
uint32_t
|
||||
dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) {
|
||||
dns_zonemgr_gettransfersperns(dns_zonemgr_t *zmgr) {
|
||||
REQUIRE(DNS_ZONEMGR_VALID(zmgr));
|
||||
|
||||
return (zmgr->transfersperns);
|
||||
}
|
||||
|
||||
isc_taskmgr_t *
|
||||
dns_zonemgr_gettaskmgr(dns_zonemgr_t *zmgr) {
|
||||
REQUIRE(DNS_ZONEMGR_VALID(zmgr));
|
||||
|
||||
return (zmgr->taskmgr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to start a new incoming zone transfer to fill a quota
|
||||
* slot that was just vacated.
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ libisc_la_HEADERS = \
|
|||
include/isc/atomic.h \
|
||||
include/isc/attributes.h \
|
||||
include/isc/backtrace.h \
|
||||
include/isc/barrier.h \
|
||||
include/isc/base32.h \
|
||||
include/isc/base64.h \
|
||||
include/isc/bind9.h \
|
||||
|
|
@ -46,6 +47,7 @@ libisc_la_HEADERS = \
|
|||
include/isc/list.h \
|
||||
include/isc/log.h \
|
||||
include/isc/magic.h \
|
||||
include/isc/managers.h \
|
||||
include/isc/md.h \
|
||||
include/isc/mem.h \
|
||||
include/isc/meminfo.h \
|
||||
|
|
@ -182,6 +184,7 @@ libisc_la_SOURCES = \
|
|||
lex.c \
|
||||
lib.c \
|
||||
log.c \
|
||||
managers.c \
|
||||
md.c \
|
||||
mem.c \
|
||||
mutexblock.c \
|
||||
|
|
@ -222,6 +225,10 @@ libisc_la_SOURCES = \
|
|||
pthreads/thread.c \
|
||||
entropy_private.h \
|
||||
fsaccess_common_p.h \
|
||||
task_p.h \
|
||||
timer_p.h \
|
||||
socket_p.h \
|
||||
netmgr_p.h \
|
||||
lib_p.h \
|
||||
mem_p.h \
|
||||
tls_p.h
|
||||
|
|
|
|||
|
|
@ -82,6 +82,9 @@ tid(void) {
|
|||
|
||||
void
|
||||
isc_hp_init(int max_threads) {
|
||||
if (isc__hp_max_threads > max_threads) {
|
||||
return;
|
||||
}
|
||||
isc__hp_max_threads = max_threads;
|
||||
isc__hp_max_retired = max_threads * HP_MAX_HPS;
|
||||
}
|
||||
|
|
|
|||
37
lib/isc/include/isc/barrier.h
Normal file
37
lib/isc/include/isc/barrier.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <isc/util.h>
|
||||
|
||||
#if __SANITIZE_THREAD__ && !defined(WIN32)
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#define isc_barrier_t pthread_barrier_t
|
||||
|
||||
#define isc_barrier_init(barrier, count) \
|
||||
pthread_barrier_init(barrier, NULL, count)
|
||||
#define isc_barrier_destroy(barrier) pthread_barrier_destroy(barrier)
|
||||
#define isc_barrier_wait(barrier) pthread_barrier_wait(barrier)
|
||||
|
||||
#else
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
#define isc_barrier_t uv_barrier_t
|
||||
|
||||
#define isc_barrier_init(barrier, count) uv_barrier_init(barrier, count)
|
||||
#define isc_barrier_destroy(barrier) uv_barrier_destroy(barrier)
|
||||
#define isc_barrier_wait(barrier) uv_barrier_wait(barrier)
|
||||
|
||||
#endif /* __SANITIZE_THREAD__ */
|
||||
|
|
@ -66,8 +66,10 @@ typedef void(isc_hp_deletefunc_t)(void *);
|
|||
void
|
||||
isc_hp_init(int max_threads);
|
||||
/*%<
|
||||
* Initialize hazard pointer constants - isc__hp_max_threads. If more threads
|
||||
* will try to access hp it will assert.
|
||||
* Initialize hazard pointer constants, isc__hp_max_threads and
|
||||
* isc__hp_max_retired. If more threads try to access hp, it
|
||||
* will assert. Calling this function repeatedly can be used
|
||||
* to increase the limits, but cannot reduce them.
|
||||
*/
|
||||
|
||||
isc_hp_t *
|
||||
|
|
|
|||
30
lib/isc/include/isc/managers.h
Normal file
30
lib/isc/include/isc/managers.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <isc/netmgr.h>
|
||||
#include <isc/result.h>
|
||||
#include <isc/socket.h>
|
||||
#include <isc/task.h>
|
||||
#include <isc/timer.h>
|
||||
|
||||
typedef struct isc_managers isc_managers_t;
|
||||
|
||||
isc_result_t
|
||||
isc_managers_create(isc_mem_t *mctx, size_t workers, size_t quantum,
|
||||
size_t sockets, isc_nm_t **netmgrp,
|
||||
isc_taskmgr_t **taskmgrp, isc_timermgr_t **timermgrp,
|
||||
isc_socketmgr_t **socketmgrp);
|
||||
|
||||
void
|
||||
isc_managers_destroy(isc_nm_t **netmgrp, isc_taskmgr_t **taskmgrp,
|
||||
isc_timermgr_t **timermgrp, isc_socketmgr_t **socketmgrp);
|
||||
|
|
@ -68,19 +68,10 @@ typedef void (*isc_nm_opaquecb_t)(void *arg);
|
|||
* callbacks.
|
||||
*/
|
||||
|
||||
isc_nm_t *
|
||||
isc_nm_start(isc_mem_t *mctx, uint32_t workers);
|
||||
/*%<
|
||||
* Creates a new network manager with 'workers' worker threads,
|
||||
* and starts it running.
|
||||
*/
|
||||
|
||||
void
|
||||
isc_nm_attach(isc_nm_t *mgr, isc_nm_t **dst);
|
||||
void
|
||||
isc_nm_detach(isc_nm_t **mgr0);
|
||||
void
|
||||
isc_nm_destroy(isc_nm_t **mgr0);
|
||||
/*%<
|
||||
* Attach/detach a network manager. When all references have been
|
||||
* released, the network manager is shut down, freeing all resources.
|
||||
|
|
@ -88,15 +79,6 @@ isc_nm_destroy(isc_nm_t **mgr0);
|
|||
* for all other references to be gone.
|
||||
*/
|
||||
|
||||
void
|
||||
isc_nm_closedown(isc_nm_t *mgr);
|
||||
/*%<
|
||||
* Close down all active connections, freeing associated resources;
|
||||
* prevent new connections from being established. This can optionally
|
||||
* be called prior to shutting down the netmgr, to stop all processing
|
||||
* before shutting down the task manager.
|
||||
*/
|
||||
|
||||
/* Return thread ID of current thread, or ISC_NETMGR_TID_UNKNOWN */
|
||||
int
|
||||
isc_nm_tid(void);
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@
|
|||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
#ifndef ISC_SOCKET_H
|
||||
#define ISC_SOCKET_H 1
|
||||
#pragma once
|
||||
|
||||
/*****
|
||||
***** Module Info
|
||||
|
|
@ -676,42 +675,6 @@ isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region, isc_task_t *task,
|
|||
*/
|
||||
/*@}*/
|
||||
|
||||
isc_result_t
|
||||
isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp);
|
||||
|
||||
isc_result_t
|
||||
isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
|
||||
unsigned int maxsocks, int nthreads);
|
||||
/*%<
|
||||
* Create a socket manager. If "maxsocks" is non-zero, it specifies the
|
||||
* maximum number of sockets that the created manager should handle.
|
||||
* isc_socketmgr_create() is equivalent of isc_socketmgr_create2() with
|
||||
* "maxsocks" being zero.
|
||||
*
|
||||
* 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_socketmgr_t.
|
||||
*
|
||||
*\li 'actx' is a valid application context (for createinctx()).
|
||||
*
|
||||
* Ensures:
|
||||
*
|
||||
*\li '*managerp' is a valid isc_socketmgr_t.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li #ISC_R_SUCCESS
|
||||
*\li #ISC_R_NOMEMORY
|
||||
*\li #ISC_R_UNEXPECTED
|
||||
*\li #ISC_R_NOTIMPLEMENTED
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
isc_socketmgr_getmaxsockets(isc_socketmgr_t *manager, unsigned int *nsockp);
|
||||
/*%<
|
||||
|
|
@ -741,31 +704,6 @@ isc_socketmgr_setstats(isc_socketmgr_t *manager, isc_stats_t *stats);
|
|||
* (see above).
|
||||
*/
|
||||
|
||||
void
|
||||
isc_socketmgr_destroy(isc_socketmgr_t **managerp);
|
||||
/*%<
|
||||
* Destroy a socket manager.
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
*\li This routine blocks until there are no sockets left in the manager,
|
||||
* so if the caller holds any socket references using the manager, it
|
||||
* must detach them before calling isc_socketmgr_destroy() or it will
|
||||
* block forever.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li '*managerp' is a valid isc_socketmgr_t.
|
||||
*
|
||||
*\li All sockets managed by this manager are fully detached.
|
||||
*
|
||||
* Ensures:
|
||||
*
|
||||
*\li *managerp == NULL
|
||||
*
|
||||
*\li All resources used by the manager have been freed.
|
||||
*/
|
||||
|
||||
isc_sockettype_t
|
||||
isc_socket_gettype(isc_socket_t *sock);
|
||||
/*%<
|
||||
|
|
@ -908,5 +846,3 @@ typedef isc_result_t (*isc_socketmgrcreatefunc_t)(isc_mem_t * mctx,
|
|||
isc_socketmgr_t **managerp);
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
#endif /* ISC_SOCKET_H */
|
||||
|
|
|
|||
|
|
@ -9,12 +9,11 @@
|
|||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
#ifndef ISC_TASK_H
|
||||
#define ISC_TASK_H 1
|
||||
#pragma once
|
||||
|
||||
/*****
|
||||
***** Module Info
|
||||
*****/
|
||||
***** Module Info
|
||||
*****/
|
||||
|
||||
/*! \file isc/task.h
|
||||
* \brief The task system provides a lightweight execution context, which is
|
||||
|
|
@ -85,8 +84,8 @@
|
|||
#define ISC_TASKEVENT_LASTEVENT (ISC_EVENTCLASS_TASK + 65535)
|
||||
|
||||
/*****
|
||||
***** Tasks.
|
||||
*****/
|
||||
***** Tasks.
|
||||
*****/
|
||||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
|
|
@ -137,6 +136,12 @@ isc_task_create_bound(isc_taskmgr_t *manager, unsigned int quantum,
|
|||
*\li #ISC_R_SHUTTINGDOWN
|
||||
*/
|
||||
|
||||
void
|
||||
isc_task_ready(isc_task_t *task);
|
||||
/*%<
|
||||
* Enqueue the task onto netmgr queue.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
isc_task_run(isc_task_t *task);
|
||||
/*%<
|
||||
|
|
@ -606,15 +611,15 @@ isc_task_setprivilege(isc_task_t *task, bool priv);
|
|||
* but when the task manager has been set to privileged execution mode via
|
||||
* isc_taskmgr_setmode(), only tasks with the flag set will be executed,
|
||||
* and all other tasks will wait until they're done. Once all privileged
|
||||
* tasks have finished executing, the task manager will automatically
|
||||
* return to normal execution mode and nonprivileged task can resume.
|
||||
* tasks have finished executing, the task manager resumes running
|
||||
* non-privileged tasks.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'task' is a valid task.
|
||||
*/
|
||||
|
||||
bool
|
||||
isc_task_privilege(isc_task_t *task);
|
||||
isc_task_getprivilege(isc_task_t *task);
|
||||
/*%<
|
||||
* Returns the current value of the task's privilege flag.
|
||||
*
|
||||
|
|
@ -622,83 +627,47 @@ isc_task_privilege(isc_task_t *task);
|
|||
*\li 'task' is a valid task.
|
||||
*/
|
||||
|
||||
/*****
|
||||
***** Task Manager.
|
||||
*****/
|
||||
|
||||
isc_result_t
|
||||
isc_taskmgr_create(isc_mem_t *mctx, unsigned int default_quantum, isc_nm_t *nm,
|
||||
isc_taskmgr_t **managerp);
|
||||
bool
|
||||
isc_task_privileged(isc_task_t *task);
|
||||
/*%<
|
||||
* Create a new task manager.
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
*\li If 'default_quantum' is non-zero, then it will be used as the default
|
||||
* quantum value when tasks are created. If zero, then an implementation
|
||||
* defined default quantum will be used.
|
||||
*
|
||||
*\li If 'nm' is set then netmgr is paused when an exclusive task mode
|
||||
* is requested.
|
||||
* Returns true if the task's privilege flag is set *and* the task
|
||||
* manager is currently in privileged mode.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'mctx' is a valid memory context.
|
||||
*
|
||||
*\li managerp != NULL && *managerp == NULL
|
||||
*
|
||||
* Ensures:
|
||||
*
|
||||
*\li On success, '*managerp' will be attached to the newly created task
|
||||
* manager.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li #ISC_R_SUCCESS
|
||||
*\li #ISC_R_NOMEMORY
|
||||
*\li #ISC_R_NOTHREADS No threads could be created.
|
||||
*\li #ISC_R_UNEXPECTED An unexpected error occurred.
|
||||
*\li #ISC_R_SHUTTINGDOWN The non-threaded, shared, task
|
||||
* manager shutting down.
|
||||
*\li 'task' is a valid task.
|
||||
*/
|
||||
|
||||
/*****
|
||||
***** Task Manager.
|
||||
*****/
|
||||
|
||||
void
|
||||
isc_taskmgr_attach(isc_taskmgr_t *, isc_taskmgr_t **);
|
||||
void
|
||||
isc_taskmgr_detach(isc_taskmgr_t *);
|
||||
/*%<
|
||||
* Attach/detach the task manager.
|
||||
*/
|
||||
|
||||
void
|
||||
isc_taskmgr_destroy(isc_taskmgr_t **managerp);
|
||||
isc_taskmgr_setmode(isc_taskmgr_t *manager, isc_taskmgrmode_t mode);
|
||||
isc_taskmgrmode_t
|
||||
isc_taskmgr_mode(isc_taskmgr_t *manager);
|
||||
/*%<
|
||||
* Destroy '*managerp'.
|
||||
* Set/get the operating mode of the task manager. Valid modes are:
|
||||
*
|
||||
* Notes:
|
||||
*\li isc_taskmgrmode_normal
|
||||
*\li isc_taskmgrmode_privileged
|
||||
*
|
||||
*\li Calling isc_taskmgr_destroy() will shutdown all tasks managed by
|
||||
* *managerp that haven't already been shutdown. The call will block
|
||||
* until all tasks have entered the done state.
|
||||
*
|
||||
*\li isc_taskmgr_destroy() must not be called by a task event action,
|
||||
* because it would block forever waiting for the event action to
|
||||
* complete. An event action that wants to cause task manager shutdown
|
||||
* should request some non-event action thread of execution to do the
|
||||
* shutdown, e.g. by signaling a condition variable or using
|
||||
* isc_app_shutdown().
|
||||
*
|
||||
*\li Task manager references are not reference counted, so the caller
|
||||
* must ensure that no attempt will be made to use the manager after
|
||||
* isc_taskmgr_destroy() returns.
|
||||
* In privileged execution mode, only tasks that have had the "privilege"
|
||||
* flag set via isc_task_setprivilege() can be executed. When all such
|
||||
* tasks are complete, non-privileged tasks resume running. The task calling
|
||||
* this function should be in task-exclusive mode; the privileged tasks
|
||||
* will be run after isc_task_endexclusive() is called.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li '*managerp' is a valid task manager.
|
||||
*
|
||||
*\li isc_taskmgr_destroy() has not be called previously on '*managerp'.
|
||||
*
|
||||
* Ensures:
|
||||
*
|
||||
*\li All resources used by the task manager, and any tasks it managed,
|
||||
* have been freed.
|
||||
*\li 'manager' is a valid task manager.
|
||||
*/
|
||||
|
||||
void
|
||||
|
|
@ -736,5 +705,3 @@ isc_taskmgr_renderjson(isc_taskmgr_t *mgr, void *tasksobj0);
|
|||
#endif /* HAVE_JSON_C */
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
#endif /* ISC_TASK_H */
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@
|
|||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
#ifndef ISC_TIMER_H
|
||||
#define ISC_TIMER_H 1
|
||||
#pragma once
|
||||
|
||||
/*****
|
||||
***** Module Info
|
||||
|
|
@ -276,58 +275,7 @@ isc_timer_gettype(isc_timer_t *timer);
|
|||
*\li 'timer' to be a valid timer.
|
||||
*/
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
void
|
||||
isc_timermgr_poke(isc_timermgr_t *m);
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
#endif /* ISC_TIMER_H */
|
||||
|
|
|
|||
144
lib/isc/managers.c
Normal file
144
lib/isc/managers.c
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <isc/hp.h>
|
||||
#include <isc/managers.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include "netmgr_p.h"
|
||||
#include "socket_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,
|
||||
size_t sockets, isc_nm_t **netmgrp,
|
||||
isc_taskmgr_t **taskmgrp, isc_timermgr_t **timermgrp,
|
||||
isc_socketmgr_t **socketmgrp) {
|
||||
isc_result_t result;
|
||||
isc_nm_t *netmgr = NULL;
|
||||
isc_socketmgr_t *socketmgr = NULL;
|
||||
isc_taskmgr_t *taskmgr = NULL;
|
||||
isc_timermgr_t *timermgr = NULL;
|
||||
|
||||
/*
|
||||
* We have ncpus network threads, ncpus old network threads - make
|
||||
* it 4x just to be on the safe side.
|
||||
*/
|
||||
isc_hp_init(4 * workers);
|
||||
|
||||
REQUIRE(netmgrp != NULL && *netmgrp == NULL);
|
||||
isc__netmgr_create(mctx, workers, &netmgr);
|
||||
*netmgrp = netmgr;
|
||||
INSIST(netmgr != NULL);
|
||||
|
||||
REQUIRE(taskmgrp == NULL || *taskmgrp == NULL);
|
||||
if (taskmgrp != NULL) {
|
||||
INSIST(netmgr != NULL);
|
||||
result = isc__taskmgr_create(mctx, quantum, netmgr, &taskmgr);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"isc_taskmgr_create() failed: %s",
|
||||
isc_result_totext(result));
|
||||
goto fail;
|
||||
}
|
||||
*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;
|
||||
}
|
||||
|
||||
REQUIRE(socketmgrp == NULL || *socketmgrp == NULL);
|
||||
if (socketmgrp != NULL) {
|
||||
result = isc__socketmgr_create(mctx, &socketmgr, sockets,
|
||||
workers);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"isc_socketmgr_create() failed: %s",
|
||||
isc_result_totext(result));
|
||||
goto fail;
|
||||
}
|
||||
*socketmgrp = socketmgr;
|
||||
}
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
fail:
|
||||
isc_managers_destroy(netmgrp, taskmgrp, timermgrp, socketmgrp);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
void
|
||||
isc_managers_destroy(isc_nm_t **netmgrp, isc_taskmgr_t **taskmgrp,
|
||||
isc_timermgr_t **timermgrp, isc_socketmgr_t **socketmgrp) {
|
||||
/*
|
||||
* If we have a taskmgr to clean up, then we must also have a netmgr.
|
||||
*/
|
||||
REQUIRE(taskmgrp != NULL || netmgrp == NULL);
|
||||
|
||||
/*
|
||||
* The sequence of operations here is important:
|
||||
*
|
||||
* 1. Initiate shutdown of the taskmgr, sending shutdown events to
|
||||
* all tasks that are not already shutting down.
|
||||
*/
|
||||
if (taskmgrp != NULL) {
|
||||
INSIST(*taskmgrp != NULL);
|
||||
isc__taskmgr_shutdown(*taskmgrp);
|
||||
}
|
||||
|
||||
/*
|
||||
* 2. Initiate shutdown of the network manager, freeing clients
|
||||
* and other resources and preventing new connections, but do
|
||||
* not stop processing of existing events.
|
||||
*/
|
||||
if (netmgrp != NULL) {
|
||||
INSIST(*netmgrp != NULL);
|
||||
isc__netmgr_shutdown(*netmgrp);
|
||||
}
|
||||
|
||||
/*
|
||||
* 3. Finish destruction of the task manager when all tasks
|
||||
* have completed.
|
||||
*/
|
||||
if (taskmgrp != NULL) {
|
||||
isc__taskmgr_destroy(taskmgrp);
|
||||
}
|
||||
|
||||
/*
|
||||
* 4. Finish destruction of the netmgr, and wait until all
|
||||
* references have been released.
|
||||
*/
|
||||
if (netmgrp != NULL) {
|
||||
isc__netmgr_destroy(netmgrp);
|
||||
}
|
||||
|
||||
/*
|
||||
* 5. Clean up the remaining managers.
|
||||
*/
|
||||
if (timermgrp != NULL) {
|
||||
INSIST(*timermgrp != NULL);
|
||||
isc__timermgr_destroy(timermgrp);
|
||||
}
|
||||
if (socketmgrp != NULL) {
|
||||
INSIST(*socketmgrp != NULL);
|
||||
isc__socketmgr_destroy(socketmgrp);
|
||||
}
|
||||
}
|
||||
|
|
@ -1199,7 +1199,7 @@ isc_nm_httpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
|
||||
sock->extrahandlesize = extrahandlesize;
|
||||
sock->connect_timeout = timeout;
|
||||
sock->result = ISC_R_DEFAULT;
|
||||
sock->result = ISC_R_UNSET;
|
||||
sock->connect_cb = cb;
|
||||
sock->connect_cbarg = cbarg;
|
||||
atomic_init(&sock->client, true);
|
||||
|
|
@ -2170,8 +2170,8 @@ isc_nm_listenhttp(isc_nm_t *mgr, isc_nmiface_t *iface, int backlog,
|
|||
isc__nmsocket_attach(sock, &sock->outer->h2.httpserver);
|
||||
|
||||
sock->nchildren = sock->outer->nchildren;
|
||||
sock->result = ISC_R_DEFAULT;
|
||||
sock->tid = isc_random_uniform(sock->nchildren);
|
||||
sock->result = ISC_R_UNSET;
|
||||
sock->tid = 0;
|
||||
sock->fd = (uv_os_sock_t)-1;
|
||||
|
||||
atomic_store(&sock->listening, true);
|
||||
|
|
@ -2239,8 +2239,6 @@ isc_nm_http_endpoint(isc_nmsocket_t *sock, const char *uri, isc_nm_recv_cb_t cb,
|
|||
|
||||
void
|
||||
isc__nm_http_stoplistening(isc_nmsocket_t *sock) {
|
||||
isc__netievent_httpstop_t *ievent = NULL;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->type == isc_nm_httplistener);
|
||||
|
||||
|
|
@ -2250,9 +2248,16 @@ isc__nm_http_stoplistening(isc_nmsocket_t *sock) {
|
|||
ISC_UNREACHABLE();
|
||||
}
|
||||
|
||||
ievent = isc__nm_get_netievent_httpstop(sock->mgr, sock);
|
||||
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
if (!isc__nm_in_netthread()) {
|
||||
isc__netievent_httpstop_t *ievent =
|
||||
isc__nm_get_netievent_httpstop(sock->mgr, sock);
|
||||
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
} else {
|
||||
REQUIRE(isc_nm_tid() == sock->tid);
|
||||
isc__netievent_httpstop_t ievent = { .sock = sock };
|
||||
isc__nm_async_httpstop(NULL, (isc__netievent_t *)&ievent);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -2294,7 +2299,6 @@ isc__nm_async_httpstop(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
UNUSED(worker);
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
atomic_store(&sock->listening, false);
|
||||
atomic_store(&sock->closing, false);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include <isc/astack.h>
|
||||
#include <isc/atomic.h>
|
||||
#include <isc/barrier.h>
|
||||
#include <isc/buffer.h>
|
||||
#include <isc/condition.h>
|
||||
#include <isc/magic.h>
|
||||
|
|
@ -39,6 +40,8 @@
|
|||
|
||||
#include "uv-compat.h"
|
||||
|
||||
#define ISC_NETMGR_QUANTUM_DEFAULT 128
|
||||
|
||||
#define ISC_NETMGR_TID_UNKNOWN -1
|
||||
|
||||
/* Must be different from ISC_NETMGR_TID_UNKNOWN */
|
||||
|
|
@ -172,7 +175,6 @@ typedef struct isc__networker {
|
|||
uv_async_t async; /* async channel to send
|
||||
* data to this networker */
|
||||
isc_mutex_t lock;
|
||||
isc_condition_t cond;
|
||||
bool paused;
|
||||
bool finished;
|
||||
isc_thread_t thread;
|
||||
|
|
@ -183,11 +185,14 @@ typedef struct isc__networker {
|
|||
* used for listening etc.
|
||||
* can be processed while
|
||||
* worker is paused */
|
||||
isc_condition_t cond_prio;
|
||||
|
||||
isc_refcount_t references;
|
||||
atomic_int_fast64_t pktcount;
|
||||
char *recvbuf;
|
||||
char *sendbuf;
|
||||
bool recvbuf_inuse;
|
||||
unsigned int quantum;
|
||||
} isc__networker_t;
|
||||
|
||||
/*
|
||||
|
|
@ -244,7 +249,6 @@ typedef enum isc__netievent_type {
|
|||
netievent_udpclose,
|
||||
netievent_udpsend,
|
||||
netievent_udpread,
|
||||
netievent_udpstop,
|
||||
netievent_udpcancel,
|
||||
|
||||
netievent_tcpconnect,
|
||||
|
|
@ -253,7 +257,6 @@ typedef enum isc__netievent_type {
|
|||
netievent_tcpstartread,
|
||||
netievent_tcppauseread,
|
||||
netievent_tcpaccept,
|
||||
netievent_tcpstop,
|
||||
netievent_tcpcancel,
|
||||
|
||||
netievent_tcpdnsaccept,
|
||||
|
|
@ -262,7 +265,6 @@ typedef enum isc__netievent_type {
|
|||
netievent_tcpdnssend,
|
||||
netievent_tcpdnsread,
|
||||
netievent_tcpdnscancel,
|
||||
netievent_tcpdnsstop,
|
||||
|
||||
netievent_tlsclose,
|
||||
netievent_tlssend,
|
||||
|
|
@ -277,12 +279,10 @@ typedef enum isc__netievent_type {
|
|||
netievent_tlsdnssend,
|
||||
netievent_tlsdnsread,
|
||||
netievent_tlsdnscancel,
|
||||
netievent_tlsdnsstop,
|
||||
netievent_tlsdnscycle,
|
||||
netievent_tlsdnsshutdown,
|
||||
|
||||
netievent_httpclose,
|
||||
netievent_httpstop,
|
||||
netievent_httpsend,
|
||||
|
||||
netievent_shutdown,
|
||||
|
|
@ -296,19 +296,26 @@ typedef enum isc__netievent_type {
|
|||
netievent_task,
|
||||
netievent_privilegedtask,
|
||||
|
||||
netievent_prio = 0xff, /* event type values higher than this
|
||||
* will be treated as high-priority
|
||||
* events, which can be processed
|
||||
* while the netmgr is paused.
|
||||
*/
|
||||
/*
|
||||
* event type values higher than this will be treated
|
||||
* as high-priority events, which can be processed
|
||||
* while the netmgr is pausing or paused.
|
||||
*/
|
||||
netievent_prio = 0xff,
|
||||
|
||||
netievent_udplisten,
|
||||
netievent_udpstop,
|
||||
netievent_tcplisten,
|
||||
netievent_tcpstop,
|
||||
netievent_tcpdnslisten,
|
||||
netievent_tcpdnsstop,
|
||||
netievent_tlsdnslisten,
|
||||
netievent_tlsdnsstop,
|
||||
netievent_httpstop,
|
||||
|
||||
netievent_resume,
|
||||
netievent_detach,
|
||||
netievent_close,
|
||||
|
||||
} isc__netievent_type;
|
||||
|
||||
typedef union {
|
||||
|
|
@ -653,7 +660,7 @@ struct isc_nm {
|
|||
int magic;
|
||||
isc_refcount_t references;
|
||||
isc_mem_t *mctx;
|
||||
uint32_t nworkers;
|
||||
int nworkers;
|
||||
isc_mutex_t lock;
|
||||
isc_condition_t wkstatecond;
|
||||
isc_condition_t wkpausecond;
|
||||
|
|
@ -668,7 +675,7 @@ struct isc_nm {
|
|||
isc_mutex_t evlock;
|
||||
|
||||
uint_fast32_t workers_running;
|
||||
uint_fast32_t workers_paused;
|
||||
atomic_uint_fast32_t workers_paused;
|
||||
atomic_uint_fast32_t maxudp;
|
||||
|
||||
atomic_bool paused;
|
||||
|
|
@ -699,6 +706,9 @@ struct isc_nm {
|
|||
atomic_uint_fast32_t keepalive;
|
||||
atomic_uint_fast32_t advertised;
|
||||
|
||||
isc_barrier_t pausing;
|
||||
isc_barrier_t resuming;
|
||||
|
||||
#ifdef NETMGR_TRACE
|
||||
ISC_LIST(isc_nmsocket_t) active_sockets;
|
||||
#endif
|
||||
|
|
@ -833,6 +843,9 @@ struct isc_nmsocket {
|
|||
/*% Self socket */
|
||||
isc_nmsocket_t *self;
|
||||
|
||||
isc_barrier_t startlistening;
|
||||
isc_barrier_t stoplistening;
|
||||
|
||||
/*% TLS stuff */
|
||||
struct tls {
|
||||
isc_tls_t *tls;
|
||||
|
|
@ -927,7 +940,7 @@ struct isc_nmsocket {
|
|||
|
||||
/* Atomic */
|
||||
/*% Number of running (e.g. listening) child sockets */
|
||||
uint_fast32_t rchildren;
|
||||
atomic_uint_fast32_t rchildren;
|
||||
|
||||
/*%
|
||||
* Socket is active if it's listening, working, etc. If it's
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include <isc/atomic.h>
|
||||
#include <isc/backtrace.h>
|
||||
#include <isc/barrier.h>
|
||||
#include <isc/buffer.h>
|
||||
#include <isc/condition.h>
|
||||
#include <isc/errno.h>
|
||||
|
|
@ -37,6 +38,7 @@
|
|||
#include <isc/util.h>
|
||||
|
||||
#include "netmgr-int.h"
|
||||
#include "netmgr_p.h"
|
||||
#include "openssl_shim.h"
|
||||
#include "uv-compat.h"
|
||||
|
||||
|
|
@ -134,15 +136,29 @@ nm_thread(isc_threadarg_t worker0);
|
|||
static void
|
||||
async_cb(uv_async_t *handle);
|
||||
static bool
|
||||
process_queue(isc__networker_t *worker, isc_queue_t *queue);
|
||||
process_netievent(isc__networker_t *worker, isc__netievent_t *ievent);
|
||||
static bool
|
||||
process_priority_queue(isc__networker_t *worker);
|
||||
process_queue(isc__networker_t *worker, isc_queue_t *queue,
|
||||
unsigned int *quantump);
|
||||
static void
|
||||
process_privilege_queue(isc__networker_t *worker);
|
||||
static void
|
||||
process_tasks_queue(isc__networker_t *worker);
|
||||
static void
|
||||
process_normal_queue(isc__networker_t *worker);
|
||||
wait_for_priority_queue(isc__networker_t *worker);
|
||||
static bool
|
||||
process_priority_queue(isc__networker_t *worker, unsigned int *quantump);
|
||||
static bool
|
||||
process_privilege_queue(isc__networker_t *worker, unsigned int *quantump);
|
||||
static bool
|
||||
process_task_queue(isc__networker_t *worker, unsigned int *quantump);
|
||||
static bool
|
||||
process_normal_queue(isc__networker_t *worker, unsigned int *quantump);
|
||||
|
||||
#define drain_priority_queue(worker) \
|
||||
(void)process_priority_queue(worker, &(unsigned int){ UINT_MAX })
|
||||
#define drain_privilege_queue(worker) \
|
||||
(void)process_privilege_queue(worker, &(unsigned int){ UINT_MAX })
|
||||
#define drain_task_queue(worker) \
|
||||
(void)process_task_queue(worker, &(unsigned int){ UINT_MAX })
|
||||
#define drain_normal_queue(worker) \
|
||||
(void)process_normal_queue(worker, &(unsigned int){ UINT_MAX })
|
||||
|
||||
static void
|
||||
isc__nm_async_stop(isc__networker_t *worker, isc__netievent_t *ev0);
|
||||
|
|
@ -206,8 +222,8 @@ isc__nm_winsock_destroy(void) {
|
|||
}
|
||||
#endif /* WIN32 */
|
||||
|
||||
isc_nm_t *
|
||||
isc_nm_start(isc_mem_t *mctx, uint32_t workers) {
|
||||
void
|
||||
isc__netmgr_create(isc_mem_t *mctx, uint32_t workers, isc_nm_t **netmgrp) {
|
||||
isc_nm_t *mgr = NULL;
|
||||
char name[32];
|
||||
|
||||
|
|
@ -227,6 +243,7 @@ isc_nm_start(isc_mem_t *mctx, uint32_t workers) {
|
|||
isc_refcount_init(&mgr->references, 1);
|
||||
atomic_init(&mgr->maxudp, 0);
|
||||
atomic_init(&mgr->interlocked, ISC_NETMGR_NON_INTERLOCKED);
|
||||
atomic_init(&mgr->workers_paused, 0);
|
||||
|
||||
#ifdef NETMGR_TRACE
|
||||
ISC_LIST_INIT(mgr->active_sockets);
|
||||
|
|
@ -256,6 +273,9 @@ isc_nm_start(isc_mem_t *mctx, uint32_t workers) {
|
|||
isc_mempool_associatelock(mgr->evpool, &mgr->evlock);
|
||||
isc_mempool_setfillcount(mgr->evpool, 32);
|
||||
|
||||
isc_barrier_init(&mgr->pausing, workers);
|
||||
isc_barrier_init(&mgr->resuming, workers);
|
||||
|
||||
mgr->workers = isc_mem_get(mctx, workers * sizeof(isc__networker_t));
|
||||
for (size_t i = 0; i < workers; i++) {
|
||||
int r;
|
||||
|
|
@ -263,6 +283,7 @@ isc_nm_start(isc_mem_t *mctx, uint32_t workers) {
|
|||
*worker = (isc__networker_t){
|
||||
.mgr = mgr,
|
||||
.id = i,
|
||||
.quantum = ISC_NETMGR_QUANTUM_DEFAULT,
|
||||
};
|
||||
|
||||
r = uv_loop_init(&worker->loop);
|
||||
|
|
@ -274,12 +295,13 @@ isc_nm_start(isc_mem_t *mctx, uint32_t workers) {
|
|||
RUNTIME_CHECK(r == 0);
|
||||
|
||||
isc_mutex_init(&worker->lock);
|
||||
isc_condition_init(&worker->cond);
|
||||
|
||||
worker->ievents = isc_queue_new(mgr->mctx, 128);
|
||||
worker->ievents_priv = isc_queue_new(mgr->mctx, 128);
|
||||
worker->ievents_task = isc_queue_new(mgr->mctx, 128);
|
||||
worker->ievents_priv = isc_queue_new(mgr->mctx, 128);
|
||||
worker->ievents_prio = isc_queue_new(mgr->mctx, 128);
|
||||
isc_condition_init(&worker->cond_prio);
|
||||
|
||||
worker->recvbuf = isc_mem_get(mctx, ISC_NETMGR_RECVBUF_SIZE);
|
||||
worker->sendbuf = isc_mem_get(mctx, ISC_NETMGR_SENDBUF_SIZE);
|
||||
|
||||
|
|
@ -296,7 +318,7 @@ isc_nm_start(isc_mem_t *mctx, uint32_t workers) {
|
|||
}
|
||||
|
||||
mgr->magic = NM_MAGIC;
|
||||
return (mgr);
|
||||
*netmgrp = mgr;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -314,7 +336,7 @@ nm_destroy(isc_nm_t **mgr0) {
|
|||
|
||||
mgr->magic = 0;
|
||||
|
||||
for (size_t i = 0; i < mgr->nworkers; i++) {
|
||||
for (int i = 0; i < mgr->nworkers; i++) {
|
||||
isc__networker_t *worker = &mgr->workers[i];
|
||||
isc__netievent_t *event = isc__nm_get_netievent_stop(mgr);
|
||||
isc__nm_enqueue_ievent(worker, event);
|
||||
|
|
@ -326,7 +348,7 @@ nm_destroy(isc_nm_t **mgr0) {
|
|||
}
|
||||
UNLOCK(&mgr->lock);
|
||||
|
||||
for (size_t i = 0; i < mgr->nworkers; i++) {
|
||||
for (int i = 0; i < mgr->nworkers; i++) {
|
||||
isc__networker_t *worker = &mgr->workers[i];
|
||||
isc__netievent_t *ievent = NULL;
|
||||
int r;
|
||||
|
|
@ -348,6 +370,7 @@ nm_destroy(isc_nm_t **mgr0) {
|
|||
{
|
||||
isc_mempool_put(mgr->evpool, ievent);
|
||||
}
|
||||
isc_condition_destroy(&worker->cond_prio);
|
||||
|
||||
r = uv_loop_close(&worker->loop);
|
||||
INSIST(r == 0);
|
||||
|
|
@ -357,7 +380,6 @@ nm_destroy(isc_nm_t **mgr0) {
|
|||
isc_queue_destroy(worker->ievents_task);
|
||||
isc_queue_destroy(worker->ievents_prio);
|
||||
isc_mutex_destroy(&worker->lock);
|
||||
isc_condition_destroy(&worker->cond);
|
||||
|
||||
isc_mem_put(mgr->mctx, worker->sendbuf,
|
||||
ISC_NETMGR_SENDBUF_SIZE);
|
||||
|
|
@ -370,6 +392,9 @@ nm_destroy(isc_nm_t **mgr0) {
|
|||
isc_stats_detach(&mgr->stats);
|
||||
}
|
||||
|
||||
isc_barrier_destroy(&mgr->resuming);
|
||||
isc_barrier_destroy(&mgr->pausing);
|
||||
|
||||
isc_condition_destroy(&mgr->wkstatecond);
|
||||
isc_condition_destroy(&mgr->wkpausecond);
|
||||
isc_mutex_destroy(&mgr->lock);
|
||||
|
|
@ -389,34 +414,70 @@ nm_destroy(isc_nm_t **mgr0) {
|
|||
#endif /* WIN32 */
|
||||
}
|
||||
|
||||
static void
|
||||
enqueue_pause(isc__networker_t *worker) {
|
||||
isc__netievent_pause_t *event =
|
||||
isc__nm_get_netievent_pause(worker->mgr);
|
||||
isc__nm_enqueue_ievent(worker, (isc__netievent_t *)event);
|
||||
}
|
||||
|
||||
static void
|
||||
isc__nm_async_pause(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
UNUSED(ev0);
|
||||
REQUIRE(worker->paused == false);
|
||||
|
||||
worker->paused = true;
|
||||
uv_stop(&worker->loop);
|
||||
}
|
||||
|
||||
void
|
||||
isc_nm_pause(isc_nm_t *mgr) {
|
||||
REQUIRE(VALID_NM(mgr));
|
||||
uint_fast32_t pausing = 0;
|
||||
REQUIRE(!atomic_load(&mgr->paused));
|
||||
|
||||
isc__nm_acquire_interlocked_force(mgr);
|
||||
|
||||
for (size_t i = 0; i < mgr->nworkers; i++) {
|
||||
if (isc__nm_in_netthread()) {
|
||||
REQUIRE(isc_nm_tid() == 0);
|
||||
}
|
||||
|
||||
for (int i = 0; i < mgr->nworkers; i++) {
|
||||
isc__networker_t *worker = &mgr->workers[i];
|
||||
if (i != (size_t)isc_nm_tid()) {
|
||||
isc__netievent_resume_t *event =
|
||||
isc__nm_get_netievent_pause(mgr);
|
||||
pausing++;
|
||||
isc__nm_enqueue_ievent(worker,
|
||||
(isc__netievent_t *)event);
|
||||
} else {
|
||||
if (i == isc_nm_tid()) {
|
||||
isc__nm_async_pause(worker, NULL);
|
||||
} else {
|
||||
enqueue_pause(worker);
|
||||
}
|
||||
}
|
||||
|
||||
if (isc__nm_in_netthread()) {
|
||||
atomic_fetch_add(&mgr->workers_paused, 1);
|
||||
isc_barrier_wait(&mgr->pausing);
|
||||
}
|
||||
|
||||
LOCK(&mgr->lock);
|
||||
while (mgr->workers_paused != pausing) {
|
||||
while (atomic_load(&mgr->workers_paused) != mgr->workers_running) {
|
||||
WAIT(&mgr->wkstatecond, &mgr->lock);
|
||||
}
|
||||
UNLOCK(&mgr->lock);
|
||||
|
||||
REQUIRE(atomic_compare_exchange_strong(&mgr->paused, &(bool){ false },
|
||||
true));
|
||||
UNLOCK(&mgr->lock);
|
||||
}
|
||||
|
||||
static void
|
||||
enqueue_resume(isc__networker_t *worker) {
|
||||
isc__netievent_resume_t *event =
|
||||
isc__nm_get_netievent_resume(worker->mgr);
|
||||
isc__nm_enqueue_ievent(worker, (isc__netievent_t *)event);
|
||||
}
|
||||
|
||||
static void
|
||||
isc__nm_async_resume(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
UNUSED(ev0);
|
||||
REQUIRE(worker->paused == true);
|
||||
|
||||
worker->paused = false;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -424,26 +485,36 @@ isc_nm_resume(isc_nm_t *mgr) {
|
|||
REQUIRE(VALID_NM(mgr));
|
||||
REQUIRE(atomic_load(&mgr->paused));
|
||||
|
||||
for (size_t i = 0; i < mgr->nworkers; i++) {
|
||||
if (isc__nm_in_netthread()) {
|
||||
REQUIRE(isc_nm_tid() == 0);
|
||||
drain_priority_queue(&mgr->workers[isc_nm_tid()]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < mgr->nworkers; i++) {
|
||||
isc__networker_t *worker = &mgr->workers[i];
|
||||
if (i != (size_t)isc_nm_tid()) {
|
||||
isc__netievent_resume_t *event =
|
||||
isc__nm_get_netievent_resume(mgr);
|
||||
isc__nm_enqueue_ievent(worker,
|
||||
(isc__netievent_t *)event);
|
||||
} else {
|
||||
if (i == isc_nm_tid()) {
|
||||
isc__nm_async_resume(worker, NULL);
|
||||
} else {
|
||||
enqueue_resume(worker);
|
||||
}
|
||||
}
|
||||
|
||||
if (isc__nm_in_netthread()) {
|
||||
drain_privilege_queue(&mgr->workers[isc_nm_tid()]);
|
||||
|
||||
atomic_fetch_sub(&mgr->workers_paused, 1);
|
||||
isc_barrier_wait(&mgr->resuming);
|
||||
}
|
||||
|
||||
LOCK(&mgr->lock);
|
||||
while (mgr->workers_paused != 0) {
|
||||
while (atomic_load(&mgr->workers_paused) != 0) {
|
||||
WAIT(&mgr->wkstatecond, &mgr->lock);
|
||||
}
|
||||
UNLOCK(&mgr->lock);
|
||||
|
||||
REQUIRE(atomic_compare_exchange_strong(&mgr->paused, &(bool){ true },
|
||||
false));
|
||||
BROADCAST(&mgr->wkpausecond);
|
||||
UNLOCK(&mgr->lock);
|
||||
|
||||
isc__nm_drop_interlocked(mgr);
|
||||
}
|
||||
|
||||
|
|
@ -473,11 +544,11 @@ isc_nm_detach(isc_nm_t **mgr0) {
|
|||
}
|
||||
|
||||
void
|
||||
isc_nm_closedown(isc_nm_t *mgr) {
|
||||
isc__netmgr_shutdown(isc_nm_t *mgr) {
|
||||
REQUIRE(VALID_NM(mgr));
|
||||
|
||||
atomic_store(&mgr->closing, true);
|
||||
for (size_t i = 0; i < mgr->nworkers; i++) {
|
||||
for (int i = 0; i < mgr->nworkers; i++) {
|
||||
isc__netievent_t *event = NULL;
|
||||
event = isc__nm_get_netievent_shutdown(mgr);
|
||||
isc__nm_enqueue_ievent(&mgr->workers[i], event);
|
||||
|
|
@ -485,19 +556,18 @@ isc_nm_closedown(isc_nm_t *mgr) {
|
|||
}
|
||||
|
||||
void
|
||||
isc_nm_destroy(isc_nm_t **mgr0) {
|
||||
isc__netmgr_destroy(isc_nm_t **netmgrp) {
|
||||
isc_nm_t *mgr = NULL;
|
||||
int counter = 0;
|
||||
|
||||
REQUIRE(mgr0 != NULL);
|
||||
REQUIRE(VALID_NM(*mgr0));
|
||||
REQUIRE(VALID_NM(*netmgrp));
|
||||
|
||||
mgr = *mgr0;
|
||||
mgr = *netmgrp;
|
||||
|
||||
/*
|
||||
* Close active connections.
|
||||
*/
|
||||
isc_nm_closedown(mgr);
|
||||
isc__netmgr_shutdown(mgr);
|
||||
|
||||
/*
|
||||
* Wait for the manager to be dereferenced elsewhere.
|
||||
|
|
@ -524,7 +594,7 @@ isc_nm_destroy(isc_nm_t **mgr0) {
|
|||
/*
|
||||
* Detach final reference.
|
||||
*/
|
||||
isc_nm_detach(mgr0);
|
||||
isc_nm_detach(netmgrp);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -615,43 +685,29 @@ nm_thread(isc_threadarg_t worker0) {
|
|||
if (worker->paused) {
|
||||
INSIST(atomic_load(&mgr->interlocked) != isc_nm_tid());
|
||||
|
||||
/*
|
||||
* We need to lock the worker first; otherwise
|
||||
* isc_nm_resume() might slip in before WAIT() in
|
||||
* the while loop starts, then the signal never
|
||||
* gets delivered and we are stuck forever in the
|
||||
* paused loop.
|
||||
*/
|
||||
LOCK(&worker->lock);
|
||||
LOCK(&mgr->lock);
|
||||
mgr->workers_paused++;
|
||||
SIGNAL(&mgr->wkstatecond);
|
||||
UNLOCK(&mgr->lock);
|
||||
atomic_fetch_add(&mgr->workers_paused, 1);
|
||||
if (isc_barrier_wait(&mgr->pausing) != 0) {
|
||||
LOCK(&mgr->lock);
|
||||
SIGNAL(&mgr->wkstatecond);
|
||||
UNLOCK(&mgr->lock);
|
||||
}
|
||||
|
||||
while (worker->paused) {
|
||||
WAIT(&worker->cond, &worker->lock);
|
||||
UNLOCK(&worker->lock);
|
||||
(void)process_priority_queue(worker);
|
||||
LOCK(&worker->lock);
|
||||
wait_for_priority_queue(worker);
|
||||
}
|
||||
|
||||
LOCK(&mgr->lock);
|
||||
mgr->workers_paused--;
|
||||
SIGNAL(&mgr->wkstatecond);
|
||||
UNLOCK(&mgr->lock);
|
||||
UNLOCK(&worker->lock);
|
||||
|
||||
/*
|
||||
* All workers must run the privileged event
|
||||
* All workers must drain the privileged event
|
||||
* queue before we resume from pause.
|
||||
*/
|
||||
process_privilege_queue(worker);
|
||||
drain_privilege_queue(worker);
|
||||
|
||||
LOCK(&mgr->lock);
|
||||
while (atomic_load(&mgr->paused)) {
|
||||
WAIT(&mgr->wkpausecond, &mgr->lock);
|
||||
atomic_fetch_sub(&mgr->workers_paused, 1);
|
||||
if (isc_barrier_wait(&mgr->resuming) != 0) {
|
||||
LOCK(&mgr->lock);
|
||||
SIGNAL(&mgr->wkstatecond);
|
||||
UNLOCK(&mgr->lock);
|
||||
}
|
||||
UNLOCK(&mgr->lock);
|
||||
}
|
||||
|
||||
if (r == 0) {
|
||||
|
|
@ -660,16 +716,6 @@ nm_thread(isc_threadarg_t worker0) {
|
|||
}
|
||||
|
||||
INSIST(!worker->finished);
|
||||
|
||||
/*
|
||||
* We've fully resumed from pause. Drain the normal
|
||||
* asynchronous event queues before resuming the uv_run()
|
||||
* loop. (This is not strictly necessary, it just ensures
|
||||
* that all pending events are processed before another
|
||||
* pause can slip in.)
|
||||
*/
|
||||
process_tasks_queue(worker);
|
||||
process_normal_queue(worker);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -677,8 +723,8 @@ nm_thread(isc_threadarg_t worker0) {
|
|||
* (they may include shutdown events) but do not process
|
||||
* the netmgr event queue.
|
||||
*/
|
||||
process_privilege_queue(worker);
|
||||
process_tasks_queue(worker);
|
||||
drain_privilege_queue(worker);
|
||||
drain_task_queue(worker);
|
||||
|
||||
LOCK(&mgr->lock);
|
||||
mgr->workers_running--;
|
||||
|
|
@ -688,6 +734,23 @@ nm_thread(isc_threadarg_t worker0) {
|
|||
return ((isc_threadresult_t)0);
|
||||
}
|
||||
|
||||
static bool
|
||||
process_all_queues(isc__networker_t *worker, unsigned int quantum) {
|
||||
/*
|
||||
* The queue processing functions will return false when the
|
||||
* system is pausing or stopping, or if we have completed
|
||||
* 'quantum' events.
|
||||
*
|
||||
* We don't want to proceed to a new queue until the previous one
|
||||
* has been fully drained, so whenever one queue is interrupted,
|
||||
* we skip all the later ones.
|
||||
*/
|
||||
return (process_priority_queue(worker, &quantum) &&
|
||||
process_privilege_queue(worker, &quantum) &&
|
||||
process_task_queue(worker, &quantum) &&
|
||||
process_normal_queue(worker, &quantum));
|
||||
}
|
||||
|
||||
/*
|
||||
* async_cb() is a universal callback for 'async' events sent to event loop.
|
||||
* It's the only way to safely pass data to the libuv event loop. We use a
|
||||
|
|
@ -697,18 +760,14 @@ nm_thread(isc_threadarg_t worker0) {
|
|||
static void
|
||||
async_cb(uv_async_t *handle) {
|
||||
isc__networker_t *worker = (isc__networker_t *)handle->loop->data;
|
||||
unsigned int quantum = worker->quantum;
|
||||
|
||||
/*
|
||||
* process_priority_queue() returns false when pausing or stopping,
|
||||
* so we don't want to process the other queues in that case.
|
||||
*/
|
||||
if (!process_priority_queue(worker)) {
|
||||
return;
|
||||
if (!process_all_queues(worker, quantum)) {
|
||||
/* If we didn't process all the events, we need to enqueue
|
||||
* async_cb to be run in the next iteration of the uv_loop
|
||||
*/
|
||||
uv_async_send(handle);
|
||||
}
|
||||
|
||||
process_privilege_queue(worker);
|
||||
process_tasks_queue(worker);
|
||||
process_normal_queue(worker);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -719,23 +778,6 @@ isc__nm_async_stop(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
uv_close((uv_handle_t *)&worker->async, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
isc__nm_async_pause(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
UNUSED(ev0);
|
||||
REQUIRE(worker->paused == false);
|
||||
|
||||
worker->paused = true;
|
||||
uv_stop(&worker->loop);
|
||||
}
|
||||
|
||||
static void
|
||||
isc__nm_async_resume(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
UNUSED(ev0);
|
||||
REQUIRE(worker->paused == true);
|
||||
|
||||
worker->paused = false;
|
||||
}
|
||||
|
||||
void
|
||||
isc_nm_task_enqueue(isc_nm_t *nm, isc_task_t *task, int threadid) {
|
||||
isc__netievent_t *event = NULL;
|
||||
|
|
@ -750,7 +792,7 @@ isc_nm_task_enqueue(isc_nm_t *nm, isc_task_t *task, int threadid) {
|
|||
|
||||
worker = &nm->workers[tid];
|
||||
|
||||
if (isc_task_privilege(task)) {
|
||||
if (isc_task_privileged(task)) {
|
||||
event = (isc__netievent_t *)
|
||||
isc__nm_get_netievent_privilegedtask(nm, task);
|
||||
} else {
|
||||
|
|
@ -775,8 +817,7 @@ isc__nm_async_task(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
|
||||
switch (result) {
|
||||
case ISC_R_QUOTA:
|
||||
isc_nm_task_enqueue(worker->mgr, (isc_task_t *)ievent->task,
|
||||
isc_nm_tid());
|
||||
isc_task_ready(ievent->task);
|
||||
return;
|
||||
case ISC_R_SUCCESS:
|
||||
return;
|
||||
|
|
@ -786,24 +827,52 @@ isc__nm_async_task(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wait_for_priority_queue(isc__networker_t *worker) {
|
||||
isc_queue_t *queue = worker->ievents_prio;
|
||||
isc_condition_t *cond = &worker->cond_prio;
|
||||
bool wait_for_work = true;
|
||||
|
||||
while (true) {
|
||||
isc__netievent_t *ievent;
|
||||
LOCK(&worker->lock);
|
||||
ievent = (isc__netievent_t *)isc_queue_dequeue(queue);
|
||||
if (wait_for_work) {
|
||||
while (ievent == NULL) {
|
||||
WAIT(cond, &worker->lock);
|
||||
ievent = (isc__netievent_t *)isc_queue_dequeue(
|
||||
queue);
|
||||
}
|
||||
}
|
||||
UNLOCK(&worker->lock);
|
||||
wait_for_work = false;
|
||||
|
||||
if (ievent == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
(void)process_netievent(worker, ievent);
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
process_priority_queue(isc__networker_t *worker) {
|
||||
return (process_queue(worker, worker->ievents_prio));
|
||||
process_priority_queue(isc__networker_t *worker, unsigned int *quantump) {
|
||||
return (process_queue(worker, worker->ievents_prio, quantump));
|
||||
}
|
||||
|
||||
static void
|
||||
process_privilege_queue(isc__networker_t *worker) {
|
||||
(void)process_queue(worker, worker->ievents_priv);
|
||||
static bool
|
||||
process_privilege_queue(isc__networker_t *worker, unsigned int *quantump) {
|
||||
return (process_queue(worker, worker->ievents_priv, quantump));
|
||||
}
|
||||
|
||||
static void
|
||||
process_tasks_queue(isc__networker_t *worker) {
|
||||
(void)process_queue(worker, worker->ievents_task);
|
||||
static bool
|
||||
process_task_queue(isc__networker_t *worker, unsigned int *quantump) {
|
||||
return (process_queue(worker, worker->ievents_task, quantump));
|
||||
}
|
||||
|
||||
static void
|
||||
process_normal_queue(isc__networker_t *worker) {
|
||||
(void)process_queue(worker, worker->ievents);
|
||||
static bool
|
||||
process_normal_queue(isc__networker_t *worker, unsigned int *quantump) {
|
||||
return (process_queue(worker, worker->ievents, quantump));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -905,16 +974,27 @@ process_netievent(isc__networker_t *worker, isc__netievent_t *ievent) {
|
|||
}
|
||||
|
||||
static bool
|
||||
process_queue(isc__networker_t *worker, isc_queue_t *queue) {
|
||||
isc__netievent_t *ievent = NULL;
|
||||
process_queue(isc__networker_t *worker, isc_queue_t *queue,
|
||||
unsigned int *quantump) {
|
||||
while (*quantump > 0) {
|
||||
isc__netievent_t *ievent =
|
||||
(isc__netievent_t *)isc_queue_dequeue(queue);
|
||||
|
||||
if (ievent == NULL) {
|
||||
/* We fully drained this queue */
|
||||
return (true);
|
||||
}
|
||||
|
||||
(*quantump)--;
|
||||
|
||||
while ((ievent = (isc__netievent_t *)isc_queue_dequeue(queue)) != NULL)
|
||||
{
|
||||
if (!process_netievent(worker, ievent)) {
|
||||
/* Netievent told us to stop */
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
return (true);
|
||||
|
||||
/* No more quantum */
|
||||
return (false);
|
||||
}
|
||||
|
||||
void *
|
||||
|
|
@ -1017,7 +1097,7 @@ isc__nm_enqueue_ievent(isc__networker_t *worker, isc__netievent_t *event) {
|
|||
*/
|
||||
LOCK(&worker->lock);
|
||||
isc_queue_enqueue(worker->ievents_prio, (uintptr_t)event);
|
||||
SIGNAL(&worker->cond);
|
||||
SIGNAL(&worker->cond_prio);
|
||||
UNLOCK(&worker->lock);
|
||||
} else if (event->type == netievent_privilegedtask) {
|
||||
isc_queue_enqueue(worker->ievents_priv, (uintptr_t)event);
|
||||
|
|
@ -1105,7 +1185,14 @@ nmsocket_cleanup(isc_nmsocket_t *sock, bool dofree FLARG) {
|
|||
}
|
||||
|
||||
/*
|
||||
* This was a parent socket; free the children.
|
||||
* This was a parent socket: destroy the listening
|
||||
* barriers that synchronized the children.
|
||||
*/
|
||||
isc_barrier_destroy(&sock->startlistening);
|
||||
isc_barrier_destroy(&sock->stoplistening);
|
||||
|
||||
/*
|
||||
* Now free them.
|
||||
*/
|
||||
isc_mem_put(sock->mgr->mctx, sock->children,
|
||||
sock->nchildren * sizeof(*sock));
|
||||
|
|
@ -1152,7 +1239,6 @@ nmsocket_cleanup(isc_nmsocket_t *sock, bool dofree FLARG) {
|
|||
isc_mem_free(sock->mgr->mctx, sock->ah_frees);
|
||||
isc_mem_free(sock->mgr->mctx, sock->ah_handles);
|
||||
isc_mutex_destroy(&sock->lock);
|
||||
isc_condition_destroy(&sock->cond);
|
||||
isc_condition_destroy(&sock->scond);
|
||||
isc__nm_tls_cleanup_data(sock);
|
||||
isc__nm_http_cleanup_data(sock);
|
||||
|
|
@ -1399,7 +1485,6 @@ isc___nmsocket_init(isc_nmsocket_t *sock, isc_nm_t *mgr, isc_nmsocket_type type,
|
|||
}
|
||||
|
||||
isc_mutex_init(&sock->lock);
|
||||
isc_condition_init(&sock->cond);
|
||||
isc_condition_init(&sock->scond);
|
||||
isc_refcount_init(&sock->references, 1);
|
||||
|
||||
|
|
@ -2690,16 +2775,25 @@ isc__nm_async_shutdown(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
|
||||
bool
|
||||
isc__nm_acquire_interlocked(isc_nm_t *mgr) {
|
||||
if (!isc__nm_in_netthread()) {
|
||||
return (false);
|
||||
}
|
||||
|
||||
LOCK(&mgr->lock);
|
||||
bool success = atomic_compare_exchange_strong(
|
||||
&mgr->interlocked, &(int){ ISC_NETMGR_NON_INTERLOCKED },
|
||||
isc_nm_tid());
|
||||
|
||||
UNLOCK(&mgr->lock);
|
||||
return (success);
|
||||
}
|
||||
|
||||
void
|
||||
isc__nm_drop_interlocked(isc_nm_t *mgr) {
|
||||
if (!isc__nm_in_netthread()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOCK(&mgr->lock);
|
||||
int tid = atomic_exchange(&mgr->interlocked,
|
||||
ISC_NETMGR_NON_INTERLOCKED);
|
||||
|
|
@ -2710,6 +2804,10 @@ isc__nm_drop_interlocked(isc_nm_t *mgr) {
|
|||
|
||||
void
|
||||
isc__nm_acquire_interlocked_force(isc_nm_t *mgr) {
|
||||
if (!isc__nm_in_netthread()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOCK(&mgr->lock);
|
||||
while (!atomic_compare_exchange_strong(
|
||||
&mgr->interlocked, &(int){ ISC_NETMGR_NON_INTERLOCKED },
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include <uv.h>
|
||||
|
||||
#include <isc/atomic.h>
|
||||
#include <isc/barrier.h>
|
||||
#include <isc/buffer.h>
|
||||
#include <isc/condition.h>
|
||||
#include <isc/errno.h>
|
||||
|
|
@ -116,7 +117,7 @@ failed_accept_cb(isc_nmsocket_t *sock, isc_result_t eresult) {
|
|||
static isc_result_t
|
||||
tcp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
|
||||
isc__networker_t *worker = NULL;
|
||||
isc_result_t result = ISC_R_DEFAULT;
|
||||
isc_result_t result = ISC_R_UNSET;
|
||||
int r;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
|
|
@ -302,7 +303,7 @@ isc_nm_tcpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
|
||||
sock->extrahandlesize = extrahandlesize;
|
||||
sock->connect_timeout = timeout;
|
||||
sock->result = ISC_R_DEFAULT;
|
||||
sock->result = ISC_R_UNSET;
|
||||
sock->fd = (uv_os_sock_t)-1;
|
||||
atomic_init(&sock->client, true);
|
||||
|
||||
|
|
@ -344,7 +345,7 @@ isc_nm_tcpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
(isc__netievent_t *)ievent);
|
||||
}
|
||||
LOCK(&sock->lock);
|
||||
while (sock->result == ISC_R_DEFAULT) {
|
||||
while (sock->result == ISC_R_UNSET) {
|
||||
WAIT(&sock->cond, &sock->lock);
|
||||
}
|
||||
atomic_store(&sock->active, true);
|
||||
|
|
@ -375,6 +376,47 @@ isc__nm_tcp_lb_socket(sa_family_t sa_family) {
|
|||
return (sock);
|
||||
}
|
||||
|
||||
static void
|
||||
start_tcp_child(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nmsocket_t *sock,
|
||||
uv_os_sock_t fd, int tid) {
|
||||
isc__netievent_tcplisten_t *ievent = NULL;
|
||||
isc_nmsocket_t *csock = &sock->children[tid];
|
||||
|
||||
isc__nmsocket_init(csock, mgr, isc_nm_tcpsocket, iface);
|
||||
csock->parent = sock;
|
||||
csock->accept_cb = sock->accept_cb;
|
||||
csock->accept_cbarg = sock->accept_cbarg;
|
||||
csock->extrahandlesize = sock->extrahandlesize;
|
||||
csock->backlog = sock->backlog;
|
||||
csock->tid = tid;
|
||||
/*
|
||||
* We don't attach to quota, just assign - to avoid
|
||||
* increasing quota unnecessarily.
|
||||
*/
|
||||
csock->pquota = sock->pquota;
|
||||
isc_quota_cb_init(&csock->quotacb, quota_accept_cb, csock);
|
||||
|
||||
#if HAVE_SO_REUSEPORT_LB || defined(WIN32)
|
||||
UNUSED(fd);
|
||||
csock->fd = isc__nm_tcp_lb_socket(iface->addr.type.sa.sa_family);
|
||||
#else
|
||||
csock->fd = dup(fd);
|
||||
#endif
|
||||
REQUIRE(csock->fd >= 0);
|
||||
|
||||
ievent = isc__nm_get_netievent_tcplisten(mgr, csock);
|
||||
isc__nm_maybe_enqueue_ievent(&mgr->workers[tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
}
|
||||
|
||||
static void
|
||||
enqueue_stoplistening(isc_nmsocket_t *sock) {
|
||||
isc__netievent_tcpstop_t *ievent =
|
||||
isc__nm_get_netievent_tcpstop(sock->mgr, sock);
|
||||
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface,
|
||||
isc_nm_accept_cb_t accept_cb, void *accept_cbarg,
|
||||
|
|
@ -382,18 +424,15 @@ isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface,
|
|||
isc_nmsocket_t **sockp) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
isc_nmsocket_t *sock = NULL;
|
||||
sa_family_t sa_family = iface->addr.type.sa.sa_family;
|
||||
size_t children_size = 0;
|
||||
#if !HAVE_SO_REUSEPORT_LB && !defined(WIN32)
|
||||
uv_os_sock_t fd = -1;
|
||||
#endif
|
||||
|
||||
REQUIRE(VALID_NM(mgr));
|
||||
|
||||
sock = isc_mem_get(mgr->mctx, sizeof(*sock));
|
||||
isc__nmsocket_init(sock, mgr, isc_nm_tcplistener, iface);
|
||||
|
||||
sock->rchildren = 0;
|
||||
atomic_init(&sock->rchildren, 0);
|
||||
#if defined(WIN32)
|
||||
sock->nchildren = 1;
|
||||
#else
|
||||
|
|
@ -403,42 +442,32 @@ isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface,
|
|||
sock->children = isc_mem_get(mgr->mctx, children_size);
|
||||
memset(sock->children, 0, children_size);
|
||||
|
||||
sock->result = ISC_R_DEFAULT;
|
||||
sock->tid = isc_random_uniform(sock->nchildren);
|
||||
sock->result = ISC_R_UNSET;
|
||||
|
||||
sock->accept_cb = accept_cb;
|
||||
sock->accept_cbarg = accept_cbarg;
|
||||
sock->extrahandlesize = extrahandlesize;
|
||||
sock->backlog = backlog;
|
||||
sock->pquota = quota;
|
||||
|
||||
sock->tid = 0;
|
||||
sock->fd = -1;
|
||||
|
||||
#if !HAVE_SO_REUSEPORT_LB && !defined(WIN32)
|
||||
fd = isc__nm_tcp_lb_socket(sa_family);
|
||||
fd = isc__nm_tcp_lb_socket(iface->addr.type.sa.sa_family);
|
||||
#endif
|
||||
|
||||
isc_barrier_init(&sock->startlistening, sock->nchildren);
|
||||
|
||||
for (size_t i = 0; i < sock->nchildren; i++) {
|
||||
isc__netievent_tcplisten_t *ievent = NULL;
|
||||
isc_nmsocket_t *csock = &sock->children[i];
|
||||
if ((int)i == isc_nm_tid()) {
|
||||
continue;
|
||||
}
|
||||
start_tcp_child(mgr, iface, sock, fd, i);
|
||||
}
|
||||
|
||||
isc__nmsocket_init(csock, mgr, isc_nm_tcpsocket, iface);
|
||||
csock->parent = sock;
|
||||
csock->accept_cb = accept_cb;
|
||||
csock->accept_cbarg = accept_cbarg;
|
||||
csock->extrahandlesize = extrahandlesize;
|
||||
csock->backlog = backlog;
|
||||
csock->tid = i;
|
||||
/*
|
||||
* We don't attach to quota, just assign - to avoid
|
||||
* increasing quota unnecessarily.
|
||||
*/
|
||||
csock->pquota = quota;
|
||||
isc_quota_cb_init(&csock->quotacb, quota_accept_cb, csock);
|
||||
|
||||
#if HAVE_SO_REUSEPORT_LB || defined(WIN32)
|
||||
csock->fd = isc__nm_tcp_lb_socket(sa_family);
|
||||
#else
|
||||
csock->fd = dup(fd);
|
||||
#endif
|
||||
REQUIRE(csock->fd >= 0);
|
||||
|
||||
ievent = isc__nm_get_netievent_tcplisten(mgr, csock);
|
||||
isc__nm_maybe_enqueue_ievent(&mgr->workers[i],
|
||||
(isc__netievent_t *)ievent);
|
||||
if (isc__nm_in_netthread()) {
|
||||
start_tcp_child(mgr, iface, sock, fd, isc_nm_tid());
|
||||
}
|
||||
|
||||
#if !HAVE_SO_REUSEPORT_LB && !defined(WIN32)
|
||||
|
|
@ -446,21 +475,21 @@ isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface,
|
|||
#endif
|
||||
|
||||
LOCK(&sock->lock);
|
||||
while (sock->rchildren != sock->nchildren) {
|
||||
while (atomic_load(&sock->rchildren) != sock->nchildren) {
|
||||
WAIT(&sock->cond, &sock->lock);
|
||||
}
|
||||
result = sock->result;
|
||||
atomic_store(&sock->active, true);
|
||||
BROADCAST(&sock->scond);
|
||||
UNLOCK(&sock->lock);
|
||||
INSIST(result != ISC_R_DEFAULT);
|
||||
|
||||
INSIST(result != ISC_R_UNSET);
|
||||
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
REQUIRE(sock->rchildren == sock->nchildren);
|
||||
REQUIRE(atomic_load(&sock->rchildren) == sock->nchildren);
|
||||
*sockp = sock;
|
||||
} else {
|
||||
atomic_store(&sock->active, false);
|
||||
isc__nm_tcp_stoplistening(sock);
|
||||
enqueue_stoplistening(sock);
|
||||
isc_nmsocket_close(&sock);
|
||||
}
|
||||
|
||||
|
|
@ -565,16 +594,14 @@ done:
|
|||
sock->pquota = NULL;
|
||||
}
|
||||
|
||||
sock->parent->rchildren += 1;
|
||||
if (sock->parent->result == ISC_R_DEFAULT) {
|
||||
atomic_fetch_add(&sock->parent->rchildren, 1);
|
||||
if (sock->parent->result == ISC_R_UNSET) {
|
||||
sock->parent->result = result;
|
||||
}
|
||||
SIGNAL(&sock->parent->cond);
|
||||
if (!atomic_load(&sock->parent->active)) {
|
||||
WAIT(&sock->parent->scond, &sock->parent->lock);
|
||||
}
|
||||
INSIST(atomic_load(&sock->parent->active));
|
||||
UNLOCK(&sock->parent->lock);
|
||||
|
||||
isc_barrier_wait(&sock->parent->startlistening);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -619,14 +646,6 @@ done:
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
enqueue_stoplistening(isc_nmsocket_t *sock) {
|
||||
isc__netievent_tcpstop_t *ievent =
|
||||
isc__nm_get_netievent_tcpstop(sock->mgr, sock);
|
||||
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
}
|
||||
|
||||
void
|
||||
isc__nm_tcp_stoplistening(isc_nmsocket_t *sock) {
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
|
|
@ -637,7 +656,12 @@ isc__nm_tcp_stoplistening(isc_nmsocket_t *sock) {
|
|||
INSIST(0);
|
||||
ISC_UNREACHABLE();
|
||||
}
|
||||
enqueue_stoplistening(sock);
|
||||
|
||||
if (!isc__nm_in_netthread()) {
|
||||
enqueue_stoplistening(sock);
|
||||
} else {
|
||||
stop_tcp_parent(sock);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1194,8 +1218,6 @@ timer_close_cb(uv_handle_t *handle) {
|
|||
|
||||
static void
|
||||
stop_tcp_child(isc_nmsocket_t *sock) {
|
||||
bool last_child = false;
|
||||
|
||||
REQUIRE(sock->type == isc_nm_tcpsocket);
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
|
|
@ -1206,33 +1228,42 @@ stop_tcp_child(isc_nmsocket_t *sock) {
|
|||
|
||||
tcp_close_direct(sock);
|
||||
|
||||
LOCK(&sock->parent->lock);
|
||||
sock->parent->rchildren -= 1;
|
||||
last_child = (sock->parent->rchildren == 0);
|
||||
UNLOCK(&sock->parent->lock);
|
||||
atomic_fetch_sub(&sock->parent->rchildren, 1);
|
||||
|
||||
if (last_child) {
|
||||
atomic_store(&sock->parent->closed, true);
|
||||
isc__nmsocket_prep_destroy(sock->parent);
|
||||
}
|
||||
isc_barrier_wait(&sock->parent->stoplistening);
|
||||
}
|
||||
|
||||
static void
|
||||
stop_tcp_parent(isc_nmsocket_t *sock) {
|
||||
isc_nmsocket_t *csock = NULL;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
REQUIRE(sock->type == isc_nm_tcplistener);
|
||||
|
||||
isc_barrier_init(&sock->stoplistening, sock->nchildren);
|
||||
|
||||
for (size_t i = 0; i < sock->nchildren; i++) {
|
||||
isc__netievent_tcpstop_t *ievent = NULL;
|
||||
isc_nmsocket_t *csock = &sock->children[i];
|
||||
csock = &sock->children[i];
|
||||
REQUIRE(VALID_NMSOCK(csock));
|
||||
|
||||
atomic_store(&csock->active, false);
|
||||
if ((int)i == isc_nm_tid()) {
|
||||
/*
|
||||
* We need to schedule closing the other sockets first
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
ievent = isc__nm_get_netievent_tcpstop(sock->mgr, csock);
|
||||
isc__nm_enqueue_ievent(&sock->mgr->workers[csock->tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
atomic_store(&csock->active, false);
|
||||
enqueue_stoplistening(csock);
|
||||
}
|
||||
|
||||
csock = &sock->children[isc_nm_tid()];
|
||||
atomic_store(&csock->active, false);
|
||||
stop_tcp_child(csock);
|
||||
|
||||
atomic_store(&sock->closed, true);
|
||||
isc__nmsocket_prep_destroy(sock);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include <uv.h>
|
||||
|
||||
#include <isc/atomic.h>
|
||||
#include <isc/barrier.h>
|
||||
#include <isc/buffer.h>
|
||||
#include <isc/condition.h>
|
||||
#include <isc/errno.h>
|
||||
|
|
@ -85,7 +86,7 @@ stop_tcpdns_child(isc_nmsocket_t *sock);
|
|||
static isc_result_t
|
||||
tcpdns_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
|
||||
isc__networker_t *worker = NULL;
|
||||
isc_result_t result = ISC_R_DEFAULT;
|
||||
isc_result_t result = ISC_R_UNSET;
|
||||
int r;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
|
|
@ -269,7 +270,7 @@ isc_nm_tcpdnsconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
|
||||
sock->extrahandlesize = extrahandlesize;
|
||||
sock->connect_timeout = timeout;
|
||||
sock->result = ISC_R_DEFAULT;
|
||||
sock->result = ISC_R_UNSET;
|
||||
atomic_init(&sock->client, true);
|
||||
|
||||
req = isc__nm_uvreq_get(mgr, sock);
|
||||
|
|
@ -311,7 +312,7 @@ isc_nm_tcpdnsconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
}
|
||||
|
||||
LOCK(&sock->lock);
|
||||
while (sock->result == ISC_R_DEFAULT) {
|
||||
while (sock->result == ISC_R_UNSET) {
|
||||
WAIT(&sock->cond, &sock->lock);
|
||||
}
|
||||
atomic_store(&sock->active, true);
|
||||
|
|
@ -342,6 +343,48 @@ isc__nm_tcpdns_lb_socket(sa_family_t sa_family) {
|
|||
return (sock);
|
||||
}
|
||||
|
||||
static void
|
||||
enqueue_stoplistening(isc_nmsocket_t *sock) {
|
||||
isc__netievent_tcpdnsstop_t *ievent =
|
||||
isc__nm_get_netievent_tcpdnsstop(sock->mgr, sock);
|
||||
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
}
|
||||
|
||||
static void
|
||||
start_tcpdns_child(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nmsocket_t *sock,
|
||||
uv_os_sock_t fd, int tid) {
|
||||
isc__netievent_tcpdnslisten_t *ievent = NULL;
|
||||
isc_nmsocket_t *csock = &sock->children[tid];
|
||||
|
||||
isc__nmsocket_init(csock, mgr, isc_nm_tcpdnssocket, iface);
|
||||
csock->parent = sock;
|
||||
csock->accept_cb = sock->accept_cb;
|
||||
csock->accept_cbarg = sock->accept_cbarg;
|
||||
csock->recv_cb = sock->recv_cb;
|
||||
csock->recv_cbarg = sock->recv_cbarg;
|
||||
csock->extrahandlesize = sock->extrahandlesize;
|
||||
csock->backlog = sock->backlog;
|
||||
csock->tid = tid;
|
||||
/*
|
||||
* We don't attach to quota, just assign - to avoid
|
||||
* increasing quota unnecessarily.
|
||||
*/
|
||||
csock->pquota = sock->pquota;
|
||||
isc_quota_cb_init(&csock->quotacb, quota_accept_cb, csock);
|
||||
|
||||
#if HAVE_SO_REUSEPORT_LB || defined(WIN32)
|
||||
UNUSED(fd);
|
||||
csock->fd = isc__nm_tcpdns_lb_socket(iface->addr.type.sa.sa_family);
|
||||
#else
|
||||
csock->fd = dup(fd);
|
||||
#endif
|
||||
REQUIRE(csock->fd >= 0);
|
||||
|
||||
ievent = isc__nm_get_netievent_tcpdnslisten(mgr, csock);
|
||||
isc__nm_maybe_enqueue_ievent(&mgr->workers[tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
}
|
||||
isc_result_t
|
||||
isc_nm_listentcpdns(isc_nm_t *mgr, isc_nmiface_t *iface,
|
||||
isc_nm_recv_cb_t recv_cb, void *recv_cbarg,
|
||||
|
|
@ -350,18 +393,15 @@ isc_nm_listentcpdns(isc_nm_t *mgr, isc_nmiface_t *iface,
|
|||
isc_nmsocket_t **sockp) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
isc_nmsocket_t *sock = NULL;
|
||||
sa_family_t sa_family = iface->addr.type.sa.sa_family;
|
||||
size_t children_size = 0;
|
||||
#if !HAVE_SO_REUSEPORT_LB && !defined(WIN32)
|
||||
uv_os_sock_t fd = -1;
|
||||
#endif
|
||||
|
||||
REQUIRE(VALID_NM(mgr));
|
||||
|
||||
sock = isc_mem_get(mgr->mctx, sizeof(*sock));
|
||||
isc__nmsocket_init(sock, mgr, isc_nm_tcpdnslistener, iface);
|
||||
|
||||
sock->rchildren = 0;
|
||||
atomic_init(&sock->rchildren, 0);
|
||||
#if defined(WIN32)
|
||||
sock->nchildren = 1;
|
||||
#else
|
||||
|
|
@ -371,44 +411,33 @@ isc_nm_listentcpdns(isc_nm_t *mgr, isc_nmiface_t *iface,
|
|||
sock->children = isc_mem_get(mgr->mctx, children_size);
|
||||
memset(sock->children, 0, children_size);
|
||||
|
||||
sock->result = ISC_R_DEFAULT;
|
||||
sock->tid = isc_random_uniform(sock->nchildren);
|
||||
sock->result = ISC_R_UNSET;
|
||||
sock->accept_cb = accept_cb;
|
||||
sock->accept_cbarg = accept_cbarg;
|
||||
sock->recv_cb = recv_cb;
|
||||
sock->recv_cbarg = recv_cbarg;
|
||||
sock->extrahandlesize = extrahandlesize;
|
||||
sock->backlog = backlog;
|
||||
sock->pquota = quota;
|
||||
|
||||
sock->tid = 0;
|
||||
sock->fd = -1;
|
||||
|
||||
#if !HAVE_SO_REUSEPORT_LB && !defined(WIN32)
|
||||
fd = isc__nm_tcpdns_lb_socket(sa_family);
|
||||
fd = isc__nm_tcpdns_lb_socket(iface->addr.type.sa.sa_family);
|
||||
#endif
|
||||
|
||||
isc_barrier_init(&sock->startlistening, sock->nchildren);
|
||||
|
||||
for (size_t i = 0; i < sock->nchildren; i++) {
|
||||
isc__netievent_tcpdnslisten_t *ievent = NULL;
|
||||
isc_nmsocket_t *csock = &sock->children[i];
|
||||
if ((int)i == isc_nm_tid()) {
|
||||
continue;
|
||||
}
|
||||
start_tcpdns_child(mgr, iface, sock, fd, i);
|
||||
}
|
||||
|
||||
isc__nmsocket_init(csock, mgr, isc_nm_tcpdnssocket, iface);
|
||||
csock->parent = sock;
|
||||
csock->accept_cb = accept_cb;
|
||||
csock->accept_cbarg = accept_cbarg;
|
||||
csock->recv_cb = recv_cb;
|
||||
csock->recv_cbarg = recv_cbarg;
|
||||
csock->extrahandlesize = extrahandlesize;
|
||||
csock->backlog = backlog;
|
||||
csock->tid = i;
|
||||
/*
|
||||
* We don't attach to quota, just assign - to avoid
|
||||
* increasing quota unnecessarily.
|
||||
*/
|
||||
csock->pquota = quota;
|
||||
isc_quota_cb_init(&csock->quotacb, quota_accept_cb, csock);
|
||||
|
||||
#if HAVE_SO_REUSEPORT_LB || defined(WIN32)
|
||||
csock->fd = isc__nm_tcpdns_lb_socket(sa_family);
|
||||
#else
|
||||
csock->fd = dup(fd);
|
||||
#endif
|
||||
REQUIRE(csock->fd >= 0);
|
||||
|
||||
ievent = isc__nm_get_netievent_tcpdnslisten(mgr, csock);
|
||||
isc__nm_maybe_enqueue_ievent(&mgr->workers[i],
|
||||
(isc__netievent_t *)ievent);
|
||||
if (isc__nm_in_netthread()) {
|
||||
start_tcpdns_child(mgr, iface, sock, fd, isc_nm_tid());
|
||||
}
|
||||
|
||||
#if !HAVE_SO_REUSEPORT_LB && !defined(WIN32)
|
||||
|
|
@ -416,21 +445,21 @@ isc_nm_listentcpdns(isc_nm_t *mgr, isc_nmiface_t *iface,
|
|||
#endif
|
||||
|
||||
LOCK(&sock->lock);
|
||||
while (sock->rchildren != sock->nchildren) {
|
||||
while (atomic_load(&sock->rchildren) != sock->nchildren) {
|
||||
WAIT(&sock->cond, &sock->lock);
|
||||
}
|
||||
result = sock->result;
|
||||
atomic_store(&sock->active, true);
|
||||
BROADCAST(&sock->scond);
|
||||
UNLOCK(&sock->lock);
|
||||
INSIST(result != ISC_R_DEFAULT);
|
||||
|
||||
INSIST(result != ISC_R_UNSET);
|
||||
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
REQUIRE(sock->rchildren == sock->nchildren);
|
||||
REQUIRE(atomic_load(&sock->rchildren) == sock->nchildren);
|
||||
*sockp = sock;
|
||||
} else {
|
||||
atomic_store(&sock->active, false);
|
||||
isc__nm_tcpdns_stoplistening(sock);
|
||||
enqueue_stoplistening(sock);
|
||||
isc_nmsocket_close(&sock);
|
||||
}
|
||||
|
||||
|
|
@ -446,7 +475,7 @@ isc__nm_async_tcpdnslisten(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
int r;
|
||||
int flags = 0;
|
||||
isc_nmsocket_t *sock = NULL;
|
||||
isc_result_t result = ISC_R_DEFAULT;
|
||||
isc_result_t result = ISC_R_UNSET;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(ievent->sock));
|
||||
REQUIRE(ievent->sock->tid == isc_nm_tid());
|
||||
|
|
@ -534,16 +563,14 @@ done:
|
|||
sock->pquota = NULL;
|
||||
}
|
||||
|
||||
sock->parent->rchildren += 1;
|
||||
if (sock->parent->result == ISC_R_DEFAULT) {
|
||||
atomic_fetch_add(&sock->parent->rchildren, 1);
|
||||
if (sock->parent->result == ISC_R_UNSET) {
|
||||
sock->parent->result = result;
|
||||
}
|
||||
SIGNAL(&sock->parent->cond);
|
||||
if (!atomic_load(&sock->parent->active)) {
|
||||
WAIT(&sock->parent->scond, &sock->parent->lock);
|
||||
}
|
||||
INSIST(atomic_load(&sock->parent->active));
|
||||
UNLOCK(&sock->parent->lock);
|
||||
|
||||
isc_barrier_wait(&sock->parent->startlistening);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -589,14 +616,6 @@ done:
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
enqueue_stoplistening(isc_nmsocket_t *sock) {
|
||||
isc__netievent_tcpdnsstop_t *ievent =
|
||||
isc__nm_get_netievent_tcpdnsstop(sock->mgr, sock);
|
||||
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
}
|
||||
|
||||
void
|
||||
isc__nm_tcpdns_stoplistening(isc_nmsocket_t *sock) {
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
|
|
@ -607,7 +626,12 @@ isc__nm_tcpdns_stoplistening(isc_nmsocket_t *sock) {
|
|||
INSIST(0);
|
||||
ISC_UNREACHABLE();
|
||||
}
|
||||
enqueue_stoplistening(sock);
|
||||
|
||||
if (!isc__nm_in_netthread()) {
|
||||
enqueue_stoplistening(sock);
|
||||
} else {
|
||||
stop_tcpdns_parent(sock);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1224,8 +1248,6 @@ timer_close_cb(uv_handle_t *timer) {
|
|||
|
||||
static void
|
||||
stop_tcpdns_child(isc_nmsocket_t *sock) {
|
||||
bool last_child = false;
|
||||
|
||||
REQUIRE(sock->type == isc_nm_tcpdnssocket);
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
|
|
@ -1236,33 +1258,42 @@ stop_tcpdns_child(isc_nmsocket_t *sock) {
|
|||
|
||||
tcpdns_close_direct(sock);
|
||||
|
||||
LOCK(&sock->parent->lock);
|
||||
sock->parent->rchildren -= 1;
|
||||
last_child = (sock->parent->rchildren == 0);
|
||||
UNLOCK(&sock->parent->lock);
|
||||
atomic_fetch_sub(&sock->parent->rchildren, 1);
|
||||
|
||||
if (last_child) {
|
||||
atomic_store(&sock->parent->closed, true);
|
||||
isc__nmsocket_prep_destroy(sock->parent);
|
||||
}
|
||||
isc_barrier_wait(&sock->parent->stoplistening);
|
||||
}
|
||||
|
||||
static void
|
||||
stop_tcpdns_parent(isc_nmsocket_t *sock) {
|
||||
isc_nmsocket_t *csock = NULL;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
REQUIRE(sock->type == isc_nm_tcpdnslistener);
|
||||
|
||||
isc_barrier_init(&sock->stoplistening, sock->nchildren);
|
||||
|
||||
for (size_t i = 0; i < sock->nchildren; i++) {
|
||||
isc__netievent_tcpdnsstop_t *ievent = NULL;
|
||||
isc_nmsocket_t *csock = &sock->children[i];
|
||||
csock = &sock->children[i];
|
||||
REQUIRE(VALID_NMSOCK(csock));
|
||||
|
||||
atomic_store(&csock->active, false);
|
||||
if ((int)i == isc_nm_tid()) {
|
||||
/*
|
||||
* We need to schedule closing the other sockets first
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
ievent = isc__nm_get_netievent_tcpdnsstop(sock->mgr, csock);
|
||||
isc__nm_enqueue_ievent(&sock->mgr->workers[csock->tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
atomic_store(&csock->active, false);
|
||||
enqueue_stoplistening(csock);
|
||||
}
|
||||
|
||||
csock = &sock->children[isc_nm_tid()];
|
||||
atomic_store(&csock->active, false);
|
||||
stop_tcpdns_child(csock);
|
||||
|
||||
atomic_store(&sock->closed, true);
|
||||
isc__nmsocket_prep_destroy(sock);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include <uv.h>
|
||||
|
||||
#include <isc/atomic.h>
|
||||
#include <isc/barrier.h>
|
||||
#include <isc/buffer.h>
|
||||
#include <isc/condition.h>
|
||||
#include <isc/errno.h>
|
||||
|
|
@ -97,7 +98,7 @@ can_log_tlsdns_quota(void) {
|
|||
static isc_result_t
|
||||
tlsdns_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
|
||||
isc__networker_t *worker = NULL;
|
||||
isc_result_t result = ISC_R_DEFAULT;
|
||||
isc_result_t result = ISC_R_UNSET;
|
||||
int r;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
|
|
@ -324,7 +325,7 @@ isc_nm_tlsdnsconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
|
||||
sock->extrahandlesize = extrahandlesize;
|
||||
sock->connect_timeout = timeout;
|
||||
sock->result = ISC_R_DEFAULT;
|
||||
sock->result = ISC_R_UNSET;
|
||||
sock->tls.ctx = sslctx;
|
||||
atomic_init(&sock->client, true);
|
||||
atomic_init(&sock->connecting, true);
|
||||
|
|
@ -364,7 +365,7 @@ isc_nm_tlsdnsconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
(isc__netievent_t *)ievent);
|
||||
}
|
||||
LOCK(&sock->lock);
|
||||
while (sock->result == ISC_R_DEFAULT) {
|
||||
while (sock->result == ISC_R_UNSET) {
|
||||
WAIT(&sock->cond, &sock->lock);
|
||||
}
|
||||
atomic_store(&sock->active, true);
|
||||
|
|
@ -407,6 +408,51 @@ isc__nm_tlsdns_lb_socket(sa_family_t sa_family) {
|
|||
return (sock);
|
||||
}
|
||||
|
||||
static void
|
||||
start_tlsdns_child(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nmsocket_t *sock,
|
||||
uv_os_sock_t fd, int tid) {
|
||||
isc__netievent_tlsdnslisten_t *ievent = NULL;
|
||||
isc_nmsocket_t *csock = &sock->children[tid];
|
||||
|
||||
isc__nmsocket_init(csock, mgr, isc_nm_tlsdnssocket, iface);
|
||||
csock->parent = sock;
|
||||
csock->accept_cb = sock->accept_cb;
|
||||
csock->accept_cbarg = sock->accept_cbarg;
|
||||
csock->recv_cb = sock->recv_cb;
|
||||
csock->recv_cbarg = sock->recv_cbarg;
|
||||
csock->extrahandlesize = sock->extrahandlesize;
|
||||
csock->backlog = sock->backlog;
|
||||
csock->tid = tid;
|
||||
csock->tls.ctx = sock->tls.ctx;
|
||||
|
||||
/*
|
||||
* We don't attach to quota, just assign - to avoid
|
||||
* increasing quota unnecessarily.
|
||||
*/
|
||||
csock->pquota = sock->pquota;
|
||||
isc_quota_cb_init(&csock->quotacb, quota_accept_cb, csock);
|
||||
|
||||
#if HAVE_SO_REUSEPORT_LB || defined(WIN32)
|
||||
UNUSED(fd);
|
||||
csock->fd = isc__nm_tlsdns_lb_socket(iface->addr.type.sa.sa_family);
|
||||
#else
|
||||
csock->fd = dup(fd);
|
||||
#endif
|
||||
REQUIRE(csock->fd >= 0);
|
||||
|
||||
ievent = isc__nm_get_netievent_tlsdnslisten(mgr, csock);
|
||||
isc__nm_maybe_enqueue_ievent(&mgr->workers[tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
}
|
||||
|
||||
static void
|
||||
enqueue_stoplistening(isc_nmsocket_t *sock) {
|
||||
isc__netievent_tlsdnsstop_t *ievent =
|
||||
isc__nm_get_netievent_tlsdnsstop(sock->mgr, sock);
|
||||
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_nm_listentlsdns(isc_nm_t *mgr, isc_nmiface_t *iface,
|
||||
isc_nm_recv_cb_t recv_cb, void *recv_cbarg,
|
||||
|
|
@ -415,18 +461,15 @@ isc_nm_listentlsdns(isc_nm_t *mgr, isc_nmiface_t *iface,
|
|||
isc_tlsctx_t *sslctx, isc_nmsocket_t **sockp) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
isc_nmsocket_t *sock = NULL;
|
||||
sa_family_t sa_family = iface->addr.type.sa.sa_family;
|
||||
size_t children_size = 0;
|
||||
#if !HAVE_SO_REUSEPORT_LB && !defined(WIN32)
|
||||
uv_os_sock_t fd = -1;
|
||||
#endif
|
||||
|
||||
REQUIRE(VALID_NM(mgr));
|
||||
|
||||
sock = isc_mem_get(mgr->mctx, sizeof(*sock));
|
||||
isc__nmsocket_init(sock, mgr, isc_nm_tlsdnslistener, iface);
|
||||
|
||||
sock->rchildren = 0;
|
||||
atomic_init(&sock->rchildren, 0);
|
||||
#if defined(WIN32)
|
||||
sock->nchildren = 1;
|
||||
#else
|
||||
|
|
@ -436,47 +479,35 @@ isc_nm_listentlsdns(isc_nm_t *mgr, isc_nmiface_t *iface,
|
|||
sock->children = isc_mem_get(mgr->mctx, children_size);
|
||||
memset(sock->children, 0, children_size);
|
||||
|
||||
sock->result = ISC_R_DEFAULT;
|
||||
sock->tid = isc_random_uniform(sock->nchildren);
|
||||
sock->fd = -1;
|
||||
sock->result = ISC_R_UNSET;
|
||||
sock->accept_cb = accept_cb;
|
||||
sock->accept_cbarg = accept_cbarg;
|
||||
sock->recv_cb = recv_cb;
|
||||
sock->recv_cbarg = recv_cbarg;
|
||||
sock->extrahandlesize = extrahandlesize;
|
||||
sock->backlog = backlog;
|
||||
sock->pquota = quota;
|
||||
|
||||
sock->tls.ctx = sslctx;
|
||||
|
||||
sock->tid = 0;
|
||||
sock->fd = -1;
|
||||
|
||||
#if !HAVE_SO_REUSEPORT_LB && !defined(WIN32)
|
||||
fd = isc__nm_tlsdns_lb_socket(sa_family);
|
||||
fd = isc__nm_tlsdns_lb_socket(iface->addr.type.sa.sa_family);
|
||||
#endif
|
||||
|
||||
isc_barrier_init(&sock->startlistening, sock->nchildren);
|
||||
|
||||
for (size_t i = 0; i < sock->nchildren; i++) {
|
||||
isc__netievent_tlsdnslisten_t *ievent = NULL;
|
||||
isc_nmsocket_t *csock = &sock->children[i];
|
||||
if ((int)i == isc_nm_tid()) {
|
||||
continue;
|
||||
}
|
||||
start_tlsdns_child(mgr, iface, sock, fd, i);
|
||||
}
|
||||
|
||||
isc__nmsocket_init(csock, mgr, isc_nm_tlsdnssocket, iface);
|
||||
csock->parent = sock;
|
||||
csock->accept_cb = accept_cb;
|
||||
csock->accept_cbarg = accept_cbarg;
|
||||
csock->recv_cb = recv_cb;
|
||||
csock->recv_cbarg = recv_cbarg;
|
||||
csock->extrahandlesize = extrahandlesize;
|
||||
csock->backlog = backlog;
|
||||
csock->tid = i;
|
||||
csock->tls.ctx = sslctx;
|
||||
|
||||
/*
|
||||
* We don't attach to quota, just assign - to avoid
|
||||
* increasing quota unnecessarily.
|
||||
*/
|
||||
csock->pquota = quota;
|
||||
isc_quota_cb_init(&csock->quotacb, quota_accept_cb, csock);
|
||||
|
||||
#if HAVE_SO_REUSEPORT_LB || defined(WIN32)
|
||||
csock->fd = isc__nm_tlsdns_lb_socket(sa_family);
|
||||
#else
|
||||
csock->fd = dup(fd);
|
||||
#endif
|
||||
REQUIRE(csock->fd >= 0);
|
||||
|
||||
ievent = isc__nm_get_netievent_tlsdnslisten(mgr, csock);
|
||||
isc__nm_maybe_enqueue_ievent(&mgr->workers[i],
|
||||
(isc__netievent_t *)ievent);
|
||||
if (isc__nm_in_netthread()) {
|
||||
start_tlsdns_child(mgr, iface, sock, fd, isc_nm_tid());
|
||||
}
|
||||
|
||||
#if !HAVE_SO_REUSEPORT_LB && !defined(WIN32)
|
||||
|
|
@ -484,21 +515,21 @@ isc_nm_listentlsdns(isc_nm_t *mgr, isc_nmiface_t *iface,
|
|||
#endif
|
||||
|
||||
LOCK(&sock->lock);
|
||||
while (sock->rchildren != sock->nchildren) {
|
||||
while (atomic_load(&sock->rchildren) != sock->nchildren) {
|
||||
WAIT(&sock->cond, &sock->lock);
|
||||
}
|
||||
result = sock->result;
|
||||
atomic_store(&sock->active, true);
|
||||
BROADCAST(&sock->scond);
|
||||
UNLOCK(&sock->lock);
|
||||
INSIST(result != ISC_R_DEFAULT);
|
||||
|
||||
INSIST(result != ISC_R_UNSET);
|
||||
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
REQUIRE(sock->rchildren == sock->nchildren);
|
||||
REQUIRE(atomic_load(&sock->rchildren) == sock->nchildren);
|
||||
*sockp = sock;
|
||||
} else {
|
||||
atomic_store(&sock->active, false);
|
||||
isc__nm_tlsdns_stoplistening(sock);
|
||||
enqueue_stoplistening(sock);
|
||||
isc_nmsocket_close(&sock);
|
||||
}
|
||||
|
||||
|
|
@ -514,7 +545,7 @@ isc__nm_async_tlsdnslisten(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
int r;
|
||||
int flags = 0;
|
||||
isc_nmsocket_t *sock = NULL;
|
||||
isc_result_t result = ISC_R_DEFAULT;
|
||||
isc_result_t result = ISC_R_UNSET;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(ievent->sock));
|
||||
REQUIRE(ievent->sock->tid == isc_nm_tid());
|
||||
|
|
@ -603,16 +634,14 @@ done:
|
|||
sock->pquota = NULL;
|
||||
}
|
||||
|
||||
sock->parent->rchildren += 1;
|
||||
if (sock->parent->result == ISC_R_DEFAULT) {
|
||||
atomic_fetch_add(&sock->parent->rchildren, 1);
|
||||
if (sock->parent->result == ISC_R_UNSET) {
|
||||
sock->parent->result = result;
|
||||
}
|
||||
SIGNAL(&sock->parent->cond);
|
||||
if (!atomic_load(&sock->parent->active)) {
|
||||
WAIT(&sock->parent->scond, &sock->parent->lock);
|
||||
}
|
||||
INSIST(atomic_load(&sock->parent->active));
|
||||
UNLOCK(&sock->parent->lock);
|
||||
|
||||
isc_barrier_wait(&sock->parent->startlistening);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -658,14 +687,6 @@ done:
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
enqueue_stoplistening(isc_nmsocket_t *sock) {
|
||||
isc__netievent_tlsdnsstop_t *ievent =
|
||||
isc__nm_get_netievent_tlsdnsstop(sock->mgr, sock);
|
||||
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
}
|
||||
|
||||
void
|
||||
isc__nm_tlsdns_stoplistening(isc_nmsocket_t *sock) {
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
|
|
@ -676,7 +697,12 @@ isc__nm_tlsdns_stoplistening(isc_nmsocket_t *sock) {
|
|||
INSIST(0);
|
||||
ISC_UNREACHABLE();
|
||||
}
|
||||
enqueue_stoplistening(sock);
|
||||
|
||||
if (!isc__nm_in_netthread()) {
|
||||
enqueue_stoplistening(sock);
|
||||
} else {
|
||||
stop_tlsdns_parent(sock);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1770,8 +1796,6 @@ timer_close_cb(uv_handle_t *handle) {
|
|||
|
||||
static void
|
||||
stop_tlsdns_child(isc_nmsocket_t *sock) {
|
||||
bool last_child = false;
|
||||
|
||||
REQUIRE(sock->type == isc_nm_tlsdnssocket);
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
|
|
@ -1782,34 +1806,43 @@ stop_tlsdns_child(isc_nmsocket_t *sock) {
|
|||
|
||||
tlsdns_close_direct(sock);
|
||||
|
||||
LOCK(&sock->parent->lock);
|
||||
sock->parent->rchildren -= 1;
|
||||
last_child = (sock->parent->rchildren == 0);
|
||||
UNLOCK(&sock->parent->lock);
|
||||
atomic_fetch_sub(&sock->parent->rchildren, 1);
|
||||
|
||||
if (last_child) {
|
||||
atomic_store(&sock->parent->closed, true);
|
||||
isc__nmsocket_prep_destroy(sock->parent);
|
||||
}
|
||||
isc_barrier_wait(&sock->parent->stoplistening);
|
||||
}
|
||||
|
||||
static void
|
||||
stop_tlsdns_parent(isc_nmsocket_t *sock) {
|
||||
isc_nmsocket_t *csock = NULL;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
REQUIRE(sock->type == isc_nm_tlsdnslistener);
|
||||
|
||||
isc_barrier_init(&sock->stoplistening, sock->nchildren);
|
||||
|
||||
for (size_t i = 0; i < sock->nchildren; i++) {
|
||||
isc__netievent_tlsdnsstop_t *ievent = NULL;
|
||||
isc_nmsocket_t *csock = &sock->children[i];
|
||||
csock = &sock->children[i];
|
||||
|
||||
REQUIRE(VALID_NMSOCK(csock));
|
||||
|
||||
atomic_store(&csock->active, false);
|
||||
if ((int)i == isc_nm_tid()) {
|
||||
/*
|
||||
* We need to schedule closing the other sockets first
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
ievent = isc__nm_get_netievent_tlsdnsstop(sock->mgr, csock);
|
||||
isc__nm_enqueue_ievent(&sock->mgr->workers[csock->tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
atomic_store(&csock->active, false);
|
||||
enqueue_stoplistening(csock);
|
||||
}
|
||||
|
||||
csock = &sock->children[isc_nm_tid()];
|
||||
atomic_store(&csock->active, false);
|
||||
stop_tlsdns_child(csock);
|
||||
|
||||
atomic_store(&sock->closed, true);
|
||||
isc__nmsocket_prep_destroy(sock);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -621,7 +621,7 @@ isc_nm_listentls(isc_nm_t *mgr, isc_nmiface_t *iface,
|
|||
tlssock->tlsstream.server_iface = *iface;
|
||||
ISC_LINK_INIT(&tlssock->tlsstream.server_iface.addr, link);
|
||||
tlssock->iface = &tlssock->tlsstream.server_iface;
|
||||
tlssock->result = ISC_R_DEFAULT;
|
||||
tlssock->result = ISC_R_UNSET;
|
||||
tlssock->accept_cb = accept_cb;
|
||||
tlssock->accept_cbarg = accept_cbarg;
|
||||
tlssock->extrahandlesize = extrahandlesize;
|
||||
|
|
@ -643,19 +643,12 @@ isc_nm_listentls(isc_nm_t *mgr, isc_nmiface_t *iface,
|
|||
|
||||
/* wait for listen result */
|
||||
isc__nmsocket_attach(tlssock->outer, &tsock);
|
||||
LOCK(&tlssock->outer->lock);
|
||||
while (tlssock->outer->rchildren != tlssock->outer->nchildren) {
|
||||
WAIT(&tlssock->outer->cond, &tlssock->outer->lock);
|
||||
}
|
||||
result = tlssock->outer->result;
|
||||
tlssock->result = result;
|
||||
atomic_store(&tlssock->active, true);
|
||||
INSIST(tlssock->outer->tlsstream.tlslistener == NULL);
|
||||
isc__nmsocket_attach(tlssock, &tlssock->outer->tlsstream.tlslistener);
|
||||
BROADCAST(&tlssock->outer->scond);
|
||||
UNLOCK(&tlssock->outer->lock);
|
||||
isc__nmsocket_detach(&tsock);
|
||||
INSIST(result != ISC_R_DEFAULT);
|
||||
INSIST(result != ISC_R_UNSET);
|
||||
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
atomic_store(&tlssock->listening, true);
|
||||
|
|
@ -849,6 +842,12 @@ isc__nm_tls_stoplistening(isc_nmsocket_t *sock) {
|
|||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->type == isc_nm_tlslistener);
|
||||
|
||||
if (!atomic_compare_exchange_strong(&sock->closing, &(bool){ false },
|
||||
true)) {
|
||||
INSIST(0);
|
||||
ISC_UNREACHABLE();
|
||||
}
|
||||
|
||||
atomic_store(&sock->listening, false);
|
||||
atomic_store(&sock->closed, true);
|
||||
sock->recv_cb = NULL;
|
||||
|
|
@ -885,7 +884,7 @@ isc_nm_tlsconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
ISC_LINK_INIT(&nsock->tlsstream.local_iface.addr, link);
|
||||
nsock->iface = &nsock->tlsstream.local_iface;
|
||||
nsock->extrahandlesize = extrahandlesize;
|
||||
nsock->result = ISC_R_DEFAULT;
|
||||
nsock->result = ISC_R_UNSET;
|
||||
nsock->connect_cb = cb;
|
||||
nsock->connect_cbarg = cbarg;
|
||||
nsock->connect_timeout = timeout;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <uv.h>
|
||||
|
||||
#include <isc/atomic.h>
|
||||
#include <isc/barrier.h>
|
||||
#include <isc/buffer.h>
|
||||
#include <isc/condition.h>
|
||||
#include <isc/errno.h>
|
||||
|
|
@ -77,18 +78,52 @@ isc__nm_udp_lb_socket(sa_family_t sa_family) {
|
|||
return (sock);
|
||||
}
|
||||
|
||||
static void
|
||||
start_udp_child(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nmsocket_t *sock,
|
||||
uv_os_sock_t fd, int tid) {
|
||||
isc_nmsocket_t *csock;
|
||||
isc__netievent_udplisten_t *ievent = NULL;
|
||||
|
||||
csock = &sock->children[tid];
|
||||
|
||||
isc__nmsocket_init(csock, mgr, isc_nm_udpsocket, iface);
|
||||
csock->parent = sock;
|
||||
csock->iface = sock->iface;
|
||||
csock->reading = true;
|
||||
csock->recv_cb = sock->recv_cb;
|
||||
csock->recv_cbarg = sock->recv_cbarg;
|
||||
csock->extrahandlesize = sock->extrahandlesize;
|
||||
csock->tid = tid;
|
||||
|
||||
#if HAVE_SO_REUSEPORT_LB || defined(WIN32)
|
||||
UNUSED(fd);
|
||||
csock->fd = isc__nm_udp_lb_socket(iface->addr.type.sa.sa_family);
|
||||
#else
|
||||
csock->fd = dup(fd);
|
||||
#endif
|
||||
REQUIRE(csock->fd >= 0);
|
||||
|
||||
ievent = isc__nm_get_netievent_udplisten(mgr, csock);
|
||||
isc__nm_maybe_enqueue_ievent(&mgr->workers[tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
}
|
||||
|
||||
static void
|
||||
enqueue_stoplistening(isc_nmsocket_t *sock) {
|
||||
isc__netievent_udpstop_t *ievent =
|
||||
isc__nm_get_netievent_udpstop(sock->mgr, sock);
|
||||
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_nm_listenudp(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb,
|
||||
void *cbarg, size_t extrahandlesize, isc_nmsocket_t **sockp) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
isc_nmsocket_t *sock = NULL;
|
||||
sa_family_t sa_family = iface->addr.type.sa.sa_family;
|
||||
size_t children_size = 0;
|
||||
#if !HAVE_SO_REUSEPORT_LB && !defined(WIN32)
|
||||
uv_os_sock_t fd = -1;
|
||||
#endif
|
||||
|
||||
REQUIRE(VALID_NM(mgr));
|
||||
uv_os_sock_t fd = -1;
|
||||
|
||||
/*
|
||||
* We are creating mgr->nworkers duplicated sockets, one
|
||||
|
|
@ -97,7 +132,7 @@ isc_nm_listenudp(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb,
|
|||
sock = isc_mem_get(mgr->mctx, sizeof(isc_nmsocket_t));
|
||||
isc__nmsocket_init(sock, mgr, isc_nm_udplistener, iface);
|
||||
|
||||
sock->rchildren = 0;
|
||||
atomic_init(&sock->rchildren, 0);
|
||||
#if defined(WIN32)
|
||||
sock->nchildren = 1;
|
||||
#else
|
||||
|
|
@ -111,37 +146,26 @@ isc_nm_listenudp(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb,
|
|||
sock->recv_cb = cb;
|
||||
sock->recv_cbarg = cbarg;
|
||||
sock->extrahandlesize = extrahandlesize;
|
||||
sock->result = ISC_R_DEFAULT;
|
||||
sock->tid = isc_random_uniform(sock->nchildren);
|
||||
sock->result = ISC_R_UNSET;
|
||||
|
||||
sock->tid = 0;
|
||||
sock->fd = -1;
|
||||
|
||||
#if !HAVE_SO_REUSEPORT_LB && !defined(WIN32)
|
||||
fd = isc__nm_udp_lb_socket(sa_family);
|
||||
fd = isc__nm_udp_lb_socket(iface->addr.type.sa.sa_family);
|
||||
#endif
|
||||
|
||||
isc_barrier_init(&sock->startlistening, sock->nchildren);
|
||||
|
||||
for (size_t i = 0; i < sock->nchildren; i++) {
|
||||
isc__netievent_udplisten_t *ievent = NULL;
|
||||
isc_nmsocket_t *csock = &sock->children[i];
|
||||
if ((int)i == isc_nm_tid()) {
|
||||
continue;
|
||||
}
|
||||
start_udp_child(mgr, iface, sock, fd, i);
|
||||
}
|
||||
|
||||
isc__nmsocket_init(csock, mgr, isc_nm_udpsocket, iface);
|
||||
csock->parent = sock;
|
||||
csock->iface = sock->iface;
|
||||
csock->reading = true;
|
||||
csock->recv_cb = cb;
|
||||
csock->recv_cbarg = cbarg;
|
||||
csock->extrahandlesize = sock->extrahandlesize;
|
||||
csock->tid = i;
|
||||
|
||||
#if HAVE_SO_REUSEPORT_LB || defined(WIN32)
|
||||
csock->fd = isc__nm_udp_lb_socket(sa_family);
|
||||
#else
|
||||
csock->fd = dup(fd);
|
||||
#endif
|
||||
REQUIRE(csock->fd >= 0);
|
||||
|
||||
ievent = isc__nm_get_netievent_udplisten(mgr, csock);
|
||||
isc__nm_maybe_enqueue_ievent(&mgr->workers[i],
|
||||
(isc__netievent_t *)ievent);
|
||||
if (isc__nm_in_netthread()) {
|
||||
start_udp_child(mgr, iface, sock, fd, isc_nm_tid());
|
||||
}
|
||||
|
||||
#if !HAVE_SO_REUSEPORT_LB && !defined(WIN32)
|
||||
|
|
@ -149,21 +173,21 @@ isc_nm_listenudp(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb,
|
|||
#endif
|
||||
|
||||
LOCK(&sock->lock);
|
||||
while (sock->rchildren != sock->nchildren) {
|
||||
while (atomic_load(&sock->rchildren) != sock->nchildren) {
|
||||
WAIT(&sock->cond, &sock->lock);
|
||||
}
|
||||
result = sock->result;
|
||||
atomic_store(&sock->active, true);
|
||||
BROADCAST(&sock->scond);
|
||||
UNLOCK(&sock->lock);
|
||||
INSIST(result != ISC_R_DEFAULT);
|
||||
|
||||
INSIST(result != ISC_R_UNSET);
|
||||
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
REQUIRE(sock->rchildren == sock->nchildren);
|
||||
REQUIRE(atomic_load(&sock->rchildren) == sock->nchildren);
|
||||
*sockp = sock;
|
||||
} else {
|
||||
atomic_store(&sock->active, false);
|
||||
isc__nm_udp_stoplistening(sock);
|
||||
enqueue_stoplistening(sock);
|
||||
isc_nmsocket_close(&sock);
|
||||
}
|
||||
|
||||
|
|
@ -181,7 +205,7 @@ isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
int r, uv_bind_flags = 0;
|
||||
int uv_init_flags = 0;
|
||||
sa_family_t sa_family;
|
||||
isc_result_t result = ISC_R_DEFAULT;
|
||||
isc_result_t result = ISC_R_UNSET;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(ievent->sock));
|
||||
REQUIRE(ievent->sock->tid == isc_nm_tid());
|
||||
|
|
@ -269,24 +293,14 @@ isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
|
||||
done:
|
||||
result = isc__nm_uverr2result(r);
|
||||
sock->parent->rchildren += 1;
|
||||
if (sock->parent->result == ISC_R_DEFAULT) {
|
||||
atomic_fetch_add(&sock->parent->rchildren, 1);
|
||||
if (sock->parent->result == ISC_R_UNSET) {
|
||||
sock->parent->result = result;
|
||||
}
|
||||
SIGNAL(&sock->parent->cond);
|
||||
if (!atomic_load(&sock->parent->active)) {
|
||||
WAIT(&sock->parent->scond, &sock->parent->lock);
|
||||
}
|
||||
INSIST(atomic_load(&sock->parent->active));
|
||||
UNLOCK(&sock->parent->lock);
|
||||
}
|
||||
|
||||
static void
|
||||
enqueue_stoplistening(isc_nmsocket_t *sock) {
|
||||
isc__netievent_udpstop_t *ievent =
|
||||
isc__nm_get_netievent_udpstop(sock->mgr, sock);
|
||||
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
|
||||
(isc__netievent_t *)ievent);
|
||||
isc_barrier_wait(&sock->parent->startlistening);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -300,7 +314,11 @@ isc__nm_udp_stoplistening(isc_nmsocket_t *sock) {
|
|||
ISC_UNREACHABLE();
|
||||
}
|
||||
|
||||
enqueue_stoplistening(sock);
|
||||
if (!isc__nm_in_netthread()) {
|
||||
enqueue_stoplistening(sock);
|
||||
} else {
|
||||
stop_udp_parent(sock);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -321,9 +339,6 @@ isc__nm_async_udpstop(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If network manager is paused, re-enqueue the event for later.
|
||||
*/
|
||||
stop_udp_parent(sock);
|
||||
}
|
||||
|
||||
|
|
@ -590,7 +605,7 @@ static isc_result_t
|
|||
udp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) {
|
||||
isc__networker_t *worker = NULL;
|
||||
int uv_bind_flags = UV_UDP_REUSEADDR;
|
||||
isc_result_t result = ISC_R_DEFAULT;
|
||||
isc_result_t result = ISC_R_UNSET;
|
||||
int tries = 3;
|
||||
int r;
|
||||
|
||||
|
|
@ -690,7 +705,6 @@ isc__nm_async_udpconnect(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||
REQUIRE(sock->parent == NULL);
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
req->handle = isc__nmhandle_get(sock, &req->peer, &sock->iface->addr);
|
||||
result = udp_connect_direct(sock, req);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
atomic_store(&sock->active, false);
|
||||
|
|
@ -734,7 +748,7 @@ isc_nm_udpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
sock->read_timeout = timeout;
|
||||
sock->extrahandlesize = extrahandlesize;
|
||||
sock->peer = peer->addr;
|
||||
sock->result = ISC_R_DEFAULT;
|
||||
sock->result = ISC_R_UNSET;
|
||||
atomic_init(&sock->client, true);
|
||||
|
||||
req = isc__nm_uvreq_get(mgr, sock);
|
||||
|
|
@ -742,6 +756,7 @@ isc_nm_udpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
req->cbarg = cbarg;
|
||||
req->peer = peer->addr;
|
||||
req->local = local->addr;
|
||||
req->handle = isc__nmhandle_get(sock, &req->peer, &sock->iface->addr);
|
||||
|
||||
result = isc__nm_socket(sa_family, SOCK_DGRAM, 0, &sock->fd);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
|
|
@ -782,7 +797,7 @@ isc_nm_udpconnect(isc_nm_t *mgr, isc_nmiface_t *local, isc_nmiface_t *peer,
|
|||
(isc__netievent_t *)event);
|
||||
}
|
||||
LOCK(&sock->lock);
|
||||
while (sock->result == ISC_R_DEFAULT) {
|
||||
while (sock->result == ISC_R_UNSET) {
|
||||
WAIT(&sock->cond, &sock->lock);
|
||||
}
|
||||
atomic_store(&sock->active, true);
|
||||
|
|
@ -970,8 +985,6 @@ stop_udp_child(isc_nmsocket_t *sock) {
|
|||
REQUIRE(sock->type == isc_nm_udpsocket);
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
|
||||
bool last_child = false;
|
||||
|
||||
if (!atomic_compare_exchange_strong(&sock->closing, &(bool){ false },
|
||||
true)) {
|
||||
return;
|
||||
|
|
@ -979,33 +992,42 @@ stop_udp_child(isc_nmsocket_t *sock) {
|
|||
|
||||
udp_close_direct(sock);
|
||||
|
||||
LOCK(&sock->parent->lock);
|
||||
sock->parent->rchildren -= 1;
|
||||
last_child = (sock->parent->rchildren == 0);
|
||||
UNLOCK(&sock->parent->lock);
|
||||
atomic_fetch_sub(&sock->parent->rchildren, 1);
|
||||
|
||||
if (last_child) {
|
||||
atomic_store(&sock->parent->closed, true);
|
||||
isc__nmsocket_prep_destroy(sock->parent);
|
||||
}
|
||||
isc_barrier_wait(&sock->parent->stoplistening);
|
||||
}
|
||||
|
||||
static void
|
||||
stop_udp_parent(isc_nmsocket_t *sock) {
|
||||
isc_nmsocket_t *csock = NULL;
|
||||
|
||||
REQUIRE(VALID_NMSOCK(sock));
|
||||
REQUIRE(sock->tid == isc_nm_tid());
|
||||
REQUIRE(sock->type == isc_nm_udplistener);
|
||||
|
||||
isc_barrier_init(&sock->stoplistening, sock->nchildren);
|
||||
|
||||
for (size_t i = 0; i < sock->nchildren; i++) {
|
||||
isc__netievent_udpstop_t *ievent = NULL;
|
||||
isc_nmsocket_t *csock = &sock->children[i];
|
||||
csock = &sock->children[i];
|
||||
REQUIRE(VALID_NMSOCK(csock));
|
||||
|
||||
atomic_store(&csock->active, false);
|
||||
if ((int)i == isc_nm_tid()) {
|
||||
/*
|
||||
* We need to schedule closing the other sockets first
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
ievent = isc__nm_get_netievent_udpstop(sock->mgr, csock);
|
||||
isc__nm_enqueue_ievent(&sock->mgr->workers[i],
|
||||
(isc__netievent_t *)ievent);
|
||||
atomic_store(&csock->active, false);
|
||||
enqueue_stoplistening(csock);
|
||||
}
|
||||
|
||||
csock = &sock->children[isc_nm_tid()];
|
||||
atomic_store(&csock->active, false);
|
||||
stop_udp_child(csock);
|
||||
|
||||
atomic_store(&sock->closed, true);
|
||||
isc__nmsocket_prep_destroy(sock);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
36
lib/isc/netmgr_p.h
Normal file
36
lib/isc/netmgr_p.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <isc/mem.h>
|
||||
#include <isc/result.h>
|
||||
|
||||
void
|
||||
isc__netmgr_create(isc_mem_t *mctx, uint32_t workers, isc_nm_t **netgmrp);
|
||||
/*%<
|
||||
* Creates a new network manager with 'workers' worker threads,
|
||||
* and starts it running.
|
||||
*/
|
||||
|
||||
void
|
||||
isc__netmgr_destroy(isc_nm_t **netmgrp);
|
||||
/*%<
|
||||
* Similar to isc_nm_detach(), but actively waits for all other references
|
||||
* to be gone before returning.
|
||||
*/
|
||||
|
||||
void
|
||||
isc__netmgr_shutdown(isc_nm_t *mgr);
|
||||
/*%<
|
||||
* Shut down all active connections, freeing associated resources;
|
||||
* prevent new connections from being established.
|
||||
*/
|
||||
81
lib/isc/socket_p.h
Normal file
81
lib/isc/socket_p.h
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <isc/mem.h>
|
||||
#include <isc/result.h>
|
||||
#include <isc/socket.h>
|
||||
|
||||
isc_result_t
|
||||
isc__socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp,
|
||||
unsigned int maxsocks, int nthreads);
|
||||
/*%<
|
||||
* Create a socket manager. If "maxsocks" is non-zero, it specifies the
|
||||
* maximum number of sockets that the created manager should handle.
|
||||
*
|
||||
* 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_socketmgr_t.
|
||||
*
|
||||
* Ensures:
|
||||
*
|
||||
*\li '*managerp' is a valid isc_socketmgr_t.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li #ISC_R_SUCCESS
|
||||
*\li #ISC_R_NOMEMORY
|
||||
*\li #ISC_R_UNEXPECTED
|
||||
*\li #ISC_R_NOTIMPLEMENTED
|
||||
*/
|
||||
|
||||
void
|
||||
isc__socketmgr_destroy(isc_socketmgr_t **managerp);
|
||||
/*%<
|
||||
* Destroy a socket manager.
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
*\li This routine blocks until there are no sockets left in the manager,
|
||||
* so if the caller holds any socket references using the manager, it
|
||||
* must detach them before calling isc_socketmgr_destroy() or it will
|
||||
* block forever.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li '*managerp' is a valid isc_socketmgr_t.
|
||||
*
|
||||
*\li All sockets managed by this manager are fully detached.
|
||||
*
|
||||
* Ensures:
|
||||
*
|
||||
*\li *managerp == NULL
|
||||
*
|
||||
*\li All resources used by the manager have been freed.
|
||||
*/
|
||||
|
||||
#if !WIN32
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
typedef struct isc_socketwait isc_socketwait_t;
|
||||
int
|
||||
isc__socketmgr_waitevents(isc_socketmgr_t *, struct timeval *,
|
||||
isc_socketwait_t **);
|
||||
isc_result_t
|
||||
isc__socketmgr_dispatch(isc_socketmgr_t *, isc_socketwait_t *);
|
||||
|
||||
#endif
|
||||
173
lib/isc/task.c
173
lib/isc/task.c
|
|
@ -17,6 +17,7 @@
|
|||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <isc/app.h>
|
||||
#include <isc/atomic.h>
|
||||
|
|
@ -44,9 +45,7 @@
|
|||
#include <json_object.h>
|
||||
#endif /* HAVE_JSON_C */
|
||||
|
||||
#ifdef OPENSSL_LEAKS
|
||||
#include <openssl/err.h>
|
||||
#endif /* ifdef OPENSSL_LEAKS */
|
||||
#include "task_p.h"
|
||||
|
||||
/*
|
||||
* Task manager is built around 'as little locking as possible' concept.
|
||||
|
|
@ -104,6 +103,7 @@ struct isc_task {
|
|||
task_state_t state;
|
||||
int pause_cnt;
|
||||
isc_refcount_t references;
|
||||
isc_refcount_t running;
|
||||
isc_eventlist_t events;
|
||||
isc_eventlist_t on_shutdown;
|
||||
unsigned int nevents;
|
||||
|
|
@ -114,21 +114,14 @@ struct isc_task {
|
|||
void *tag;
|
||||
bool bound;
|
||||
/* Protected by atomics */
|
||||
atomic_uint_fast32_t flags;
|
||||
atomic_bool shuttingdown;
|
||||
atomic_bool privileged;
|
||||
/* Locked by task manager lock. */
|
||||
LINK(isc_task_t) link;
|
||||
};
|
||||
|
||||
#define TASK_F_SHUTTINGDOWN 0x01
|
||||
#define TASK_F_PRIVILEGED 0x02
|
||||
|
||||
#define TASK_SHUTTINGDOWN(t) \
|
||||
((atomic_load_acquire(&(t)->flags) & TASK_F_SHUTTINGDOWN) != 0)
|
||||
#define TASK_PRIVILEGED(t) \
|
||||
((atomic_load_acquire(&(t)->flags) & TASK_F_PRIVILEGED) != 0)
|
||||
|
||||
#define TASK_FLAG_SET(t, f) atomic_fetch_or_release(&(t)->flags, (f))
|
||||
#define TASK_FLAG_CLR(t, f) atomic_fetch_and_release(&(t)->flags, ~(f))
|
||||
#define TASK_SHUTTINGDOWN(t) (atomic_load_acquire(&(t)->shuttingdown))
|
||||
#define TASK_PRIVILEGED(t) (atomic_load_acquire(&(t)->privileged))
|
||||
|
||||
#define TASK_MANAGER_MAGIC ISC_MAGIC('T', 'S', 'K', 'M')
|
||||
#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, TASK_MANAGER_MAGIC)
|
||||
|
|
@ -139,20 +132,16 @@ struct isc_taskmgr {
|
|||
isc_refcount_t references;
|
||||
isc_mem_t *mctx;
|
||||
isc_mutex_t lock;
|
||||
atomic_uint_fast32_t tasks_running;
|
||||
atomic_uint_fast32_t tasks_ready;
|
||||
atomic_uint_fast32_t tasks_count;
|
||||
isc_nm_t *nm;
|
||||
isc_nm_t *netmgr;
|
||||
|
||||
/* Locked by task manager lock. */
|
||||
unsigned int default_quantum;
|
||||
LIST(isc_task_t) tasks;
|
||||
atomic_uint_fast32_t mode;
|
||||
atomic_bool exclusive_req;
|
||||
atomic_bool exiting;
|
||||
|
||||
/* Locked by halt_lock */
|
||||
unsigned int halted;
|
||||
|
||||
/*
|
||||
* Multiple threads can read/write 'excl' at the same time, so we need
|
||||
* to protect the access. We can't use 'lock' since isc_task_detach()
|
||||
|
|
@ -163,9 +152,6 @@ struct isc_taskmgr {
|
|||
};
|
||||
|
||||
#define DEFAULT_DEFAULT_QUANTUM 25
|
||||
#define FINISHED(m) \
|
||||
(atomic_load_relaxed(&((m)->exiting)) && \
|
||||
atomic_load(&(m)->tasks_count) == 0)
|
||||
|
||||
/*%
|
||||
* The following are intended for internal use (indicated by "isc__"
|
||||
|
|
@ -195,6 +181,7 @@ task_finished(isc_task_t *task) {
|
|||
|
||||
XTRACE("task_finished");
|
||||
|
||||
isc_refcount_destroy(&task->running);
|
||||
isc_refcount_destroy(&task->references);
|
||||
|
||||
LOCK(&manager->lock);
|
||||
|
|
@ -253,11 +240,13 @@ isc_task_create_bound(isc_taskmgr_t *manager, unsigned int quantum,
|
|||
task->pause_cnt = 0;
|
||||
|
||||
isc_refcount_init(&task->references, 1);
|
||||
isc_refcount_init(&task->running, 0);
|
||||
INIT_LIST(task->events);
|
||||
INIT_LIST(task->on_shutdown);
|
||||
task->nevents = 0;
|
||||
task->quantum = (quantum > 0) ? quantum : manager->default_quantum;
|
||||
atomic_init(&task->flags, 0);
|
||||
atomic_init(&task->shuttingdown, false);
|
||||
atomic_init(&task->privileged, false);
|
||||
task->now = 0;
|
||||
isc_time_settoepoch(&task->tnow);
|
||||
memset(task->name, 0, sizeof(task->name));
|
||||
|
|
@ -313,9 +302,9 @@ task_shutdown(isc_task_t *task) {
|
|||
|
||||
XTRACE("task_shutdown");
|
||||
|
||||
if (!TASK_SHUTTINGDOWN(task)) {
|
||||
if (atomic_compare_exchange_strong(&task->shuttingdown,
|
||||
&(bool){ false }, true)) {
|
||||
XTRACE("shutting down");
|
||||
TASK_FLAG_SET(task, TASK_F_SHUTTINGDOWN);
|
||||
if (task->state == task_state_idle) {
|
||||
INSIST(EMPTY(task->events));
|
||||
task->state = task_state_ready;
|
||||
|
|
@ -352,7 +341,14 @@ task_ready(isc_task_t *task) {
|
|||
REQUIRE(VALID_MANAGER(manager));
|
||||
|
||||
XTRACE("task_ready");
|
||||
isc_nm_task_enqueue(manager->nm, task, task->threadid);
|
||||
|
||||
isc_refcount_increment0(&task->running);
|
||||
isc_nm_task_enqueue(manager->netmgr, task, task->threadid);
|
||||
}
|
||||
|
||||
void
|
||||
isc_task_ready(isc_task_t *task) {
|
||||
task_ready(task);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
|
|
@ -822,8 +818,7 @@ task_run(isc_task_t *task) {
|
|||
* and task lock to avoid deadlocks, just bail then.
|
||||
*/
|
||||
if (task->state != task_state_ready) {
|
||||
UNLOCK(&task->lock);
|
||||
return (ISC_R_SUCCESS);
|
||||
goto done;
|
||||
}
|
||||
|
||||
INSIST(task->state == task_state_ready);
|
||||
|
|
@ -888,7 +883,6 @@ task_run(isc_task_t *task) {
|
|||
* The task is done.
|
||||
*/
|
||||
XTRACE("done");
|
||||
finished = true;
|
||||
task->state = task_state_done;
|
||||
} else {
|
||||
if (task->state == task_state_running) {
|
||||
|
|
@ -922,6 +916,13 @@ task_run(isc_task_t *task) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (isc_refcount_decrement(&task->running) == 1 &&
|
||||
task->state == task_state_done)
|
||||
{
|
||||
finished = true;
|
||||
}
|
||||
UNLOCK(&task->lock);
|
||||
|
||||
if (finished) {
|
||||
|
|
@ -939,7 +940,7 @@ isc_task_run(isc_task_t *task) {
|
|||
static void
|
||||
manager_free(isc_taskmgr_t *manager) {
|
||||
isc_refcount_destroy(&manager->references);
|
||||
isc_nm_detach(&manager->nm);
|
||||
isc_nm_detach(&manager->netmgr);
|
||||
|
||||
isc_mutex_destroy(&manager->lock);
|
||||
isc_mutex_destroy(&manager->excl_lock);
|
||||
|
|
@ -967,8 +968,8 @@ isc_taskmgr_detach(isc_taskmgr_t *manager) {
|
|||
}
|
||||
|
||||
isc_result_t
|
||||
isc_taskmgr_create(isc_mem_t *mctx, unsigned int default_quantum, isc_nm_t *nm,
|
||||
isc_taskmgr_t **managerp) {
|
||||
isc__taskmgr_create(isc_mem_t *mctx, unsigned int default_quantum, isc_nm_t *nm,
|
||||
isc_taskmgr_t **managerp) {
|
||||
isc_taskmgr_t *manager;
|
||||
|
||||
/*
|
||||
|
|
@ -990,14 +991,12 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int default_quantum, isc_nm_t *nm,
|
|||
manager->default_quantum = default_quantum;
|
||||
|
||||
if (nm != NULL) {
|
||||
isc_nm_attach(nm, &manager->nm);
|
||||
isc_nm_attach(nm, &manager->netmgr);
|
||||
}
|
||||
|
||||
INIT_LIST(manager->tasks);
|
||||
atomic_init(&manager->tasks_count, 0);
|
||||
atomic_init(&manager->tasks_running, 0);
|
||||
atomic_init(&manager->tasks_ready, 0);
|
||||
atomic_init(&manager->exiting, false);
|
||||
atomic_init(&manager->mode, isc_taskmgrmode_normal);
|
||||
atomic_store_relaxed(&manager->exclusive_req, false);
|
||||
|
||||
isc_mem_attach(mctx, &manager->mctx);
|
||||
|
|
@ -1010,19 +1009,12 @@ isc_taskmgr_create(isc_mem_t *mctx, unsigned int default_quantum, isc_nm_t *nm,
|
|||
}
|
||||
|
||||
void
|
||||
isc_taskmgr_destroy(isc_taskmgr_t **managerp) {
|
||||
isc_taskmgr_t *manager;
|
||||
isc__taskmgr_shutdown(isc_taskmgr_t *manager) {
|
||||
isc_task_t *task;
|
||||
|
||||
/*
|
||||
* Destroy '*managerp'.
|
||||
*/
|
||||
|
||||
REQUIRE(managerp != NULL);
|
||||
manager = *managerp;
|
||||
REQUIRE(VALID_MANAGER(manager));
|
||||
|
||||
XTHREADTRACE("isc_taskmgr_destroy");
|
||||
XTHREADTRACE("isc_taskmgr_shutdown");
|
||||
/*
|
||||
* Only one non-worker thread may ever call this routine.
|
||||
* If a worker thread wants to initiate shutdown of the
|
||||
|
|
@ -1072,16 +1064,39 @@ isc_taskmgr_destroy(isc_taskmgr_t **managerp) {
|
|||
}
|
||||
|
||||
UNLOCK(&manager->lock);
|
||||
}
|
||||
|
||||
isc_taskmgr_detach(manager);
|
||||
void
|
||||
isc__taskmgr_destroy(isc_taskmgr_t **managerp) {
|
||||
REQUIRE(managerp != NULL && VALID_MANAGER(*managerp));
|
||||
|
||||
isc_taskmgr_t *manager = *managerp;
|
||||
*managerp = NULL;
|
||||
|
||||
XTHREADTRACE("isc_taskmgr_destroy");
|
||||
|
||||
#ifdef ISC_TASK_TRACE
|
||||
int counter = 0;
|
||||
while (isc_refcount_current(&manager->references) > 1 &&
|
||||
counter++ < 1000) {
|
||||
usleep(10 * 1000);
|
||||
}
|
||||
#else
|
||||
while (isc_refcount_current(&manager->references) > 1) {
|
||||
usleep(10 * 1000);
|
||||
}
|
||||
#endif
|
||||
|
||||
REQUIRE(isc_refcount_decrement(&manager->references) == 1);
|
||||
manager_free(manager);
|
||||
}
|
||||
|
||||
void
|
||||
isc_taskmgr_setexcltask(isc_taskmgr_t *mgr, isc_task_t *task) {
|
||||
REQUIRE(VALID_MANAGER(mgr));
|
||||
REQUIRE(VALID_TASK(task));
|
||||
REQUIRE(task->threadid == 0);
|
||||
|
||||
LOCK(&mgr->excl_lock);
|
||||
if (mgr->excl != NULL) {
|
||||
isc_task_detach(&mgr->excl);
|
||||
|
|
@ -1130,7 +1145,7 @@ isc_task_beginexclusive(isc_task_t *task) {
|
|||
return (ISC_R_LOCKBUSY);
|
||||
}
|
||||
|
||||
isc_nm_pause(manager->nm);
|
||||
isc_nm_pause(manager->netmgr);
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
|
@ -1143,7 +1158,7 @@ isc_task_endexclusive(isc_task_t *task) {
|
|||
REQUIRE(task->state == task_state_running);
|
||||
manager = task->manager;
|
||||
|
||||
isc_nm_resume(manager->nm);
|
||||
isc_nm_resume(manager->netmgr);
|
||||
REQUIRE(atomic_compare_exchange_strong(&manager->exclusive_req,
|
||||
&(bool){ true }, false));
|
||||
}
|
||||
|
|
@ -1207,32 +1222,37 @@ isc_task_unpause(isc_task_t *task) {
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
isc_taskmgr_setmode(isc_taskmgr_t *manager, isc_taskmgrmode_t mode) {
|
||||
atomic_store(&manager->mode, mode);
|
||||
}
|
||||
|
||||
isc_taskmgrmode_t
|
||||
isc_taskmgr_mode(isc_taskmgr_t *manager) {
|
||||
return (atomic_load(&manager->mode));
|
||||
}
|
||||
|
||||
void
|
||||
isc_task_setprivilege(isc_task_t *task, bool priv) {
|
||||
REQUIRE(VALID_TASK(task));
|
||||
uint_fast32_t oldflags, newflags;
|
||||
|
||||
oldflags = atomic_load_acquire(&task->flags);
|
||||
do {
|
||||
if (priv) {
|
||||
newflags = oldflags | TASK_F_PRIVILEGED;
|
||||
} else {
|
||||
newflags = oldflags & ~TASK_F_PRIVILEGED;
|
||||
}
|
||||
if (newflags == oldflags) {
|
||||
return;
|
||||
}
|
||||
} while (!atomic_compare_exchange_weak_acq_rel(&task->flags, &oldflags,
|
||||
newflags));
|
||||
atomic_store_release(&task->privileged, priv);
|
||||
}
|
||||
|
||||
bool
|
||||
isc_task_privilege(isc_task_t *task) {
|
||||
isc_task_getprivilege(isc_task_t *task) {
|
||||
REQUIRE(VALID_TASK(task));
|
||||
|
||||
return (TASK_PRIVILEGED(task));
|
||||
}
|
||||
|
||||
bool
|
||||
isc_task_privileged(isc_task_t *task) {
|
||||
REQUIRE(VALID_TASK(task));
|
||||
|
||||
return (isc_taskmgr_mode(task->manager) && TASK_PRIVILEGED(task));
|
||||
}
|
||||
|
||||
bool
|
||||
isc_task_exiting(isc_task_t *task) {
|
||||
REQUIRE(VALID_TASK(task));
|
||||
|
|
@ -1269,21 +1289,6 @@ isc_taskmgr_renderxml(isc_taskmgr_t *mgr, void *writer0) {
|
|||
mgr->default_quantum));
|
||||
TRY0(xmlTextWriterEndElement(writer)); /* default-quantum */
|
||||
|
||||
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks-count"));
|
||||
TRY0(xmlTextWriterWriteFormatString(
|
||||
writer, "%d", (int)atomic_load_relaxed(&mgr->tasks_count)));
|
||||
TRY0(xmlTextWriterEndElement(writer)); /* tasks-count */
|
||||
|
||||
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks-running"));
|
||||
TRY0(xmlTextWriterWriteFormatString(
|
||||
writer, "%d", (int)atomic_load_relaxed(&mgr->tasks_running)));
|
||||
TRY0(xmlTextWriterEndElement(writer)); /* tasks-running */
|
||||
|
||||
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks-ready"));
|
||||
TRY0(xmlTextWriterWriteFormatString(
|
||||
writer, "%d", (int)atomic_load_relaxed(&mgr->tasks_ready)));
|
||||
TRY0(xmlTextWriterEndElement(writer)); /* tasks-ready */
|
||||
|
||||
TRY0(xmlTextWriterEndElement(writer)); /* thread-model */
|
||||
|
||||
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks"));
|
||||
|
|
@ -1373,18 +1378,6 @@ isc_taskmgr_renderjson(isc_taskmgr_t *mgr, void *tasks0) {
|
|||
CHECKMEM(obj);
|
||||
json_object_object_add(tasks, "default-quantum", obj);
|
||||
|
||||
obj = json_object_new_int(atomic_load_relaxed(&mgr->tasks_count));
|
||||
CHECKMEM(obj);
|
||||
json_object_object_add(tasks, "tasks-count", obj);
|
||||
|
||||
obj = json_object_new_int(atomic_load_relaxed(&mgr->tasks_running));
|
||||
CHECKMEM(obj);
|
||||
json_object_object_add(tasks, "tasks-running", obj);
|
||||
|
||||
obj = json_object_new_int(atomic_load_relaxed(&mgr->tasks_ready));
|
||||
CHECKMEM(obj);
|
||||
json_object_object_add(tasks, "tasks-ready", obj);
|
||||
|
||||
array = json_object_new_array();
|
||||
CHECKMEM(array);
|
||||
|
||||
|
|
|
|||
104
lib/isc/task_p.h
Normal file
104
lib/isc/task_p.h
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <isc/mem.h>
|
||||
#include <isc/result.h>
|
||||
#include <isc/task.h>
|
||||
|
||||
isc_result_t
|
||||
isc__taskmgr_create(isc_mem_t *mctx, unsigned int default_quantum, isc_nm_t *nm,
|
||||
isc_taskmgr_t **managerp);
|
||||
/*%<
|
||||
* Create a new task manager.
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
*\li If 'default_quantum' is non-zero, then it will be used as the default
|
||||
* quantum value when tasks are created. If zero, then an implementation
|
||||
* defined default quantum will be used.
|
||||
*
|
||||
*\li If 'nm' is set then netmgr is paused when an exclusive task mode
|
||||
* is requested.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'mctx' is a valid memory context.
|
||||
*
|
||||
*\li managerp != NULL && *managerp == NULL
|
||||
*
|
||||
* Ensures:
|
||||
*
|
||||
*\li On success, '*managerp' will be attached to the newly created task
|
||||
* manager.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li #ISC_R_SUCCESS
|
||||
*\li #ISC_R_NOMEMORY
|
||||
*\li #ISC_R_NOTHREADS No threads could be created.
|
||||
*\li #ISC_R_UNEXPECTED An unexpected error occurred.
|
||||
*\li #ISC_R_SHUTTINGDOWN The non-threaded, shared, task
|
||||
* manager shutting down.
|
||||
*/
|
||||
|
||||
void
|
||||
isc__taskmgr_destroy(isc_taskmgr_t **managerp);
|
||||
/*%<
|
||||
* Destroy '*managerp'.
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
*\li Calling isc_taskmgr_destroy() will shutdown all tasks managed by
|
||||
* *managerp that haven't already been shutdown. The call will block
|
||||
* until all tasks have entered the done state.
|
||||
*
|
||||
*\li isc_taskmgr_destroy() must not be called by a task event action,
|
||||
* because it would block forever waiting for the event action to
|
||||
* complete. An event action that wants to cause task manager shutdown
|
||||
* should request some non-event action thread of execution to do the
|
||||
* shutdown, e.g. by signaling a condition variable or using
|
||||
* isc_app_shutdown().
|
||||
*
|
||||
*\li Task manager references are not reference counted, so the caller
|
||||
* must ensure that no attempt will be made to use the manager after
|
||||
* isc_taskmgr_destroy() returns.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li '*managerp' is a valid task manager.
|
||||
*
|
||||
*\li 'isc__taskmgr_shutdown()' and isc__netmgr_shutdown() have been
|
||||
* called.
|
||||
*/
|
||||
|
||||
void
|
||||
isc__taskmgr_shutdown(isc_taskmgr_t *manager);
|
||||
/*%>
|
||||
* Shutdown 'manager'.
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
*\li Calling isc__taskmgr_shutdown() will shut down all tasks managed by
|
||||
* *managerp that haven't already been shut down.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'manager' is a valid task manager.
|
||||
*
|
||||
*\li isc_taskmgr_destroy() has not be called previously on '*managerp'.
|
||||
*
|
||||
* Ensures:
|
||||
*
|
||||
*\li All resources used by the task manager, and any tasks it managed,
|
||||
* have been freed.
|
||||
*/
|
||||
|
|
@ -10,7 +10,7 @@ LDADD += \
|
|||
|
||||
check_LTLIBRARIES = libisctest.la
|
||||
libisctest_la_SOURCES = \
|
||||
../unix/socket_p.h \
|
||||
../socket_p.h \
|
||||
isctest.c \
|
||||
isctest.h \
|
||||
uv_wrap.h
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
#include "../netmgr/netmgr-int.h"
|
||||
#include "../netmgr/uv-compat.c"
|
||||
#include "../netmgr/uv-compat.h"
|
||||
#include "../netmgr_p.h"
|
||||
#include "isctest.h"
|
||||
|
||||
#define MAX_NM 2
|
||||
|
|
@ -319,7 +320,7 @@ nm_setup(void **state) {
|
|||
|
||||
nm = isc_mem_get(test_mctx, MAX_NM * sizeof(nm[0]));
|
||||
for (size_t i = 0; i < MAX_NM; i++) {
|
||||
nm[i] = isc_nm_start(test_mctx, nworkers);
|
||||
isc__netmgr_create(test_mctx, nworkers, &nm[i]);
|
||||
assert_non_null(nm[i]);
|
||||
}
|
||||
|
||||
|
|
@ -339,7 +340,7 @@ nm_teardown(void **state) {
|
|||
isc_nm_t **nm = (isc_nm_t **)*state;
|
||||
|
||||
for (size_t i = 0; i < MAX_NM; i++) {
|
||||
isc_nm_destroy(&nm[i]);
|
||||
isc__netmgr_destroy(&nm[i]);
|
||||
assert_null(nm[i]);
|
||||
}
|
||||
isc_mem_put(test_mctx, nm, MAX_NM * sizeof(nm[0]));
|
||||
|
|
@ -498,7 +499,7 @@ doh_noop(void **state) {
|
|||
.length = send_msg.len },
|
||||
noop_read_cb, NULL, atomic_load(&use_TLS), 30000);
|
||||
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
assert_int_equal(0, atomic_load(&csends));
|
||||
assert_int_equal(0, atomic_load(&creads));
|
||||
|
|
@ -545,7 +546,7 @@ doh_noresponse(void **state) {
|
|||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -666,7 +667,7 @@ doh_timeout_recovery(void **state) {
|
|||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -792,7 +793,7 @@ doh_recv_one(void **state) {
|
|||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
X(csends);
|
||||
X(creads);
|
||||
|
|
@ -913,7 +914,7 @@ doh_recv_two(void **state) {
|
|||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
X(csends);
|
||||
X(creads);
|
||||
|
|
@ -979,7 +980,7 @@ doh_recv_send(void **state) {
|
|||
isc_thread_join(threads[i], NULL);
|
||||
}
|
||||
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
|
|
@ -1050,7 +1051,7 @@ doh_recv_half_send(void **state) {
|
|||
isc_thread_yield();
|
||||
}
|
||||
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
for (size_t i = 0; i < nthreads; i++) {
|
||||
isc_thread_join(threads[i], NULL);
|
||||
|
|
@ -1134,7 +1135,7 @@ doh_half_recv_send(void **state) {
|
|||
isc_thread_join(threads[i], NULL);
|
||||
}
|
||||
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
X(csends);
|
||||
X(creads);
|
||||
|
|
@ -1202,7 +1203,7 @@ doh_half_recv_half_send(void **state) {
|
|||
isc_thread_yield();
|
||||
}
|
||||
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include <isc/buffer.h>
|
||||
#include <isc/hash.h>
|
||||
#include <isc/hp.h>
|
||||
#include <isc/managers.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/os.h>
|
||||
#include <isc/socket.h>
|
||||
|
|
@ -58,18 +59,10 @@ cleanup_managers(void) {
|
|||
isc_task_shutdown(maintask);
|
||||
isc_task_destroy(&maintask);
|
||||
}
|
||||
if (socketmgr != NULL) {
|
||||
isc_socketmgr_destroy(&socketmgr);
|
||||
}
|
||||
if (taskmgr != NULL) {
|
||||
isc_taskmgr_destroy(&taskmgr);
|
||||
}
|
||||
if (netmgr != NULL) {
|
||||
isc_nm_destroy(&netmgr);
|
||||
}
|
||||
if (timermgr != NULL) {
|
||||
isc_timermgr_destroy(&timermgr);
|
||||
}
|
||||
isc_managers_destroy(netmgr == NULL ? NULL : &netmgr,
|
||||
taskmgr == NULL ? NULL : &taskmgr,
|
||||
timermgr == NULL ? NULL : &timermgr,
|
||||
socketmgr == NULL ? NULL : &socketmgr);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
|
|
@ -87,14 +80,12 @@ create_managers(unsigned int workers) {
|
|||
INSIST(workers != 0);
|
||||
|
||||
isc_hp_init(6 * workers);
|
||||
isc_managers_create(test_mctx, workers, 0, 0, &netmgr, &taskmgr,
|
||||
&timermgr, &socketmgr);
|
||||
|
||||
netmgr = isc_nm_start(test_mctx, workers);
|
||||
CHECK(isc_taskmgr_create(test_mctx, 0, netmgr, &taskmgr));
|
||||
CHECK(isc_task_create(taskmgr, 0, &maintask));
|
||||
CHECK(isc_task_create_bound(taskmgr, 0, &maintask, 0));
|
||||
isc_taskmgr_setexcltask(taskmgr, maintask);
|
||||
|
||||
CHECK(isc_timermgr_create(test_mctx, &timermgr));
|
||||
CHECK(isc_socketmgr_create(test_mctx, &socketmgr));
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
cleanup:
|
||||
|
|
@ -150,9 +141,6 @@ isc_test_end(void) {
|
|||
if (maintask != NULL) {
|
||||
isc_task_detach(&maintask);
|
||||
}
|
||||
if (taskmgr != NULL) {
|
||||
isc_taskmgr_destroy(&taskmgr);
|
||||
}
|
||||
|
||||
cleanup_managers();
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include "../netmgr/udp.c"
|
||||
#include "../netmgr/uv-compat.c"
|
||||
#include "../netmgr/uv-compat.h"
|
||||
#include "../netmgr_p.h"
|
||||
#include "isctest.h"
|
||||
|
||||
typedef void (*stream_connect_function)(isc_nm_t *nm);
|
||||
|
|
@ -335,12 +336,12 @@ nm_setup(void **state __attribute__((unused))) {
|
|||
return (-1);
|
||||
}
|
||||
|
||||
listen_nm = isc_nm_start(test_mctx, workers);
|
||||
isc__netmgr_create(test_mctx, workers, &listen_nm);
|
||||
assert_non_null(listen_nm);
|
||||
isc_nm_settimeouts(listen_nm, T_INIT, T_IDLE, T_KEEPALIVE,
|
||||
T_ADVERTISED);
|
||||
|
||||
connect_nm = isc_nm_start(test_mctx, workers);
|
||||
isc__netmgr_create(test_mctx, workers, &connect_nm);
|
||||
assert_non_null(connect_nm);
|
||||
isc_nm_settimeouts(connect_nm, T_INIT, T_IDLE, T_KEEPALIVE,
|
||||
T_ADVERTISED);
|
||||
|
|
@ -358,10 +359,10 @@ static int
|
|||
nm_teardown(void **state __attribute__((unused))) {
|
||||
UNUSED(state);
|
||||
|
||||
isc_nm_destroy(&connect_nm);
|
||||
isc__netmgr_destroy(&connect_nm);
|
||||
assert_null(connect_nm);
|
||||
|
||||
isc_nm_destroy(&listen_nm);
|
||||
isc__netmgr_destroy(&listen_nm);
|
||||
assert_null(listen_nm);
|
||||
|
||||
WAIT_FOR_EQ(active_cconnects, 0);
|
||||
|
|
@ -677,7 +678,7 @@ mock_udpconnect_uv_udp_open(void **state __attribute__((unused))) {
|
|||
isc_nm_udpconnect(connect_nm, (isc_nmiface_t *)&udp_connect_addr,
|
||||
(isc_nmiface_t *)&udp_listen_addr, connect_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
RESET_RETURN;
|
||||
}
|
||||
|
|
@ -691,7 +692,7 @@ mock_udpconnect_uv_udp_bind(void **state __attribute__((unused))) {
|
|||
isc_nm_udpconnect(connect_nm, (isc_nmiface_t *)&udp_connect_addr,
|
||||
(isc_nmiface_t *)&udp_listen_addr, connect_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
RESET_RETURN;
|
||||
}
|
||||
|
|
@ -706,7 +707,7 @@ mock_udpconnect_uv_udp_connect(void **state __attribute__((unused))) {
|
|||
isc_nm_udpconnect(connect_nm, (isc_nmiface_t *)&udp_connect_addr,
|
||||
(isc_nmiface_t *)&udp_listen_addr, connect_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
RESET_RETURN;
|
||||
}
|
||||
|
|
@ -721,7 +722,7 @@ mock_udpconnect_uv_recv_buffer_size(void **state __attribute__((unused))) {
|
|||
isc_nm_udpconnect(connect_nm, (isc_nmiface_t *)&udp_connect_addr,
|
||||
(isc_nmiface_t *)&udp_listen_addr, connect_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
RESET_RETURN;
|
||||
}
|
||||
|
|
@ -735,7 +736,7 @@ mock_udpconnect_uv_send_buffer_size(void **state __attribute__((unused))) {
|
|||
isc_nm_udpconnect(connect_nm, (isc_nmiface_t *)&udp_connect_addr,
|
||||
(isc_nmiface_t *)&udp_listen_addr, connect_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
RESET_RETURN;
|
||||
}
|
||||
|
|
@ -758,7 +759,7 @@ udp_noop(void **state __attribute__((unused))) {
|
|||
isc_nm_udpconnect(connect_nm, (isc_nmiface_t *)&udp_connect_addr,
|
||||
(isc_nmiface_t *)&udp_listen_addr, connect_connect_cb,
|
||||
NULL, T_CONNECT, 0);
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
atomic_assert_int_eq(cconnects, 0);
|
||||
atomic_assert_int_eq(csends, 0);
|
||||
|
|
@ -787,7 +788,7 @@ udp_noresponse(void **state __attribute__((unused))) {
|
|||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
X(cconnects);
|
||||
X(csends);
|
||||
|
|
@ -860,7 +861,7 @@ udp_timeout_recovery(void **state __attribute__((unused))) {
|
|||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -889,7 +890,7 @@ udp_recv_one(void **state __attribute__((unused))) {
|
|||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
X(cconnects);
|
||||
X(csends);
|
||||
|
|
@ -937,7 +938,7 @@ udp_recv_two(void **state __attribute__((unused))) {
|
|||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
X(cconnects);
|
||||
X(csends);
|
||||
|
|
@ -980,7 +981,7 @@ udp_recv_send(void **state __attribute__((unused))) {
|
|||
isc_thread_join(threads[i], NULL);
|
||||
}
|
||||
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
|
|
@ -1020,7 +1021,7 @@ udp_recv_half_send(void **state __attribute__((unused))) {
|
|||
WAIT_FOR_GE(ssends, esends / 2);
|
||||
WAIT_FOR_GE(creads, esends / 2);
|
||||
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
DONE();
|
||||
for (size_t i = 0; i < workers; i++) {
|
||||
|
|
@ -1073,7 +1074,7 @@ udp_half_recv_send(void **state __attribute__((unused))) {
|
|||
/* Try to send a little while longer */
|
||||
isc_test_nap((esends / 2) * 10000);
|
||||
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
DONE();
|
||||
for (size_t i = 0; i < workers; i++) {
|
||||
|
|
@ -1115,7 +1116,7 @@ udp_half_recv_half_send(void **state __attribute__((unused))) {
|
|||
WAIT_FOR_GE(ssends, esends / 2);
|
||||
WAIT_FOR_GE(creads, esends / 2);
|
||||
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
|
|
@ -1218,7 +1219,7 @@ stream_noop(void **state __attribute__((unused))) {
|
|||
connect_readcb = NULL;
|
||||
isc_refcount_increment0(&active_cconnects);
|
||||
stream_connect(connect_connect_cb, NULL, T_CONNECT, 0);
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
atomic_assert_int_eq(cconnects, 0);
|
||||
atomic_assert_int_eq(csends, 0);
|
||||
|
|
@ -1244,7 +1245,7 @@ stream_noresponse(void **state __attribute__((unused))) {
|
|||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
X(cconnects);
|
||||
X(csends);
|
||||
|
|
@ -1294,7 +1295,7 @@ stream_timeout_recovery(void **state __attribute__((unused))) {
|
|||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1322,7 +1323,7 @@ stream_recv_one(void **state __attribute__((unused))) {
|
|||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
X(cconnects);
|
||||
X(csends);
|
||||
|
|
@ -1367,7 +1368,7 @@ stream_recv_two(void **state __attribute__((unused))) {
|
|||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
X(cconnects);
|
||||
X(csends);
|
||||
|
|
@ -1416,7 +1417,7 @@ stream_recv_send(void **state __attribute__((unused))) {
|
|||
isc_thread_join(threads[i], NULL);
|
||||
}
|
||||
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
|
|
@ -1462,7 +1463,7 @@ stream_recv_half_send(void **state __attribute__((unused))) {
|
|||
WAIT_FOR_GE(ssends, esends / 2);
|
||||
WAIT_FOR_GE(creads, esends / 2);
|
||||
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
DONE();
|
||||
for (size_t i = 0; i < workers; i++) {
|
||||
|
|
@ -1521,7 +1522,7 @@ stream_half_recv_send(void **state __attribute__((unused))) {
|
|||
/* Try to send a little while longer */
|
||||
isc_test_nap((esends / 2) * 10000);
|
||||
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
DONE();
|
||||
for (size_t i = 0; i < workers; i++) {
|
||||
|
|
@ -1569,7 +1570,7 @@ stream_half_recv_half_send(void **state __attribute__((unused))) {
|
|||
WAIT_FOR_GE(ssends, esends / 2);
|
||||
WAIT_FOR_GE(creads, esends / 2);
|
||||
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
|
|
@ -1767,7 +1768,7 @@ tcpdns_noop(void **state __attribute__((unused))) {
|
|||
isc_nm_tcpdnsconnect(connect_nm, (isc_nmiface_t *)&tcp_connect_addr,
|
||||
(isc_nmiface_t *)&tcp_listen_addr,
|
||||
connect_connect_cb, NULL, T_CONNECT, 0);
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
atomic_assert_int_eq(cconnects, 0);
|
||||
atomic_assert_int_eq(csends, 0);
|
||||
|
|
@ -1801,7 +1802,7 @@ tcpdns_noresponse(void **state __attribute__((unused))) {
|
|||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
X(cconnects);
|
||||
X(csends);
|
||||
|
|
@ -1856,7 +1857,7 @@ tcpdns_timeout_recovery(void **state __attribute__((unused))) {
|
|||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1886,7 +1887,7 @@ tcpdns_recv_one(void **state __attribute__((unused))) {
|
|||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
X(cconnects);
|
||||
X(csends);
|
||||
|
|
@ -1936,7 +1937,7 @@ tcpdns_recv_two(void **state __attribute__((unused))) {
|
|||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
X(cconnects);
|
||||
X(csends);
|
||||
|
|
@ -1980,7 +1981,7 @@ tcpdns_recv_send(void **state __attribute__((unused))) {
|
|||
isc_thread_join(threads[i], NULL);
|
||||
}
|
||||
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
|
|
@ -2021,7 +2022,7 @@ tcpdns_recv_half_send(void **state __attribute__((unused))) {
|
|||
WAIT_FOR_GE(ssends, esends / 2);
|
||||
WAIT_FOR_GE(creads, esends / 2);
|
||||
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
DONE();
|
||||
for (size_t i = 0; i < workers; i++) {
|
||||
|
|
@ -2075,7 +2076,7 @@ tcpdns_half_recv_send(void **state __attribute__((unused))) {
|
|||
/* Try to send a little while longer */
|
||||
isc_test_nap((esends / 2) * 10000);
|
||||
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
DONE();
|
||||
for (size_t i = 0; i < workers; i++) {
|
||||
|
|
@ -2118,7 +2119,7 @@ tcpdns_half_recv_half_send(void **state __attribute__((unused))) {
|
|||
WAIT_FOR_GE(ssends, esends / 2);
|
||||
WAIT_FOR_GE(creads, esends / 2);
|
||||
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
|
|
@ -2355,7 +2356,7 @@ tlsdns_noop(void **state __attribute__((unused))) {
|
|||
connect_connect_cb, NULL, T_CONNECT, 0,
|
||||
tcp_connect_tlsctx);
|
||||
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
atomic_assert_int_eq(cconnects, 0);
|
||||
atomic_assert_int_eq(csends, 0);
|
||||
|
|
@ -2391,7 +2392,7 @@ tlsdns_noresponse(void **state __attribute__((unused))) {
|
|||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
X(cconnects);
|
||||
X(csends);
|
||||
|
|
@ -2452,7 +2453,7 @@ tlsdns_timeout_recovery(void **state __attribute__((unused))) {
|
|||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -2484,7 +2485,7 @@ tlsdns_recv_one(void **state __attribute__((unused))) {
|
|||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
X(cconnects);
|
||||
X(csends);
|
||||
|
|
@ -2537,7 +2538,7 @@ tlsdns_recv_two(void **state __attribute__((unused))) {
|
|||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
X(cconnects);
|
||||
X(csends);
|
||||
|
|
@ -2582,7 +2583,7 @@ tlsdns_recv_send(void **state __attribute__((unused))) {
|
|||
isc_thread_join(threads[i], NULL);
|
||||
}
|
||||
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
|
|
@ -2624,7 +2625,7 @@ tlsdns_recv_half_send(void **state __attribute__((unused))) {
|
|||
WAIT_FOR_GE(ssends, esends / 2);
|
||||
WAIT_FOR_GE(creads, esends / 2);
|
||||
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
DONE();
|
||||
for (size_t i = 0; i < workers; i++) {
|
||||
|
|
@ -2679,7 +2680,7 @@ tlsdns_half_recv_send(void **state __attribute__((unused))) {
|
|||
/* Try to send a little while longer */
|
||||
isc_test_nap((esends / 2) * 10000);
|
||||
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
|
||||
DONE();
|
||||
for (size_t i = 0; i < workers; i++) {
|
||||
|
|
@ -2723,7 +2724,7 @@ tlsdns_half_recv_half_send(void **state __attribute__((unused))) {
|
|||
WAIT_FOR_GE(ssends, esends / 2);
|
||||
WAIT_FOR_GE(creads, esends / 2);
|
||||
|
||||
isc_nm_closedown(connect_nm);
|
||||
isc__netmgr_shutdown(connect_nm);
|
||||
isc_nm_stoplistening(listen_sock);
|
||||
isc_nmsocket_close(&listen_sock);
|
||||
assert_null(listen_sock);
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
/*! \file */
|
||||
|
||||
#if HAVE_CMOCKA
|
||||
#include <inttypes.h>
|
||||
#include <sched.h> /* IWYU pragma: keep */
|
||||
#include <setjmp.h>
|
||||
#include <stdarg.h>
|
||||
|
|
@ -30,7 +31,7 @@
|
|||
#include <isc/socket.h>
|
||||
#include <isc/task.h>
|
||||
|
||||
#include "../unix/socket_p.h"
|
||||
#include "../socket_p.h"
|
||||
#include "isctest.h"
|
||||
|
||||
static bool recv_dscp;
|
||||
|
|
@ -79,14 +80,14 @@ _teardown(void **state) {
|
|||
|
||||
typedef struct {
|
||||
atomic_bool done;
|
||||
atomic_uintptr_t socket;
|
||||
isc_result_t result;
|
||||
isc_socket_t *socket;
|
||||
} completion_t;
|
||||
|
||||
static void
|
||||
completion_init(completion_t *completion) {
|
||||
atomic_init(&completion->done, false);
|
||||
completion->socket = NULL;
|
||||
atomic_init(&completion->socket, (uintptr_t)NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -99,7 +100,7 @@ accept_done(isc_task_t *task, isc_event_t *event) {
|
|||
completion->result = nevent->result;
|
||||
atomic_store(&completion->done, true);
|
||||
if (completion->result == ISC_R_SUCCESS) {
|
||||
completion->socket = nevent->newsocket;
|
||||
atomic_store(&completion->socket, (uintptr_t)nevent->newsocket);
|
||||
}
|
||||
|
||||
isc_event_free(&event);
|
||||
|
|
@ -136,35 +137,24 @@ event_done(isc_task_t *task, isc_event_t *event) {
|
|||
isc_event_free(&event);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
static void
|
||||
waitfor(completion_t *completion) {
|
||||
int i = 0;
|
||||
while (!atomic_load(&completion->done) && i++ < 5000) {
|
||||
isc_test_nap(1000);
|
||||
isc_test_nap(10000);
|
||||
}
|
||||
if (atomic_load(&completion->done)) {
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
return (ISC_R_FAILURE);
|
||||
assert_true(atomic_load(&completion->done));
|
||||
}
|
||||
|
||||
static void
|
||||
waitbody(void) {
|
||||
isc_test_nap(1000);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
waitfor2(completion_t *c1, completion_t *c2) {
|
||||
int i = 0;
|
||||
|
||||
while (!(atomic_load(&c1->done) && atomic_load(&c2->done)) &&
|
||||
i++ < 5000) {
|
||||
waitbody();
|
||||
isc_test_nap(10000);
|
||||
}
|
||||
if (atomic_load(&c1->done) && atomic_load(&c2->done)) {
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
return (ISC_R_FAILURE);
|
||||
assert_true(atomic_load(&c1->done) && atomic_load(&c2->done));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -525,7 +515,7 @@ tcp_dscp_v4_test(void **state) {
|
|||
assert_int_equal(completion.result, ISC_R_SUCCESS);
|
||||
assert_true(atomic_load(&completion2.done));
|
||||
assert_int_equal(completion2.result, ISC_R_SUCCESS);
|
||||
s3 = completion2.socket;
|
||||
s3 = (isc_socket_t *)atomic_load(&completion2.socket);
|
||||
|
||||
isc_socket_dscp(s2, 056); /* EF */
|
||||
|
||||
|
|
@ -613,7 +603,7 @@ tcp_dscp_v6_test(void **state) {
|
|||
assert_int_equal(completion.result, ISC_R_SUCCESS);
|
||||
assert_true(atomic_load(&completion2.done));
|
||||
assert_int_equal(completion2.result, ISC_R_SUCCESS);
|
||||
s3 = completion2.socket;
|
||||
s3 = (isc_socket_t *)atomic_load(&completion2.socket);
|
||||
|
||||
isc_socket_dscp(s2, 056); /* EF */
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include <isc/cmocka.h>
|
||||
#include <isc/commandline.h>
|
||||
#include <isc/condition.h>
|
||||
#include <isc/managers.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/platform.h>
|
||||
#include <isc/print.h>
|
||||
|
|
@ -215,18 +216,19 @@ privileged_events(void **state) {
|
|||
* queue without things happening while we do it.
|
||||
*/
|
||||
isc_nm_pause(netmgr);
|
||||
isc_taskmgr_setmode(taskmgr, isc_taskmgrmode_privileged);
|
||||
|
||||
result = isc_task_create(taskmgr, 0, &task1);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
isc_task_setname(task1, "privileged", NULL);
|
||||
assert_false(isc_task_privilege(task1));
|
||||
assert_false(isc_task_getprivilege(task1));
|
||||
isc_task_setprivilege(task1, true);
|
||||
assert_true(isc_task_privilege(task1));
|
||||
assert_true(isc_task_getprivilege(task1));
|
||||
|
||||
result = isc_task_create(taskmgr, 0, &task2);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
isc_task_setname(task2, "normal", NULL);
|
||||
assert_false(isc_task_privilege(task2));
|
||||
assert_false(isc_task_getprivilege(task2));
|
||||
|
||||
/* First event: privileged */
|
||||
event = isc_event_allocate(test_mctx, task1, ISC_TASKEVENT_TEST, set,
|
||||
|
|
@ -295,7 +297,7 @@ privileged_events(void **state) {
|
|||
assert_int_equal(atomic_load(&counter), 6);
|
||||
|
||||
isc_task_setprivilege(task1, false);
|
||||
assert_false(isc_task_privilege(task1));
|
||||
assert_false(isc_task_getprivilege(task1));
|
||||
|
||||
isc_task_destroy(&task1);
|
||||
assert_null(task1);
|
||||
|
|
@ -329,18 +331,19 @@ privilege_drop(void **state) {
|
|||
* without things happening while we do it.
|
||||
*/
|
||||
isc_nm_pause(netmgr);
|
||||
isc_taskmgr_setmode(taskmgr, isc_taskmgrmode_privileged);
|
||||
|
||||
result = isc_task_create(taskmgr, 0, &task1);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
isc_task_setname(task1, "privileged", NULL);
|
||||
assert_false(isc_task_privilege(task1));
|
||||
assert_false(isc_task_getprivilege(task1));
|
||||
isc_task_setprivilege(task1, true);
|
||||
assert_true(isc_task_privilege(task1));
|
||||
assert_true(isc_task_getprivilege(task1));
|
||||
|
||||
result = isc_task_create(taskmgr, 0, &task2);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
isc_task_setname(task2, "normal", NULL);
|
||||
assert_false(isc_task_privilege(task2));
|
||||
assert_false(isc_task_getprivilege(task2));
|
||||
|
||||
/* First event: privileged */
|
||||
event = isc_event_allocate(test_mctx, task1, ISC_TASKEVENT_TEST,
|
||||
|
|
@ -705,12 +708,16 @@ task_exclusive(void **state) {
|
|||
|
||||
tasks[i] = NULL;
|
||||
|
||||
result = isc_task_create(taskmgr, 0, &tasks[i]);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
/* task chosen from the middle of the range */
|
||||
if (i == 6) {
|
||||
/* task chosen from the middle of the range */
|
||||
result = isc_task_create_bound(taskmgr, 0, &tasks[i],
|
||||
0);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
isc_taskmgr_setexcltask(taskmgr, tasks[6]);
|
||||
} else {
|
||||
result = isc_task_create(taskmgr, 0, &tasks[i]);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
v = isc_mem_get(test_mctx, sizeof *v);
|
||||
|
|
@ -784,7 +791,6 @@ maxtask_cb(isc_task_t *task, isc_event_t *event) {
|
|||
static void
|
||||
manytasks(void **state) {
|
||||
isc_mem_t *mctx = NULL;
|
||||
isc_result_t result;
|
||||
isc_event_t *event = NULL;
|
||||
uintptr_t ntasks = 10000;
|
||||
|
||||
|
|
@ -801,9 +807,7 @@ manytasks(void **state) {
|
|||
isc_mem_debugging = ISC_MEM_DEBUGRECORD;
|
||||
isc_mem_create(&mctx);
|
||||
|
||||
netmgr = isc_nm_start(mctx, 4);
|
||||
result = isc_taskmgr_create(mctx, 0, netmgr, &taskmgr);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
isc_managers_create(mctx, 4, 0, 0, &netmgr, &taskmgr, NULL, NULL);
|
||||
|
||||
atomic_init(&done, false);
|
||||
|
||||
|
|
@ -818,8 +822,8 @@ manytasks(void **state) {
|
|||
}
|
||||
UNLOCK(&lock);
|
||||
|
||||
isc_taskmgr_destroy(&taskmgr);
|
||||
isc_nm_destroy(&netmgr);
|
||||
isc_managers_destroy(&netmgr, &taskmgr, NULL, NULL);
|
||||
|
||||
isc_mem_destroy(&mctx);
|
||||
isc_condition_destroy(&cv);
|
||||
isc_mutex_destroy(&lock);
|
||||
|
|
@ -899,7 +903,7 @@ sd_event2(isc_task_t *task, isc_event_t *event) {
|
|||
}
|
||||
|
||||
static void
|
||||
shutdown(void **state) {
|
||||
task_shutdown(void **state) {
|
||||
isc_result_t result;
|
||||
isc_eventtype_t event_type;
|
||||
isc_event_t *event = NULL;
|
||||
|
|
@ -1545,7 +1549,8 @@ main(int argc, char **argv) {
|
|||
cmocka_unit_test_setup_teardown(purgeevent_notpurge, _setup,
|
||||
_teardown),
|
||||
cmocka_unit_test_setup_teardown(purgerange, _setup, _teardown),
|
||||
cmocka_unit_test_setup_teardown(shutdown, _setup4, _teardown),
|
||||
cmocka_unit_test_setup_teardown(task_shutdown, _setup4,
|
||||
_teardown),
|
||||
cmocka_unit_test_setup_teardown(task_exclusive, _setup4,
|
||||
_teardown),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -164,9 +164,9 @@ set_privilege(void **state) {
|
|||
assert_true(VALID_TASK(task2));
|
||||
assert_true(VALID_TASK(task3));
|
||||
|
||||
assert_true(isc_task_privilege(task1));
|
||||
assert_true(isc_task_privilege(task2));
|
||||
assert_true(isc_task_privilege(task3));
|
||||
assert_true(isc_task_getprivilege(task1));
|
||||
assert_true(isc_task_getprivilege(task2));
|
||||
assert_true(isc_task_getprivilege(task3));
|
||||
|
||||
isc_task_destroy(&task1);
|
||||
isc_task_destroy(&task2);
|
||||
|
|
|
|||
|
|
@ -29,9 +29,7 @@
|
|||
#include <isc/timer.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#ifdef OPENSSL_LEAKS
|
||||
#include <openssl/err.h>
|
||||
#endif /* ifdef OPENSSL_LEAKS */
|
||||
#include "timer_p.h"
|
||||
|
||||
#ifdef ISC_TIMER_TRACE
|
||||
#define XTRACE(s) fprintf(stderr, "%s\n", (s))
|
||||
|
|
@ -630,10 +628,6 @@ static isc_threadresult_t
|
|||
}
|
||||
UNLOCK(&manager->lock);
|
||||
|
||||
#ifdef OPENSSL_LEAKS
|
||||
ERR_remove_state(0);
|
||||
#endif /* ifdef OPENSSL_LEAKS */
|
||||
|
||||
return ((isc_threadresult_t)0);
|
||||
}
|
||||
|
||||
|
|
@ -663,7 +657,7 @@ set_index(void *what, unsigned int index) {
|
|||
}
|
||||
|
||||
isc_result_t
|
||||
isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) {
|
||||
isc__timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) {
|
||||
isc_timermgr_t *manager;
|
||||
isc_result_t result;
|
||||
|
||||
|
|
@ -707,7 +701,7 @@ isc_timermgr_poke(isc_timermgr_t *manager) {
|
|||
}
|
||||
|
||||
void
|
||||
isc_timermgr_destroy(isc_timermgr_t **managerp) {
|
||||
isc__timermgr_destroy(isc_timermgr_t **managerp) {
|
||||
isc_timermgr_t *manager;
|
||||
|
||||
/*
|
||||
|
|
|
|||
65
lib/isc/timer_p.h
Normal file
65
lib/isc/timer_p.h
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <isc/mem.h>
|
||||
#include <isc/result.h>
|
||||
#include <isc/timer.h>
|
||||
|
||||
isc_result_t
|
||||
isc__timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp);
|
||||
/*%<
|
||||
* Create a timer manager.
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
*\li All memory will be allocated in memory context 'mctx'.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 'mctx' is a valid memory context.
|
||||
*
|
||||
*\li 'managerp' points to a NULL isc_timermgr_t.
|
||||
*
|
||||
* Ensures:
|
||||
*
|
||||
*\li '*managerp' is a valid isc_timermgr_t.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li Success
|
||||
*\li No memory
|
||||
*\li Unexpected error
|
||||
*/
|
||||
|
||||
void
|
||||
isc__timermgr_destroy(isc_timermgr_t **managerp);
|
||||
/*%<
|
||||
* Destroy a timer manager.
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
*\li This routine blocks until there are no timers left in the manager,
|
||||
* so if the caller holds any timer references using the manager, it
|
||||
* must detach them before calling isc_timermgr_destroy() or it will
|
||||
* block forever.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li '*managerp' is a valid isc_timermgr_t.
|
||||
*
|
||||
* Ensures:
|
||||
*
|
||||
*\li *managerp == NULL
|
||||
*
|
||||
*\li All resources used by the manager have been freed.
|
||||
*/
|
||||
|
|
@ -74,6 +74,7 @@
|
|||
#include <netinet/tcp.h>
|
||||
|
||||
#include "errno2result.h"
|
||||
#include "socket_p.h"
|
||||
|
||||
#ifdef ENABLE_TCP_FASTOPEN
|
||||
#include <netinet/tcp.h>
|
||||
|
|
@ -3752,12 +3753,7 @@ cleanup_thread(isc_mem_t *mctx, isc__socketthread_t *thread) {
|
|||
}
|
||||
|
||||
isc_result_t
|
||||
isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) {
|
||||
return (isc_socketmgr_create2(mctx, managerp, 0, 1));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
|
||||
isc__socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp,
|
||||
unsigned int maxsocks, int nthreads) {
|
||||
int i;
|
||||
isc_socketmgr_t *manager;
|
||||
|
|
@ -3828,7 +3824,7 @@ isc_socketmgr_setstats(isc_socketmgr_t *manager, isc_stats_t *stats) {
|
|||
}
|
||||
|
||||
void
|
||||
isc_socketmgr_destroy(isc_socketmgr_t **managerp) {
|
||||
isc__socketmgr_destroy(isc_socketmgr_t **managerp) {
|
||||
isc_socketmgr_t *manager;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef ISC_SOCKET_P_H
|
||||
#define ISC_SOCKET_P_H
|
||||
|
||||
/*! \file */
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
typedef struct isc_socketwait isc_socketwait_t;
|
||||
int
|
||||
isc__socketmgr_waitevents(isc_socketmgr_t *, struct timeval *,
|
||||
isc_socketwait_t **);
|
||||
isc_result_t
|
||||
isc__socketmgr_dispatch(isc_socketmgr_t *, isc_socketwait_t *);
|
||||
#endif /* ISC_SOCKET_P_H */
|
||||
|
|
@ -96,14 +96,12 @@ isc_socket_send
|
|||
isc_socket_sendto
|
||||
isc_socket_sendto2
|
||||
isc_socket_setname
|
||||
isc_socketmgr_create
|
||||
isc_socketmgr_create2
|
||||
isc_socketmgr_destroy
|
||||
isc_socketmgr_getmaxsockets
|
||||
isc_socketmgr_setreserved
|
||||
isc_socketmgr_setstats
|
||||
isc_task_getname
|
||||
isc_task_gettag
|
||||
isc_task_ready
|
||||
isc_task_run
|
||||
isc_task_unsendrange
|
||||
isc_taskmgr_attach
|
||||
|
|
@ -352,6 +350,8 @@ isc_logconfig_create
|
|||
isc_logconfig_destroy
|
||||
isc_logconfig_use
|
||||
isc_logfile_roll
|
||||
isc_managers_create
|
||||
isc_managers_destroy
|
||||
isc_md_new
|
||||
isc_md_init
|
||||
isc_md_reset
|
||||
|
|
@ -452,8 +452,6 @@ isc_nmhandle_peeraddr
|
|||
isc_nmhandle_setdata
|
||||
isc_nmhandle_settimeout
|
||||
isc_nm_cancelread
|
||||
isc_nm_closedown
|
||||
isc_nm_destroy
|
||||
isc_nm_detach
|
||||
isc_nm_http_endpoint
|
||||
isc_nm_httpconnect
|
||||
|
|
@ -469,7 +467,6 @@ isc_nm_read
|
|||
isc_nm_resumeread
|
||||
isc_nm_send
|
||||
isc_nm_setstats
|
||||
isc_nm_start
|
||||
isc_nm_stoplistening
|
||||
isc_nm_tcpconnect
|
||||
isc_nm_tcpdnsconnect
|
||||
|
|
@ -638,9 +635,10 @@ isc_task_endexclusive
|
|||
isc_task_exiting
|
||||
isc_task_getcurrenttime
|
||||
isc_task_getcurrenttimex
|
||||
isc_task_getprivilege
|
||||
isc_task_onshutdown
|
||||
isc_task_pause
|
||||
isc_task_privilege
|
||||
isc_task_privileged
|
||||
isc_task_purge
|
||||
isc_task_purgeevent
|
||||
isc_task_purgerange
|
||||
|
|
@ -653,9 +651,8 @@ isc_task_setprivilege
|
|||
isc_task_shutdown
|
||||
isc_task_unpause
|
||||
isc_task_unsend
|
||||
isc_taskmgr_create
|
||||
isc_taskmgr_destroy
|
||||
isc_taskmgr_excltask
|
||||
isc_taskmgr_mode
|
||||
@IF NOTYET
|
||||
isc_taskmgr_renderjson
|
||||
@END NOTYET
|
||||
|
|
@ -663,6 +660,7 @@ isc_taskmgr_renderjson
|
|||
isc_taskmgr_renderxml
|
||||
@END LIBXML2
|
||||
isc_taskmgr_setexcltask
|
||||
isc_taskmgr_setmode
|
||||
isc_taskpool_create
|
||||
isc_taskpool_destroy
|
||||
isc_taskpool_expand
|
||||
|
|
@ -706,8 +704,6 @@ isc_timer_detach
|
|||
isc_timer_gettype
|
||||
isc_timer_reset
|
||||
isc_timer_touch
|
||||
isc_timermgr_create
|
||||
isc_timermgr_destroy
|
||||
isc_timermgr_poke
|
||||
isc_tls_get_http2_alpn
|
||||
isc_tls_create
|
||||
|
|
|
|||
|
|
@ -44,6 +44,9 @@
|
|||
<ClInclude Include="..\include\isc\backtrace.h">
|
||||
<Filter>Library Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\isc\barrier.h">
|
||||
<Filter>Library Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\isc\base32.h">
|
||||
<Filter>Library Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
|
@ -140,6 +143,9 @@
|
|||
<ClInclude Include="..\include\isc\magic.h">
|
||||
<Filter>Library Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\isc\managers.h">
|
||||
<Filter>Library Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\isc\mem.h">
|
||||
<Filter>Library Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
|
@ -530,6 +536,9 @@
|
|||
<ClCompile Include="..\log.c">
|
||||
<Filter>Library Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\managers.c">
|
||||
<Filter>Library Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\mem.c">
|
||||
<Filter>Library Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
|||
|
|
@ -269,6 +269,7 @@ copy InstallFiles ..\Build\Release\
|
|||
<ClInclude Include="..\include\isc\astack.h" />
|
||||
<ClInclude Include="..\include\isc\atomic.h" />
|
||||
<ClInclude Include="..\include\isc\backtrace.h" />
|
||||
<ClInclude Include="..\include\isc\barrier.h" />
|
||||
<ClInclude Include="..\include\isc\base32.h" />
|
||||
<ClInclude Include="..\include\isc\base64.h" />
|
||||
<ClInclude Include="..\include\isc\bind9.h" />
|
||||
|
|
@ -302,6 +303,7 @@ copy InstallFiles ..\Build\Release\
|
|||
<ClInclude Include="..\include\isc\list.h" />
|
||||
<ClInclude Include="..\include\isc\log.h" />
|
||||
<ClInclude Include="..\include\isc\magic.h" />
|
||||
<ClInclude Include="..\include\isc\managers.h" />
|
||||
<ClInclude Include="..\include\isc\md.h" />
|
||||
<ClInclude Include="..\include\isc\mem.h" />
|
||||
<ClInclude Include="..\include\isc\meminfo.h" />
|
||||
|
|
@ -412,6 +414,7 @@ copy InstallFiles ..\Build\Release\
|
|||
<ClCompile Include="..\lex.c" />
|
||||
<ClCompile Include="..\lib.c" />
|
||||
<ClCompile Include="..\log.c" />
|
||||
<ClCompile Include="..\managers.c" />
|
||||
<ClCompile Include="..\md.c" />
|
||||
<ClCompile Include="..\mem.c" />
|
||||
<ClCompile Include="..\mutexblock.c" />
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@
|
|||
#endif /* HAVE_LIBXML2 */
|
||||
|
||||
#include "errno2result.h"
|
||||
#include "socket_p.h"
|
||||
|
||||
/*
|
||||
* Set by the -T dscp option on the command line. If set to a value
|
||||
|
|
@ -2548,12 +2549,7 @@ SocketIoThread(LPVOID ThreadContext) {
|
|||
* Create a new socket manager.
|
||||
*/
|
||||
isc_result_t
|
||||
isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) {
|
||||
return (isc_socketmgr_create2(mctx, managerp, 0, 1));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
|
||||
isc__socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp,
|
||||
unsigned int maxsocks, int nthreads) {
|
||||
isc_socketmgr_t *manager;
|
||||
|
||||
|
|
@ -2611,7 +2607,7 @@ isc_socketmgr_setstats(isc_socketmgr_t *manager, isc_stats_t *stats) {
|
|||
}
|
||||
|
||||
void
|
||||
isc_socketmgr_destroy(isc_socketmgr_t **managerp) {
|
||||
isc__socketmgr_destroy(isc_socketmgr_t **managerp) {
|
||||
isc_socketmgr_t *manager;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1629,15 +1629,13 @@ ns__client_put_cb(void *client0) {
|
|||
void
|
||||
ns__client_request(isc_nmhandle_t *handle, isc_result_t eresult,
|
||||
isc_region_t *region, void *arg) {
|
||||
ns_client_t *client;
|
||||
ns_clientmgr_t *mgr;
|
||||
ns_interface_t *ifp;
|
||||
ns_client_t *client = NULL;
|
||||
isc_result_t result;
|
||||
isc_result_t sigresult = ISC_R_SUCCESS;
|
||||
isc_buffer_t *buffer;
|
||||
isc_buffer_t *buffer = NULL;
|
||||
isc_buffer_t tbuffer;
|
||||
dns_rdataset_t *opt;
|
||||
const dns_name_t *signame;
|
||||
dns_rdataset_t *opt = NULL;
|
||||
const dns_name_t *signame = NULL;
|
||||
bool ra; /* Recursion available. */
|
||||
isc_netaddr_t netaddr;
|
||||
int match;
|
||||
|
|
@ -1645,29 +1643,24 @@ ns__client_request(isc_nmhandle_t *handle, isc_result_t eresult,
|
|||
unsigned int flags;
|
||||
bool notimp;
|
||||
size_t reqsize;
|
||||
dns_aclenv_t *env;
|
||||
dns_aclenv_t *env = NULL;
|
||||
#ifdef HAVE_DNSTAP
|
||||
dns_dtmsgtype_t dtmsgtype;
|
||||
#endif /* ifdef HAVE_DNSTAP */
|
||||
ifp = (ns_interface_t *)arg;
|
||||
|
||||
if (eresult != ISC_R_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
mgr = ifp->clientmgr;
|
||||
if (mgr == NULL) {
|
||||
/* The interface was shut down in the meantime, just bail */
|
||||
return;
|
||||
}
|
||||
|
||||
REQUIRE(VALID_MANAGER(mgr));
|
||||
|
||||
client = isc_nmhandle_getdata(handle);
|
||||
if (client == NULL) {
|
||||
ns_interface_t *ifp = (ns_interface_t *)arg;
|
||||
|
||||
INSIST(VALID_MANAGER(ifp->clientmgr));
|
||||
|
||||
client = isc_nmhandle_getextra(handle);
|
||||
|
||||
result = ns__client_setup(client, mgr, true);
|
||||
result = ns__client_setup(client, ifp->clientmgr, true);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include <isc/buffer.h>
|
||||
#include <isc/file.h>
|
||||
#include <isc/hash.h>
|
||||
#include <isc/managers.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/netmgr.h>
|
||||
#include <isc/os.h>
|
||||
|
|
@ -56,7 +57,6 @@ isc_taskmgr_t *taskmgr = NULL;
|
|||
isc_task_t *maintask = NULL;
|
||||
isc_timermgr_t *timermgr = NULL;
|
||||
isc_socketmgr_t *socketmgr = NULL;
|
||||
isc_nm_t *nm = NULL;
|
||||
dns_zonemgr_t *zonemgr = NULL;
|
||||
dns_dispatchmgr_t *dispatchmgr = NULL;
|
||||
ns_clientmgr_t *clientmgr = NULL;
|
||||
|
|
@ -198,28 +198,12 @@ cleanup_managers(void) {
|
|||
if (interfacemgr != NULL) {
|
||||
ns_interfacemgr_detach(&interfacemgr);
|
||||
}
|
||||
if (socketmgr != NULL) {
|
||||
isc_socketmgr_destroy(&socketmgr);
|
||||
}
|
||||
ns_test_nap(500000);
|
||||
if (nm != NULL) {
|
||||
/*
|
||||
* Force something in the workqueue as a workaround
|
||||
* for libuv bug - not sending uv_close callback.
|
||||
*/
|
||||
isc_nm_pause(nm);
|
||||
isc_nm_resume(nm);
|
||||
isc_nm_detach(&nm);
|
||||
}
|
||||
if (taskmgr != NULL) {
|
||||
isc_taskmgr_destroy(&taskmgr);
|
||||
}
|
||||
if (netmgr != NULL) {
|
||||
isc_nm_destroy(&netmgr);
|
||||
}
|
||||
if (timermgr != NULL) {
|
||||
isc_timermgr_destroy(&timermgr);
|
||||
}
|
||||
|
||||
isc_managers_destroy(netmgr == NULL ? NULL : &netmgr,
|
||||
taskmgr == NULL ? NULL : &taskmgr,
|
||||
timermgr == NULL ? NULL : &timermgr,
|
||||
socketmgr == NULL ? NULL : &socketmgr);
|
||||
|
||||
if (app_running) {
|
||||
isc_app_finish();
|
||||
}
|
||||
|
|
@ -241,24 +225,18 @@ create_managers(void) {
|
|||
isc_event_t *event = NULL;
|
||||
ncpus = isc_os_ncpus();
|
||||
|
||||
netmgr = isc_nm_start(mctx, ncpus);
|
||||
CHECK(isc_taskmgr_create(mctx, 0, netmgr, &taskmgr));
|
||||
CHECK(isc_task_create(taskmgr, 0, &maintask));
|
||||
isc_managers_create(mctx, ncpus, 0, 0, &netmgr, &taskmgr, &timermgr,
|
||||
&socketmgr);
|
||||
CHECK(isc_task_create_bound(taskmgr, 0, &maintask, 0));
|
||||
isc_taskmgr_setexcltask(taskmgr, maintask);
|
||||
CHECK(isc_task_onshutdown(maintask, shutdown_managers, NULL));
|
||||
|
||||
CHECK(isc_timermgr_create(mctx, &timermgr));
|
||||
|
||||
CHECK(isc_socketmgr_create(mctx, &socketmgr));
|
||||
|
||||
nm = isc_nm_start(mctx, ncpus);
|
||||
|
||||
CHECK(ns_server_create(mctx, matchview, &sctx));
|
||||
|
||||
CHECK(dns_dispatchmgr_create(mctx, &dispatchmgr));
|
||||
|
||||
CHECK(ns_interfacemgr_create(mctx, sctx, taskmgr, timermgr, socketmgr,
|
||||
nm, dispatchmgr, maintask, ncpus, NULL,
|
||||
netmgr, dispatchmgr, maintask, ncpus, NULL,
|
||||
ncpus, &interfacemgr));
|
||||
|
||||
CHECK(ns_listenlist_default(mctx, port, -1, true, &listenon));
|
||||
|
|
|
|||
|
|
@ -1852,6 +1852,7 @@
|
|||
./lib/isc/include/isc/atomic.h C 2018,2019,2020,2021
|
||||
./lib/isc/include/isc/attributes.h C 2020,2021
|
||||
./lib/isc/include/isc/backtrace.h C 2009,2016,2018,2019,2020,2021
|
||||
./lib/isc/include/isc/barrier.h C 2021
|
||||
./lib/isc/include/isc/base32.h C 2008,2014,2016,2018,2019,2020,2021
|
||||
./lib/isc/include/isc/base64.h C 1999,2000,2001,2004,2005,2006,2007,2016,2018,2019,2020,2021
|
||||
./lib/isc/include/isc/bind9.h C 2009,2013,2016,2018,2019,2020,2021
|
||||
|
|
@ -1887,6 +1888,7 @@
|
|||
./lib/isc/include/isc/list.h C 1997,1998,1999,2000,2001,2002,2004,2006,2007,2011,2012,2013,2016,2018,2019,2020,2021
|
||||
./lib/isc/include/isc/log.h C 1999,2000,2001,2002,2004,2005,2006,2007,2009,2014,2016,2017,2018,2019,2020,2021
|
||||
./lib/isc/include/isc/magic.h C 1999,2000,2001,2004,2005,2006,2007,2016,2017,2018,2019,2020,2021
|
||||
./lib/isc/include/isc/managers.h C 2021
|
||||
./lib/isc/include/isc/md.h C 2018,2019,2020,2021
|
||||
./lib/isc/include/isc/mem.h C 1997,1998,1999,2000,2001,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2015,2016,2017,2018,2019,2020,2021
|
||||
./lib/isc/include/isc/meminfo.h C 2015,2016,2018,2019,2020,2021
|
||||
|
|
@ -1944,6 +1946,7 @@
|
|||
./lib/isc/lib.c C 1999,2000,2001,2004,2005,2007,2009,2013,2014,2015,2016,2018,2019,2020,2021
|
||||
./lib/isc/lib_p.h C 2021
|
||||
./lib/isc/log.c C 1999,2000,2001,2002,2003,2004,2005,2006,2007,2009,2011,2012,2013,2014,2016,2017,2018,2019,2020,2021
|
||||
./lib/isc/managers.c C 2021
|
||||
./lib/isc/md.c C 2018,2019,2020,2021
|
||||
./lib/isc/mem.c C 1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021
|
||||
./lib/isc/mem_p.h C 2018,2019,2020,2021
|
||||
|
|
@ -1960,6 +1963,7 @@
|
|||
./lib/isc/netmgr/uv-compat.c C 2020,2021
|
||||
./lib/isc/netmgr/uv-compat.h C 2019,2020,2021
|
||||
./lib/isc/netmgr/uverr2result.c C 2019,2020,2021
|
||||
./lib/isc/netmgr_p.h C 2021
|
||||
./lib/isc/netscope.c C 2002,2004,2005,2006,2007,2016,2018,2019,2020,2021
|
||||
./lib/isc/nonce.c C 2018,2019,2020,2021
|
||||
./lib/isc/openssl_shim.c C 2018,2019,2020,2021
|
||||
|
|
@ -1989,10 +1993,12 @@
|
|||
./lib/isc/serial.c C 1999,2000,2001,2004,2005,2007,2016,2018,2019,2020,2021
|
||||
./lib/isc/siphash.c C 2019,2020,2021
|
||||
./lib/isc/sockaddr.c C 1999,2000,2001,2002,2003,2004,2005,2006,2007,2010,2011,2012,2014,2015,2016,2017,2018,2019,2020,2021
|
||||
./lib/isc/socket_p.h C 2021
|
||||
./lib/isc/stats.c C 2009,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021
|
||||
./lib/isc/string.c C 1999,2000,2001,2003,2004,2005,2006,2007,2011,2012,2014,2015,2016,2018,2019,2020,2021
|
||||
./lib/isc/symtab.c C 1996,1997,1998,1999,2000,2001,2004,2005,2007,2011,2012,2013,2016,2018,2019,2020,2021
|
||||
./lib/isc/task.c C 1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021
|
||||
./lib/isc/task_p.h C 2021
|
||||
./lib/isc/taskpool.c C 1999,2000,2001,2004,2005,2007,2011,2012,2013,2016,2018,2019,2020,2021
|
||||
./lib/isc/tests/aes_test.c C 2014,2016,2018,2019,2020,2021
|
||||
./lib/isc/tests/buffer_test.c C 2014,2015,2016,2017,2018,2019,2020,2021
|
||||
|
|
@ -2031,6 +2037,7 @@
|
|||
./lib/isc/tests/timer_test.c C 2018,2019,2020,2021
|
||||
./lib/isc/tests/uv_wrap.h C 2020,2021
|
||||
./lib/isc/timer.c C 1998,1999,2000,2001,2002,2004,2005,2007,2008,2009,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021
|
||||
./lib/isc/timer_p.h C 2021
|
||||
./lib/isc/tls.c C 2021
|
||||
./lib/isc/tls_p.h C 2021
|
||||
./lib/isc/tm.c C 2014,2016,2018,2019,2020,2021
|
||||
|
|
@ -2059,7 +2066,6 @@
|
|||
./lib/isc/unix/pk11_api.c C 2014,2016,2018,2019,2020,2021
|
||||
./lib/isc/unix/resource.c C 2000,2001,2004,2007,2008,2009,2016,2018,2019,2020,2021
|
||||
./lib/isc/unix/socket.c C 1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021
|
||||
./lib/isc/unix/socket_p.h C 2000,2001,2004,2005,2007,2008,2009,2016,2018,2019,2020,2021
|
||||
./lib/isc/unix/stdio.c C 2000,2001,2004,2007,2011,2012,2013,2014,2016,2018,2019,2020,2021
|
||||
./lib/isc/unix/stdtime.c C 1999,2000,2001,2004,2005,2007,2016,2018,2019,2020,2021
|
||||
./lib/isc/unix/syslog.c C 2001,2004,2005,2007,2016,2018,2019,2020,2021
|
||||
|
|
|
|||
Loading…
Reference in a new issue