mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-03 16:15:27 +00:00
ensure interlocked netmgr events run on worker[0]
Network manager events that require interlock (pause, resume, listen) are now always executed in the same worker thread, mgr->workers[0], to prevent races. "stoplistening" events no longer require interlock.
This commit is contained in:
@@ -10201,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
|
* startup and shutdown of the server, as well as all exclusive
|
||||||
* tasks.
|
* 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");
|
"creating server task");
|
||||||
isc_task_setname(server->task, "server", server);
|
isc_task_setname(server->task, "server", server);
|
||||||
isc_taskmgr_setexcltask(named_g_taskmgr, server->task);
|
isc_taskmgr_setexcltask(named_g_taskmgr, server->task);
|
||||||
|
@@ -2171,7 +2171,7 @@ isc_nm_listenhttp(isc_nm_t *mgr, isc_nmiface_t *iface, int backlog,
|
|||||||
|
|
||||||
sock->nchildren = sock->outer->nchildren;
|
sock->nchildren = sock->outer->nchildren;
|
||||||
sock->result = ISC_R_UNSET;
|
sock->result = ISC_R_UNSET;
|
||||||
sock->tid = isc_random_uniform(sock->nchildren);
|
sock->tid = 0;
|
||||||
sock->fd = (uv_os_sock_t)-1;
|
sock->fd = (uv_os_sock_t)-1;
|
||||||
|
|
||||||
atomic_store(&sock->listening, true);
|
atomic_store(&sock->listening, true);
|
||||||
@@ -2254,6 +2254,7 @@ isc__nm_http_stoplistening(isc_nmsocket_t *sock) {
|
|||||||
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
|
isc__nm_enqueue_ievent(&sock->mgr->workers[sock->tid],
|
||||||
(isc__netievent_t *)ievent);
|
(isc__netievent_t *)ievent);
|
||||||
} else {
|
} else {
|
||||||
|
REQUIRE(isc_nm_tid() == sock->tid);
|
||||||
isc__netievent_httpstop_t ievent = { .sock = sock };
|
isc__netievent_httpstop_t ievent = { .sock = sock };
|
||||||
isc__nm_async_httpstop(NULL, (isc__netievent_t *)&ievent);
|
isc__nm_async_httpstop(NULL, (isc__netievent_t *)&ievent);
|
||||||
}
|
}
|
||||||
|
@@ -437,6 +437,10 @@ isc_nm_pause(isc_nm_t *mgr) {
|
|||||||
|
|
||||||
isc__nm_acquire_interlocked_force(mgr);
|
isc__nm_acquire_interlocked_force(mgr);
|
||||||
|
|
||||||
|
if (isc__nm_in_netthread()) {
|
||||||
|
REQUIRE(isc_nm_tid() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < mgr->nworkers; i++) {
|
for (int i = 0; i < mgr->nworkers; i++) {
|
||||||
isc__networker_t *worker = &mgr->workers[i];
|
isc__networker_t *worker = &mgr->workers[i];
|
||||||
if (i == isc_nm_tid()) {
|
if (i == isc_nm_tid()) {
|
||||||
@@ -447,8 +451,8 @@ isc_nm_pause(isc_nm_t *mgr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isc__nm_in_netthread()) {
|
if (isc__nm_in_netthread()) {
|
||||||
|
atomic_fetch_add(&mgr->workers_paused, 1);
|
||||||
isc_barrier_wait(&mgr->pausing);
|
isc_barrier_wait(&mgr->pausing);
|
||||||
drain_priority_queue(&mgr->workers[isc_nm_tid()]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCK(&mgr->lock);
|
LOCK(&mgr->lock);
|
||||||
@@ -481,6 +485,11 @@ isc_nm_resume(isc_nm_t *mgr) {
|
|||||||
REQUIRE(VALID_NM(mgr));
|
REQUIRE(VALID_NM(mgr));
|
||||||
REQUIRE(atomic_load(&mgr->paused));
|
REQUIRE(atomic_load(&mgr->paused));
|
||||||
|
|
||||||
|
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++) {
|
for (int i = 0; i < mgr->nworkers; i++) {
|
||||||
isc__networker_t *worker = &mgr->workers[i];
|
isc__networker_t *worker = &mgr->workers[i];
|
||||||
if (i == isc_nm_tid()) {
|
if (i == isc_nm_tid()) {
|
||||||
|
@@ -409,6 +409,14 @@ start_tcp_child(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nmsocket_t *sock,
|
|||||||
(isc__netievent_t *)ievent);
|
(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_result_t
|
||||||
isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface,
|
isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface,
|
||||||
isc_nm_accept_cb_t accept_cb, void *accept_cbarg,
|
isc_nm_accept_cb_t accept_cb, void *accept_cbarg,
|
||||||
@@ -442,11 +450,7 @@ isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface,
|
|||||||
sock->backlog = backlog;
|
sock->backlog = backlog;
|
||||||
sock->pquota = quota;
|
sock->pquota = quota;
|
||||||
|
|
||||||
if (isc__nm_in_netthread()) {
|
sock->tid = 0;
|
||||||
sock->tid = isc_nm_tid();
|
|
||||||
} else {
|
|
||||||
sock->tid = isc_random_uniform(sock->nchildren);
|
|
||||||
}
|
|
||||||
sock->fd = -1;
|
sock->fd = -1;
|
||||||
|
|
||||||
#if !HAVE_SO_REUSEPORT_LB && !defined(WIN32)
|
#if !HAVE_SO_REUSEPORT_LB && !defined(WIN32)
|
||||||
@@ -485,7 +489,7 @@ isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface,
|
|||||||
*sockp = sock;
|
*sockp = sock;
|
||||||
} else {
|
} else {
|
||||||
atomic_store(&sock->active, false);
|
atomic_store(&sock->active, false);
|
||||||
isc_nm_stoplistening(sock);
|
enqueue_stoplistening(sock);
|
||||||
isc_nmsocket_close(&sock);
|
isc_nmsocket_close(&sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -642,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
|
void
|
||||||
isc__nm_tcp_stoplistening(isc_nmsocket_t *sock) {
|
isc__nm_tcp_stoplistening(isc_nmsocket_t *sock) {
|
||||||
REQUIRE(VALID_NMSOCK(sock));
|
REQUIRE(VALID_NMSOCK(sock));
|
||||||
@@ -663,11 +659,8 @@ isc__nm_tcp_stoplistening(isc_nmsocket_t *sock) {
|
|||||||
|
|
||||||
if (!isc__nm_in_netthread()) {
|
if (!isc__nm_in_netthread()) {
|
||||||
enqueue_stoplistening(sock);
|
enqueue_stoplistening(sock);
|
||||||
} else if (!isc__nm_acquire_interlocked(sock->mgr)) {
|
|
||||||
enqueue_stoplistening(sock);
|
|
||||||
} else {
|
} else {
|
||||||
stop_tcp_parent(sock);
|
stop_tcp_parent(sock);
|
||||||
isc__nm_drop_interlocked(sock->mgr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -686,12 +679,7 @@ isc__nm_async_tcpstop(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isc__nm_acquire_interlocked(sock->mgr)) {
|
stop_tcp_parent(sock);
|
||||||
enqueue_stoplistening(sock);
|
|
||||||
} else {
|
|
||||||
stop_tcp_parent(sock);
|
|
||||||
isc__nm_drop_interlocked(sock->mgr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1248,7 +1236,9 @@ stop_tcp_child(isc_nmsocket_t *sock) {
|
|||||||
static void
|
static void
|
||||||
stop_tcp_parent(isc_nmsocket_t *sock) {
|
stop_tcp_parent(isc_nmsocket_t *sock) {
|
||||||
isc_nmsocket_t *csock = NULL;
|
isc_nmsocket_t *csock = NULL;
|
||||||
|
|
||||||
REQUIRE(VALID_NMSOCK(sock));
|
REQUIRE(VALID_NMSOCK(sock));
|
||||||
|
REQUIRE(sock->tid == isc_nm_tid());
|
||||||
REQUIRE(sock->type == isc_nm_tcplistener);
|
REQUIRE(sock->type == isc_nm_tcplistener);
|
||||||
|
|
||||||
isc_barrier_init(&sock->stoplistening, sock->nchildren);
|
isc_barrier_init(&sock->stoplistening, sock->nchildren);
|
||||||
|
@@ -343,6 +343,14 @@ isc__nm_tcpdns_lb_socket(sa_family_t sa_family) {
|
|||||||
return (sock);
|
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
|
static void
|
||||||
start_tcpdns_child(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nmsocket_t *sock,
|
start_tcpdns_child(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nmsocket_t *sock,
|
||||||
uv_os_sock_t fd, int tid) {
|
uv_os_sock_t fd, int tid) {
|
||||||
@@ -412,11 +420,7 @@ isc_nm_listentcpdns(isc_nm_t *mgr, isc_nmiface_t *iface,
|
|||||||
sock->backlog = backlog;
|
sock->backlog = backlog;
|
||||||
sock->pquota = quota;
|
sock->pquota = quota;
|
||||||
|
|
||||||
if (isc__nm_in_netthread()) {
|
sock->tid = 0;
|
||||||
sock->tid = isc_nm_tid();
|
|
||||||
} else {
|
|
||||||
sock->tid = isc_random_uniform(sock->nchildren);
|
|
||||||
}
|
|
||||||
sock->fd = -1;
|
sock->fd = -1;
|
||||||
|
|
||||||
#if !HAVE_SO_REUSEPORT_LB && !defined(WIN32)
|
#if !HAVE_SO_REUSEPORT_LB && !defined(WIN32)
|
||||||
@@ -455,7 +459,7 @@ isc_nm_listentcpdns(isc_nm_t *mgr, isc_nmiface_t *iface,
|
|||||||
*sockp = sock;
|
*sockp = sock;
|
||||||
} else {
|
} else {
|
||||||
atomic_store(&sock->active, false);
|
atomic_store(&sock->active, false);
|
||||||
isc_nm_stoplistening(sock);
|
enqueue_stoplistening(sock);
|
||||||
isc_nmsocket_close(&sock);
|
isc_nmsocket_close(&sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -612,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
|
void
|
||||||
isc__nm_tcpdns_stoplistening(isc_nmsocket_t *sock) {
|
isc__nm_tcpdns_stoplistening(isc_nmsocket_t *sock) {
|
||||||
REQUIRE(VALID_NMSOCK(sock));
|
REQUIRE(VALID_NMSOCK(sock));
|
||||||
@@ -633,11 +629,8 @@ isc__nm_tcpdns_stoplistening(isc_nmsocket_t *sock) {
|
|||||||
|
|
||||||
if (!isc__nm_in_netthread()) {
|
if (!isc__nm_in_netthread()) {
|
||||||
enqueue_stoplistening(sock);
|
enqueue_stoplistening(sock);
|
||||||
} else if (!isc__nm_acquire_interlocked(sock->mgr)) {
|
|
||||||
enqueue_stoplistening(sock);
|
|
||||||
} else {
|
} else {
|
||||||
stop_tcpdns_parent(sock);
|
stop_tcpdns_parent(sock);
|
||||||
isc__nm_drop_interlocked(sock->mgr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -657,15 +650,7 @@ isc__nm_async_tcpdnsstop(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
stop_tcpdns_parent(sock);
|
||||||
* If network manager is paused, re-enqueue the event for later.
|
|
||||||
*/
|
|
||||||
if (!isc__nm_acquire_interlocked(sock->mgr)) {
|
|
||||||
enqueue_stoplistening(sock);
|
|
||||||
} else {
|
|
||||||
stop_tcpdns_parent(sock);
|
|
||||||
isc__nm_drop_interlocked(sock->mgr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1283,6 +1268,7 @@ stop_tcpdns_parent(isc_nmsocket_t *sock) {
|
|||||||
isc_nmsocket_t *csock = NULL;
|
isc_nmsocket_t *csock = NULL;
|
||||||
|
|
||||||
REQUIRE(VALID_NMSOCK(sock));
|
REQUIRE(VALID_NMSOCK(sock));
|
||||||
|
REQUIRE(sock->tid == isc_nm_tid());
|
||||||
REQUIRE(sock->type == isc_nm_tcpdnslistener);
|
REQUIRE(sock->type == isc_nm_tcpdnslistener);
|
||||||
|
|
||||||
isc_barrier_init(&sock->stoplistening, sock->nchildren);
|
isc_barrier_init(&sock->stoplistening, sock->nchildren);
|
||||||
|
@@ -445,6 +445,14 @@ start_tlsdns_child(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nmsocket_t *sock,
|
|||||||
(isc__netievent_t *)ievent);
|
(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_result_t
|
||||||
isc_nm_listentlsdns(isc_nm_t *mgr, isc_nmiface_t *iface,
|
isc_nm_listentlsdns(isc_nm_t *mgr, isc_nmiface_t *iface,
|
||||||
isc_nm_recv_cb_t recv_cb, void *recv_cbarg,
|
isc_nm_recv_cb_t recv_cb, void *recv_cbarg,
|
||||||
@@ -480,13 +488,9 @@ isc_nm_listentlsdns(isc_nm_t *mgr, isc_nmiface_t *iface,
|
|||||||
sock->backlog = backlog;
|
sock->backlog = backlog;
|
||||||
sock->pquota = quota;
|
sock->pquota = quota;
|
||||||
|
|
||||||
if (isc__nm_in_netthread()) {
|
|
||||||
sock->tid = isc_nm_tid();
|
|
||||||
} else {
|
|
||||||
sock->tid = isc_random_uniform(sock->nchildren);
|
|
||||||
}
|
|
||||||
|
|
||||||
sock->tls.ctx = sslctx;
|
sock->tls.ctx = sslctx;
|
||||||
|
|
||||||
|
sock->tid = 0;
|
||||||
sock->fd = -1;
|
sock->fd = -1;
|
||||||
|
|
||||||
#if !HAVE_SO_REUSEPORT_LB && !defined(WIN32)
|
#if !HAVE_SO_REUSEPORT_LB && !defined(WIN32)
|
||||||
@@ -525,7 +529,7 @@ isc_nm_listentlsdns(isc_nm_t *mgr, isc_nmiface_t *iface,
|
|||||||
*sockp = sock;
|
*sockp = sock;
|
||||||
} else {
|
} else {
|
||||||
atomic_store(&sock->active, false);
|
atomic_store(&sock->active, false);
|
||||||
isc_nm_stoplistening(sock);
|
enqueue_stoplistening(sock);
|
||||||
isc_nmsocket_close(&sock);
|
isc_nmsocket_close(&sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -683,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
|
void
|
||||||
isc__nm_tlsdns_stoplistening(isc_nmsocket_t *sock) {
|
isc__nm_tlsdns_stoplistening(isc_nmsocket_t *sock) {
|
||||||
REQUIRE(VALID_NMSOCK(sock));
|
REQUIRE(VALID_NMSOCK(sock));
|
||||||
@@ -704,11 +700,8 @@ isc__nm_tlsdns_stoplistening(isc_nmsocket_t *sock) {
|
|||||||
|
|
||||||
if (!isc__nm_in_netthread()) {
|
if (!isc__nm_in_netthread()) {
|
||||||
enqueue_stoplistening(sock);
|
enqueue_stoplistening(sock);
|
||||||
} else if (!isc__nm_acquire_interlocked(sock->mgr)) {
|
|
||||||
enqueue_stoplistening(sock);
|
|
||||||
} else {
|
} else {
|
||||||
stop_tlsdns_parent(sock);
|
stop_tlsdns_parent(sock);
|
||||||
isc__nm_drop_interlocked(sock->mgr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -803,15 +796,7 @@ isc__nm_async_tlsdnsstop(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
stop_tlsdns_parent(sock);
|
||||||
* If network manager is paused, re-enqueue the event for later.
|
|
||||||
*/
|
|
||||||
if (!isc__nm_acquire_interlocked(sock->mgr)) {
|
|
||||||
enqueue_stoplistening(sock);
|
|
||||||
} else {
|
|
||||||
stop_tlsdns_parent(sock);
|
|
||||||
isc__nm_drop_interlocked(sock->mgr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1831,6 +1816,7 @@ stop_tlsdns_parent(isc_nmsocket_t *sock) {
|
|||||||
isc_nmsocket_t *csock = NULL;
|
isc_nmsocket_t *csock = NULL;
|
||||||
|
|
||||||
REQUIRE(VALID_NMSOCK(sock));
|
REQUIRE(VALID_NMSOCK(sock));
|
||||||
|
REQUIRE(sock->tid == isc_nm_tid());
|
||||||
REQUIRE(sock->type == isc_nm_tlsdnslistener);
|
REQUIRE(sock->type == isc_nm_tlsdnslistener);
|
||||||
|
|
||||||
isc_barrier_init(&sock->stoplistening, sock->nchildren);
|
isc_barrier_init(&sock->stoplistening, sock->nchildren);
|
||||||
|
@@ -108,6 +108,14 @@ start_udp_child(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nmsocket_t *sock,
|
|||||||
(isc__netievent_t *)ievent);
|
(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_result_t
|
||||||
isc_nm_listenudp(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb,
|
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) {
|
void *cbarg, size_t extrahandlesize, isc_nmsocket_t **sockp) {
|
||||||
@@ -139,11 +147,8 @@ isc_nm_listenudp(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb,
|
|||||||
sock->recv_cbarg = cbarg;
|
sock->recv_cbarg = cbarg;
|
||||||
sock->extrahandlesize = extrahandlesize;
|
sock->extrahandlesize = extrahandlesize;
|
||||||
sock->result = ISC_R_UNSET;
|
sock->result = ISC_R_UNSET;
|
||||||
if (isc__nm_in_netthread()) {
|
|
||||||
sock->tid = isc_nm_tid();
|
sock->tid = 0;
|
||||||
} else {
|
|
||||||
sock->tid = isc_random_uniform(sock->nchildren);
|
|
||||||
}
|
|
||||||
sock->fd = -1;
|
sock->fd = -1;
|
||||||
|
|
||||||
#if !HAVE_SO_REUSEPORT_LB && !defined(WIN32)
|
#if !HAVE_SO_REUSEPORT_LB && !defined(WIN32)
|
||||||
@@ -182,7 +187,7 @@ isc_nm_listenudp(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb,
|
|||||||
*sockp = sock;
|
*sockp = sock;
|
||||||
} else {
|
} else {
|
||||||
atomic_store(&sock->active, false);
|
atomic_store(&sock->active, false);
|
||||||
isc_nm_stoplistening(sock);
|
enqueue_stoplistening(sock);
|
||||||
isc_nmsocket_close(&sock);
|
isc_nmsocket_close(&sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,14 +303,6 @@ done:
|
|||||||
isc_barrier_wait(&sock->parent->startlistening);
|
isc_barrier_wait(&sock->parent->startlistening);
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
isc__nm_udp_stoplistening(isc_nmsocket_t *sock) {
|
isc__nm_udp_stoplistening(isc_nmsocket_t *sock) {
|
||||||
REQUIRE(VALID_NMSOCK(sock));
|
REQUIRE(VALID_NMSOCK(sock));
|
||||||
@@ -319,11 +316,8 @@ isc__nm_udp_stoplistening(isc_nmsocket_t *sock) {
|
|||||||
|
|
||||||
if (!isc__nm_in_netthread()) {
|
if (!isc__nm_in_netthread()) {
|
||||||
enqueue_stoplistening(sock);
|
enqueue_stoplistening(sock);
|
||||||
} else if (!isc__nm_acquire_interlocked(sock->mgr)) {
|
|
||||||
enqueue_stoplistening(sock);
|
|
||||||
} else {
|
} else {
|
||||||
stop_udp_parent(sock);
|
stop_udp_parent(sock);
|
||||||
isc__nm_drop_interlocked(sock->mgr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,15 +339,7 @@ isc__nm_async_udpstop(isc__networker_t *worker, isc__netievent_t *ev0) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
stop_udp_parent(sock);
|
||||||
* If network manager is paused, re-enqueue the event for later.
|
|
||||||
*/
|
|
||||||
if (!isc__nm_acquire_interlocked(sock->mgr)) {
|
|
||||||
enqueue_stoplistening(sock);
|
|
||||||
} else {
|
|
||||||
stop_udp_parent(sock);
|
|
||||||
isc__nm_drop_interlocked(sock->mgr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1016,6 +1002,7 @@ stop_udp_parent(isc_nmsocket_t *sock) {
|
|||||||
isc_nmsocket_t *csock = NULL;
|
isc_nmsocket_t *csock = NULL;
|
||||||
|
|
||||||
REQUIRE(VALID_NMSOCK(sock));
|
REQUIRE(VALID_NMSOCK(sock));
|
||||||
|
REQUIRE(sock->tid == isc_nm_tid());
|
||||||
REQUIRE(sock->type == isc_nm_udplistener);
|
REQUIRE(sock->type == isc_nm_udplistener);
|
||||||
|
|
||||||
isc_barrier_init(&sock->stoplistening, sock->nchildren);
|
isc_barrier_init(&sock->stoplistening, sock->nchildren);
|
||||||
|
@@ -1095,6 +1095,8 @@ void
|
|||||||
isc_taskmgr_setexcltask(isc_taskmgr_t *mgr, isc_task_t *task) {
|
isc_taskmgr_setexcltask(isc_taskmgr_t *mgr, isc_task_t *task) {
|
||||||
REQUIRE(VALID_MANAGER(mgr));
|
REQUIRE(VALID_MANAGER(mgr));
|
||||||
REQUIRE(VALID_TASK(task));
|
REQUIRE(VALID_TASK(task));
|
||||||
|
REQUIRE(task->threadid == 0);
|
||||||
|
|
||||||
LOCK(&mgr->excl_lock);
|
LOCK(&mgr->excl_lock);
|
||||||
if (mgr->excl != NULL) {
|
if (mgr->excl != NULL) {
|
||||||
isc_task_detach(&mgr->excl);
|
isc_task_detach(&mgr->excl);
|
||||||
|
@@ -83,7 +83,7 @@ create_managers(unsigned int workers) {
|
|||||||
isc_managers_create(test_mctx, workers, 0, 0, &netmgr, &taskmgr,
|
isc_managers_create(test_mctx, workers, 0, 0, &netmgr, &taskmgr,
|
||||||
&timermgr, &socketmgr);
|
&timermgr, &socketmgr);
|
||||||
|
|
||||||
CHECK(isc_task_create(taskmgr, 0, &maintask));
|
CHECK(isc_task_create_bound(taskmgr, 0, &maintask, 0));
|
||||||
isc_taskmgr_setexcltask(taskmgr, maintask);
|
isc_taskmgr_setexcltask(taskmgr, maintask);
|
||||||
|
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
|
@@ -708,12 +708,16 @@ task_exclusive(void **state) {
|
|||||||
|
|
||||||
tasks[i] = NULL;
|
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) {
|
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]);
|
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);
|
v = isc_mem_get(test_mctx, sizeof *v);
|
||||||
|
@@ -227,7 +227,7 @@ create_managers(void) {
|
|||||||
|
|
||||||
isc_managers_create(mctx, ncpus, 0, 0, &netmgr, &taskmgr, &timermgr,
|
isc_managers_create(mctx, ncpus, 0, 0, &netmgr, &taskmgr, &timermgr,
|
||||||
&socketmgr);
|
&socketmgr);
|
||||||
CHECK(isc_task_create(taskmgr, 0, &maintask));
|
CHECK(isc_task_create_bound(taskmgr, 0, &maintask, 0));
|
||||||
isc_taskmgr_setexcltask(taskmgr, maintask);
|
isc_taskmgr_setexcltask(taskmgr, maintask);
|
||||||
CHECK(isc_task_onshutdown(maintask, shutdown_managers, NULL));
|
CHECK(isc_task_onshutdown(maintask, shutdown_managers, NULL));
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user