|
|
1872c6 |
From 64d62856d251b58fe3350e9c3cf985a78debba5d Mon Sep 17 00:00:00 2001
|
|
|
1872c6 |
From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= <ondrej@isc.org>
|
|
|
1872c6 |
Date: Wed, 7 Aug 2019 05:46:45 -0400
|
|
|
1872c6 |
Subject: [PATCH] Merge branch '1148-deadlock-hangs-named-v9_11' into 'v9_11'
|
|
|
1872c6 |
|
|
|
1872c6 |
Convert (dns_view_t){ .weakrefs } to isc_refcount_t
|
|
|
1872c6 |
|
|
|
1872c6 |
See merge request isc-projects/bind9!2227
|
|
|
1872c6 |
|
|
|
1872c6 |
(cherry picked from commit e3903e83962c659bbac52454c816588c24078b5e)
|
|
|
1872c6 |
---
|
|
|
1872c6 |
lib/dns/client.c | 121 +++++++++++++++++--------------------
|
|
|
1872c6 |
lib/dns/include/dns/view.h | 2 +-
|
|
|
1872c6 |
lib/dns/view.c | 88 +++++++++------------------
|
|
|
1872c6 |
lib/isc/app_api.c | 18 +++++-
|
|
|
1872c6 |
4 files changed, 103 insertions(+), 126 deletions(-)
|
|
|
1872c6 |
|
|
|
1872c6 |
diff --git a/lib/dns/client.c b/lib/dns/client.c
|
|
|
1872c6 |
index b0dfa57dbe..e7eb40cd07 100644
|
|
|
1872c6 |
--- a/lib/dns/client.c
|
|
|
1872c6 |
+++ b/lib/dns/client.c
|
|
|
1872c6 |
@@ -17,6 +17,7 @@
|
|
|
1872c6 |
#include <isc/buffer.h>
|
|
|
1872c6 |
#include <isc/mem.h>
|
|
|
1872c6 |
#include <isc/mutex.h>
|
|
|
1872c6 |
+#include <isc/refcount.h>
|
|
|
1872c6 |
#include <isc/safe.h>
|
|
|
1872c6 |
#include <isc/sockaddr.h>
|
|
|
1872c6 |
#include <isc/socket.h>
|
|
|
1872c6 |
@@ -92,8 +93,9 @@ struct dns_client {
|
|
|
1872c6 |
unsigned int find_timeout;
|
|
|
1872c6 |
unsigned int find_udpretries;
|
|
|
1872c6 |
|
|
|
1872c6 |
+ isc_refcount_t references;
|
|
|
1872c6 |
+
|
|
|
1872c6 |
/* Locked */
|
|
|
1872c6 |
- unsigned int references;
|
|
|
1872c6 |
dns_viewlist_t viewlist;
|
|
|
1872c6 |
ISC_LIST(struct resctx) resctxs;
|
|
|
1872c6 |
ISC_LIST(struct reqctx) reqctxs;
|
|
|
1872c6 |
@@ -463,8 +465,7 @@ dns_client_createx2(isc_mem_t *mctx, isc_appctx_t *actx,
|
|
|
1872c6 |
|
|
|
1872c6 |
result = isc_mutex_init(&client->lock);
|
|
|
1872c6 |
if (result != ISC_R_SUCCESS) {
|
|
|
1872c6 |
- isc_mem_put(mctx, client, sizeof(*client));
|
|
|
1872c6 |
- return (result);
|
|
|
1872c6 |
+ goto cleanup_client;
|
|
|
1872c6 |
}
|
|
|
1872c6 |
|
|
|
1872c6 |
client->actx = actx;
|
|
|
1872c6 |
@@ -474,12 +475,14 @@ dns_client_createx2(isc_mem_t *mctx, isc_appctx_t *actx,
|
|
|
1872c6 |
|
|
|
1872c6 |
client->task = NULL;
|
|
|
1872c6 |
result = isc_task_create(client->taskmgr, 0, &client->task);
|
|
|
1872c6 |
- if (result != ISC_R_SUCCESS)
|
|
|
1872c6 |
- goto cleanup;
|
|
|
1872c6 |
+ if (result != ISC_R_SUCCESS) {
|
|
|
1872c6 |
+ goto cleanup_lock;
|
|
|
1872c6 |
+ }
|
|
|
1872c6 |
|
|
|
1872c6 |
result = dns_dispatchmgr_create(mctx, NULL, &dispatchmgr);
|
|
|
1872c6 |
- if (result != ISC_R_SUCCESS)
|
|
|
1872c6 |
- goto cleanup;
|
|
|
1872c6 |
+ if (result != ISC_R_SUCCESS) {
|
|
|
1872c6 |
+ goto cleanup_task;
|
|
|
1872c6 |
+ }
|
|
|
1872c6 |
client->dispatchmgr = dispatchmgr;
|
|
|
1872c6 |
|
|
|
1872c6 |
/*
|
|
|
1872c6 |
@@ -491,8 +494,9 @@ dns_client_createx2(isc_mem_t *mctx, isc_appctx_t *actx,
|
|
|
1872c6 |
result = getudpdispatch(AF_INET, dispatchmgr, socketmgr,
|
|
|
1872c6 |
taskmgr, ISC_TRUE,
|
|
|
1872c6 |
&dispatchv4, localaddr4);
|
|
|
1872c6 |
- if (result == ISC_R_SUCCESS)
|
|
|
1872c6 |
+ if (result == ISC_R_SUCCESS) {
|
|
|
1872c6 |
client->dispatchv4 = dispatchv4;
|
|
|
1872c6 |
+ }
|
|
|
1872c6 |
}
|
|
|
1872c6 |
|
|
|
1872c6 |
client->dispatchv6 = NULL;
|
|
|
1872c6 |
@@ -500,22 +504,30 @@ dns_client_createx2(isc_mem_t *mctx, isc_appctx_t *actx,
|
|
|
1872c6 |
result = getudpdispatch(AF_INET6, dispatchmgr, socketmgr,
|
|
|
1872c6 |
taskmgr, ISC_TRUE,
|
|
|
1872c6 |
&dispatchv6, localaddr6);
|
|
|
1872c6 |
- if (result == ISC_R_SUCCESS)
|
|
|
1872c6 |
+ if (result == ISC_R_SUCCESS) {
|
|
|
1872c6 |
client->dispatchv6 = dispatchv6;
|
|
|
1872c6 |
+ }
|
|
|
1872c6 |
}
|
|
|
1872c6 |
|
|
|
1872c6 |
/* We need at least one of the dispatchers */
|
|
|
1872c6 |
if (dispatchv4 == NULL && dispatchv6 == NULL) {
|
|
|
1872c6 |
INSIST(result != ISC_R_SUCCESS);
|
|
|
1872c6 |
- goto cleanup;
|
|
|
1872c6 |
+ goto cleanup_dispatchmgr;
|
|
|
1872c6 |
+ }
|
|
|
1872c6 |
+
|
|
|
1872c6 |
+ result = isc_refcount_init(&client->references, 1);
|
|
|
1872c6 |
+ if (result != ISC_R_SUCCESS) {
|
|
|
1872c6 |
+ goto cleanup_dispatches;
|
|
|
1872c6 |
}
|
|
|
1872c6 |
|
|
|
1872c6 |
/* Create the default view for class IN */
|
|
|
1872c6 |
result = createview(mctx, dns_rdataclass_in, options, taskmgr,
|
|
|
1872c6 |
RESOLVER_NTASKS, socketmgr, timermgr,
|
|
|
1872c6 |
dispatchmgr, dispatchv4, dispatchv6, &view);
|
|
|
1872c6 |
- if (result != ISC_R_SUCCESS)
|
|
|
1872c6 |
- goto cleanup;
|
|
|
1872c6 |
+ if (result != ISC_R_SUCCESS) {
|
|
|
1872c6 |
+ goto cleanup_references;
|
|
|
1872c6 |
+ }
|
|
|
1872c6 |
+
|
|
|
1872c6 |
ISC_LIST_INIT(client->viewlist);
|
|
|
1872c6 |
ISC_LIST_APPEND(client->viewlist, view, link);
|
|
|
1872c6 |
|
|
|
1872c6 |
@@ -535,32 +547,38 @@ dns_client_createx2(isc_mem_t *mctx, isc_appctx_t *actx,
|
|
|
1872c6 |
client->find_udpretries = DEF_FIND_UDPRETRIES;
|
|
|
1872c6 |
client->attributes = 0;
|
|
|
1872c6 |
|
|
|
1872c6 |
- client->references = 1;
|
|
|
1872c6 |
client->magic = DNS_CLIENT_MAGIC;
|
|
|
1872c6 |
|
|
|
1872c6 |
*clientp = client;
|
|
|
1872c6 |
|
|
|
1872c6 |
return (ISC_R_SUCCESS);
|
|
|
1872c6 |
|
|
|
1872c6 |
- cleanup:
|
|
|
1872c6 |
+ cleanup_references:
|
|
|
1872c6 |
+ isc_refcount_decrement(&client->references, NULL);
|
|
|
1872c6 |
+ isc_refcount_destroy(&client->references);
|
|
|
1872c6 |
+ cleanup_dispatches:
|
|
|
1872c6 |
if (dispatchv4 != NULL)
|
|
|
1872c6 |
dns_dispatch_detach(&dispatchv4);
|
|
|
1872c6 |
if (dispatchv6 != NULL)
|
|
|
1872c6 |
dns_dispatch_detach(&dispatchv6);
|
|
|
1872c6 |
- if (dispatchmgr != NULL)
|
|
|
1872c6 |
- dns_dispatchmgr_destroy(&dispatchmgr);
|
|
|
1872c6 |
- if (client->task != NULL)
|
|
|
1872c6 |
- isc_task_detach(&client->task);
|
|
|
1872c6 |
+ cleanup_dispatchmgr:
|
|
|
1872c6 |
+ dns_dispatchmgr_destroy(&dispatchmgr);
|
|
|
1872c6 |
+ cleanup_task:
|
|
|
1872c6 |
+ isc_task_detach(&client->task);
|
|
|
1872c6 |
+ cleanup_lock:
|
|
|
1872c6 |
+ DESTROYLOCK(&client->lock);
|
|
|
1872c6 |
+ cleanup_client:
|
|
|
1872c6 |
isc_mem_put(mctx, client, sizeof(*client));
|
|
|
1872c6 |
|
|
|
1872c6 |
return (result);
|
|
|
1872c6 |
}
|
|
|
1872c6 |
|
|
|
1872c6 |
static void
|
|
|
1872c6 |
-destroyclient(dns_client_t **clientp) {
|
|
|
1872c6 |
- dns_client_t *client = *clientp;
|
|
|
1872c6 |
+destroyclient(dns_client_t *client) {
|
|
|
1872c6 |
dns_view_t *view;
|
|
|
1872c6 |
|
|
|
1872c6 |
+ isc_refcount_destroy(&client->references);
|
|
|
1872c6 |
+
|
|
|
1872c6 |
while ((view = ISC_LIST_HEAD(client->viewlist)) != NULL) {
|
|
|
1872c6 |
ISC_LIST_UNLINK(client->viewlist, view, link);
|
|
|
1872c6 |
dns_view_detach(&view);
|
|
|
1872c6 |
@@ -592,32 +610,22 @@ destroyclient(dns_client_t **clientp) {
|
|
|
1872c6 |
client->magic = 0;
|
|
|
1872c6 |
|
|
|
1872c6 |
isc_mem_putanddetach(&client->mctx, client, sizeof(*client));
|
|
|
1872c6 |
-
|
|
|
1872c6 |
- *clientp = NULL;
|
|
|
1872c6 |
}
|
|
|
1872c6 |
|
|
|
1872c6 |
void
|
|
|
1872c6 |
dns_client_destroy(dns_client_t **clientp) {
|
|
|
1872c6 |
dns_client_t *client;
|
|
|
1872c6 |
- isc_boolean_t destroyok = ISC_FALSE;
|
|
|
1872c6 |
+ isc_uint32_t references;
|
|
|
1872c6 |
|
|
|
1872c6 |
REQUIRE(clientp != NULL);
|
|
|
1872c6 |
client = *clientp;
|
|
|
1872c6 |
+ *clientp = NULL;
|
|
|
1872c6 |
REQUIRE(DNS_CLIENT_VALID(client));
|
|
|
1872c6 |
|
|
|
1872c6 |
- LOCK(&client->lock);
|
|
|
1872c6 |
- client->references--;
|
|
|
1872c6 |
- if (client->references == 0 && ISC_LIST_EMPTY(client->resctxs) &&
|
|
|
1872c6 |
- ISC_LIST_EMPTY(client->reqctxs) &&
|
|
|
1872c6 |
- ISC_LIST_EMPTY(client->updatectxs)) {
|
|
|
1872c6 |
- destroyok = ISC_TRUE;
|
|
|
1872c6 |
+ isc_refcount_decrement(&client->references, &references);
|
|
|
1872c6 |
+ if (references == 0U) {
|
|
|
1872c6 |
+ destroyclient(client);
|
|
|
1872c6 |
}
|
|
|
1872c6 |
- UNLOCK(&client->lock);
|
|
|
1872c6 |
-
|
|
|
1872c6 |
- if (destroyok)
|
|
|
1872c6 |
- destroyclient(&client);
|
|
|
1872c6 |
-
|
|
|
1872c6 |
- *clientp = NULL;
|
|
|
1872c6 |
}
|
|
|
1872c6 |
|
|
|
1872c6 |
isc_result_t
|
|
|
1872c6 |
@@ -1407,6 +1415,7 @@ dns_client_startresolve(dns_client_t *client, dns_name_t *name,
|
|
|
1872c6 |
rctx->event = event;
|
|
|
1872c6 |
|
|
|
1872c6 |
rctx->magic = RCTX_MAGIC;
|
|
|
1872c6 |
+ isc_refcount_increment(&client->references, NULL);
|
|
|
1872c6 |
|
|
|
1872c6 |
LOCK(&client->lock);
|
|
|
1872c6 |
ISC_LIST_APPEND(client->resctxs, rctx, link);
|
|
|
1872c6 |
@@ -1477,10 +1486,10 @@ dns_client_destroyrestrans(dns_clientrestrans_t **transp) {
|
|
|
1872c6 |
resctx_t *rctx;
|
|
|
1872c6 |
isc_mem_t *mctx;
|
|
|
1872c6 |
dns_client_t *client;
|
|
|
1872c6 |
- isc_boolean_t need_destroyclient = ISC_FALSE;
|
|
|
1872c6 |
|
|
|
1872c6 |
REQUIRE(transp != NULL);
|
|
|
1872c6 |
rctx = (resctx_t *)*transp;
|
|
|
1872c6 |
+ *transp = NULL;
|
|
|
1872c6 |
REQUIRE(RCTX_VALID(rctx));
|
|
|
1872c6 |
REQUIRE(rctx->fetch == NULL);
|
|
|
1872c6 |
REQUIRE(rctx->event == NULL);
|
|
|
1872c6 |
@@ -1502,11 +1511,6 @@ dns_client_destroyrestrans(dns_clientrestrans_t **transp) {
|
|
|
1872c6 |
INSIST(ISC_LINK_LINKED(rctx, link));
|
|
|
1872c6 |
ISC_LIST_UNLINK(client->resctxs, rctx, link);
|
|
|
1872c6 |
|
|
|
1872c6 |
- if (client->references == 0 && ISC_LIST_EMPTY(client->resctxs) &&
|
|
|
1872c6 |
- ISC_LIST_EMPTY(client->reqctxs) &&
|
|
|
1872c6 |
- ISC_LIST_EMPTY(client->updatectxs))
|
|
|
1872c6 |
- need_destroyclient = ISC_TRUE;
|
|
|
1872c6 |
-
|
|
|
1872c6 |
UNLOCK(&client->lock);
|
|
|
1872c6 |
|
|
|
1872c6 |
INSIST(ISC_LIST_EMPTY(rctx->namelist));
|
|
|
1872c6 |
@@ -1516,10 +1520,8 @@ dns_client_destroyrestrans(dns_clientrestrans_t **transp) {
|
|
|
1872c6 |
|
|
|
1872c6 |
isc_mem_put(mctx, rctx, sizeof(*rctx));
|
|
|
1872c6 |
|
|
|
1872c6 |
- if (need_destroyclient)
|
|
|
1872c6 |
- destroyclient(&client);
|
|
|
1872c6 |
+ dns_client_destroy(&client);
|
|
|
1872c6 |
|
|
|
1872c6 |
- *transp = NULL;
|
|
|
1872c6 |
}
|
|
|
1872c6 |
|
|
|
1872c6 |
isc_result_t
|
|
|
1872c6 |
@@ -1793,6 +1795,7 @@ dns_client_startrequest(dns_client_t *client, dns_message_t *qmessage,
|
|
|
1872c6 |
|
|
|
1872c6 |
LOCK(&client->lock);
|
|
|
1872c6 |
ISC_LIST_APPEND(client->reqctxs, ctx, link);
|
|
|
1872c6 |
+ isc_refcount_increment(&client->references, NULL);
|
|
|
1872c6 |
UNLOCK(&client->lock);
|
|
|
1872c6 |
|
|
|
1872c6 |
ctx->request = NULL;
|
|
|
1872c6 |
@@ -1807,6 +1810,8 @@ dns_client_startrequest(dns_client_t *client, dns_message_t *qmessage,
|
|
|
1872c6 |
return (ISC_R_SUCCESS);
|
|
|
1872c6 |
}
|
|
|
1872c6 |
|
|
|
1872c6 |
+ isc_refcount_decrement(&client->references, NULL);
|
|
|
1872c6 |
+
|
|
|
1872c6 |
cleanup:
|
|
|
1872c6 |
if (ctx != NULL) {
|
|
|
1872c6 |
LOCK(&client->lock);
|
|
|
1872c6 |
@@ -1847,10 +1852,10 @@ dns_client_destroyreqtrans(dns_clientreqtrans_t **transp) {
|
|
|
1872c6 |
reqctx_t *ctx;
|
|
|
1872c6 |
isc_mem_t *mctx;
|
|
|
1872c6 |
dns_client_t *client;
|
|
|
1872c6 |
- isc_boolean_t need_destroyclient = ISC_FALSE;
|
|
|
1872c6 |
|
|
|
1872c6 |
REQUIRE(transp != NULL);
|
|
|
1872c6 |
ctx = (reqctx_t *)*transp;
|
|
|
1872c6 |
+ *transp = NULL;
|
|
|
1872c6 |
REQUIRE(REQCTX_VALID(ctx));
|
|
|
1872c6 |
client = ctx->client;
|
|
|
1872c6 |
REQUIRE(DNS_CLIENT_VALID(client));
|
|
|
1872c6 |
@@ -1865,12 +1870,6 @@ dns_client_destroyreqtrans(dns_clientreqtrans_t **transp) {
|
|
|
1872c6 |
INSIST(ISC_LINK_LINKED(ctx, link));
|
|
|
1872c6 |
ISC_LIST_UNLINK(client->reqctxs, ctx, link);
|
|
|
1872c6 |
|
|
|
1872c6 |
- if (client->references == 0 && ISC_LIST_EMPTY(client->resctxs) &&
|
|
|
1872c6 |
- ISC_LIST_EMPTY(client->reqctxs) &&
|
|
|
1872c6 |
- ISC_LIST_EMPTY(client->updatectxs)) {
|
|
|
1872c6 |
- need_destroyclient = ISC_TRUE;
|
|
|
1872c6 |
- }
|
|
|
1872c6 |
-
|
|
|
1872c6 |
UNLOCK(&client->lock);
|
|
|
1872c6 |
|
|
|
1872c6 |
DESTROYLOCK(&ctx->lock);
|
|
|
1872c6 |
@@ -1878,10 +1877,7 @@ dns_client_destroyreqtrans(dns_clientreqtrans_t **transp) {
|
|
|
1872c6 |
|
|
|
1872c6 |
isc_mem_put(mctx, ctx, sizeof(*ctx));
|
|
|
1872c6 |
|
|
|
1872c6 |
- if (need_destroyclient)
|
|
|
1872c6 |
- destroyclient(&client);
|
|
|
1872c6 |
-
|
|
|
1872c6 |
- *transp = NULL;
|
|
|
1872c6 |
+ dns_client_destroy(&client);
|
|
|
1872c6 |
}
|
|
|
1872c6 |
|
|
|
1872c6 |
/*%
|
|
|
1872c6 |
@@ -2971,6 +2967,7 @@ dns_client_startupdate(dns_client_t *client, dns_rdataclass_t rdclass,
|
|
|
1872c6 |
|
|
|
1872c6 |
LOCK(&client->lock);
|
|
|
1872c6 |
ISC_LIST_APPEND(client->updatectxs, uctx, link);
|
|
|
1872c6 |
+ isc_refcount_increment(&client->references, NULL);
|
|
|
1872c6 |
UNLOCK(&client->lock);
|
|
|
1872c6 |
|
|
|
1872c6 |
*transp = (dns_clientupdatetrans_t *)uctx;
|
|
|
1872c6 |
@@ -2989,6 +2986,8 @@ dns_client_startupdate(dns_client_t *client, dns_rdataclass_t rdclass,
|
|
|
1872c6 |
}
|
|
|
1872c6 |
if (result == ISC_R_SUCCESS)
|
|
|
1872c6 |
return (result);
|
|
|
1872c6 |
+
|
|
|
1872c6 |
+ isc_refcount_decrement(&client->references, NULL);
|
|
|
1872c6 |
*transp = NULL;
|
|
|
1872c6 |
|
|
|
1872c6 |
fail:
|
|
|
1872c6 |
@@ -3046,11 +3045,11 @@ dns_client_destroyupdatetrans(dns_clientupdatetrans_t **transp) {
|
|
|
1872c6 |
updatectx_t *uctx;
|
|
|
1872c6 |
isc_mem_t *mctx;
|
|
|
1872c6 |
dns_client_t *client;
|
|
|
1872c6 |
- isc_boolean_t need_destroyclient = ISC_FALSE;
|
|
|
1872c6 |
isc_sockaddr_t *sa;
|
|
|
1872c6 |
|
|
|
1872c6 |
REQUIRE(transp != NULL);
|
|
|
1872c6 |
uctx = (updatectx_t *)*transp;
|
|
|
1872c6 |
+ *transp = NULL;
|
|
|
1872c6 |
REQUIRE(UCTX_VALID(uctx));
|
|
|
1872c6 |
client = uctx->client;
|
|
|
1872c6 |
REQUIRE(DNS_CLIENT_VALID(client));
|
|
|
1872c6 |
@@ -3071,11 +3070,6 @@ dns_client_destroyupdatetrans(dns_clientupdatetrans_t **transp) {
|
|
|
1872c6 |
INSIST(ISC_LINK_LINKED(uctx, link));
|
|
|
1872c6 |
ISC_LIST_UNLINK(client->updatectxs, uctx, link);
|
|
|
1872c6 |
|
|
|
1872c6 |
- if (client->references == 0 && ISC_LIST_EMPTY(client->resctxs) &&
|
|
|
1872c6 |
- ISC_LIST_EMPTY(client->reqctxs) &&
|
|
|
1872c6 |
- ISC_LIST_EMPTY(client->updatectxs))
|
|
|
1872c6 |
- need_destroyclient = ISC_TRUE;
|
|
|
1872c6 |
-
|
|
|
1872c6 |
UNLOCK(&client->lock);
|
|
|
1872c6 |
|
|
|
1872c6 |
DESTROYLOCK(&uctx->lock);
|
|
|
1872c6 |
@@ -3083,10 +3077,7 @@ dns_client_destroyupdatetrans(dns_clientupdatetrans_t **transp) {
|
|
|
1872c6 |
|
|
|
1872c6 |
isc_mem_put(mctx, uctx, sizeof(*uctx));
|
|
|
1872c6 |
|
|
|
1872c6 |
- if (need_destroyclient)
|
|
|
1872c6 |
- destroyclient(&client);
|
|
|
1872c6 |
-
|
|
|
1872c6 |
- *transp = NULL;
|
|
|
1872c6 |
+ dns_client_destroy(&client);
|
|
|
1872c6 |
}
|
|
|
1872c6 |
|
|
|
1872c6 |
isc_mem_t *
|
|
|
1872c6 |
diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h
|
|
|
1872c6 |
index 7cd88f8377..e383c40f0f 100644
|
|
|
1872c6 |
--- a/lib/dns/include/dns/view.h
|
|
|
1872c6 |
+++ b/lib/dns/include/dns/view.h
|
|
|
1872c6 |
@@ -191,9 +191,9 @@ struct dns_view {
|
|
|
1872c6 |
|
|
|
1872c6 |
/* Locked by themselves. */
|
|
|
1872c6 |
isc_refcount_t references;
|
|
|
1872c6 |
+ isc_refcount_t weakrefs;
|
|
|
1872c6 |
|
|
|
1872c6 |
/* Locked by lock. */
|
|
|
1872c6 |
- unsigned int weakrefs;
|
|
|
1872c6 |
unsigned int attributes;
|
|
|
1872c6 |
/* Under owner's locking control. */
|
|
|
1872c6 |
ISC_LINK(struct dns_view) link;
|
|
|
1872c6 |
diff --git a/lib/dns/view.c b/lib/dns/view.c
|
|
|
1872c6 |
index f53193c3ec..db09c3db6e 100644
|
|
|
1872c6 |
--- a/lib/dns/view.c
|
|
|
1872c6 |
+++ b/lib/dns/view.c
|
|
|
1872c6 |
@@ -155,9 +155,13 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
|
|
|
1872c6 |
view->frozen = ISC_FALSE;
|
|
|
1872c6 |
view->task = NULL;
|
|
|
1872c6 |
result = isc_refcount_init(&view->references, 1);
|
|
|
1872c6 |
- if (result != ISC_R_SUCCESS)
|
|
|
1872c6 |
+ if (result != ISC_R_SUCCESS) {
|
|
|
1872c6 |
goto cleanup_fwdtable;
|
|
|
1872c6 |
- view->weakrefs = 0;
|
|
|
1872c6 |
+ }
|
|
|
1872c6 |
+ result = isc_refcount_init(&view->weakrefs, 1);
|
|
|
1872c6 |
+ if (result != ISC_R_SUCCESS) {
|
|
|
1872c6 |
+ goto cleanup_references;
|
|
|
1872c6 |
+ }
|
|
|
1872c6 |
view->attributes = (DNS_VIEWATTR_RESSHUTDOWN|DNS_VIEWATTR_ADBSHUTDOWN|
|
|
|
1872c6 |
DNS_VIEWATTR_REQSHUTDOWN);
|
|
|
1872c6 |
view->statickeys = NULL;
|
|
|
1872c6 |
@@ -167,7 +171,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
|
|
|
1872c6 |
view->matchrecursiveonly = ISC_FALSE;
|
|
|
1872c6 |
result = dns_tsigkeyring_create(view->mctx, &view->dynamickeys);
|
|
|
1872c6 |
if (result != ISC_R_SUCCESS)
|
|
|
1872c6 |
- goto cleanup_references;
|
|
|
1872c6 |
+ goto cleanup_weakrefs;
|
|
|
1872c6 |
view->peers = NULL;
|
|
|
1872c6 |
view->order = NULL;
|
|
|
1872c6 |
view->delonly = NULL;
|
|
|
1872c6 |
@@ -304,6 +308,10 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
|
|
|
1872c6 |
if (view->dynamickeys != NULL)
|
|
|
1872c6 |
dns_tsigkeyring_detach(&view->dynamickeys);
|
|
|
1872c6 |
|
|
|
1872c6 |
+ cleanup_weakrefs:
|
|
|
1872c6 |
+ isc_refcount_decrement(&view->weakrefs, NULL);
|
|
|
1872c6 |
+ isc_refcount_destroy(&view->weakrefs);
|
|
|
1872c6 |
+
|
|
|
1872c6 |
cleanup_references:
|
|
|
1872c6 |
isc_refcount_destroy(&view->references);
|
|
|
1872c6 |
|
|
|
1872c6 |
@@ -336,12 +344,13 @@ destroy(dns_view_t *view) {
|
|
|
1872c6 |
dns_dlzdb_t *dlzdb;
|
|
|
1872c6 |
|
|
|
1872c6 |
REQUIRE(!ISC_LINK_LINKED(view, link));
|
|
|
1872c6 |
- REQUIRE(isc_refcount_current(&view->references) == 0);
|
|
|
1872c6 |
- REQUIRE(view->weakrefs == 0);
|
|
|
1872c6 |
REQUIRE(RESSHUTDOWN(view));
|
|
|
1872c6 |
REQUIRE(ADBSHUTDOWN(view));
|
|
|
1872c6 |
REQUIRE(REQSHUTDOWN(view));
|
|
|
1872c6 |
|
|
|
1872c6 |
+ isc_refcount_destroy(&view->references);
|
|
|
1872c6 |
+ isc_refcount_destroy(&view->weakrefs);
|
|
|
1872c6 |
+
|
|
|
1872c6 |
if (view->order != NULL)
|
|
|
1872c6 |
dns_order_detach(&view->order);
|
|
|
1872c6 |
if (view->peers != NULL)
|
|
|
1872c6 |
@@ -536,26 +545,12 @@ destroy(dns_view_t *view) {
|
|
|
1872c6 |
DESTROYLOCK(&view->new_zone_lock);
|
|
|
1872c6 |
DESTROYLOCK(&view->lock);
|
|
|
1872c6 |
isc_refcount_destroy(&view->references);
|
|
|
1872c6 |
+ isc_refcount_destroy(&view->weakrefs);
|
|
|
1872c6 |
isc_mem_free(view->mctx, view->nta_file);
|
|
|
1872c6 |
isc_mem_free(view->mctx, view->name);
|
|
|
1872c6 |
isc_mem_putanddetach(&view->mctx, view, sizeof(*view));
|
|
|
1872c6 |
}
|
|
|
1872c6 |
|
|
|
1872c6 |
-/*
|
|
|
1872c6 |
- * Return true iff 'view' may be freed.
|
|
|
1872c6 |
- * The caller must be holding the view lock.
|
|
|
1872c6 |
- */
|
|
|
1872c6 |
-static isc_boolean_t
|
|
|
1872c6 |
-all_done(dns_view_t *view) {
|
|
|
1872c6 |
-
|
|
|
1872c6 |
- if (isc_refcount_current(&view->references) == 0 &&
|
|
|
1872c6 |
- view->weakrefs == 0 &&
|
|
|
1872c6 |
- RESSHUTDOWN(view) && ADBSHUTDOWN(view) && REQSHUTDOWN(view))
|
|
|
1872c6 |
- return (ISC_TRUE);
|
|
|
1872c6 |
-
|
|
|
1872c6 |
- return (ISC_FALSE);
|
|
|
1872c6 |
-}
|
|
|
1872c6 |
-
|
|
|
1872c6 |
void
|
|
|
1872c6 |
dns_view_attach(dns_view_t *source, dns_view_t **targetp) {
|
|
|
1872c6 |
|
|
|
1872c6 |
@@ -571,10 +566,10 @@ static void
|
|
|
1872c6 |
view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) {
|
|
|
1872c6 |
dns_view_t *view;
|
|
|
1872c6 |
unsigned int refs;
|
|
|
1872c6 |
- isc_boolean_t done = ISC_FALSE;
|
|
|
1872c6 |
|
|
|
1872c6 |
REQUIRE(viewp != NULL);
|
|
|
1872c6 |
view = *viewp;
|
|
|
1872c6 |
+ *viewp = NULL;
|
|
|
1872c6 |
REQUIRE(DNS_VIEW_VALID(view));
|
|
|
1872c6 |
|
|
|
1872c6 |
if (flush)
|
|
|
1872c6 |
@@ -613,7 +608,6 @@ view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) {
|
|
|
1872c6 |
if (view->catzs != NULL) {
|
|
|
1872c6 |
dns_catz_catzs_detach(&view->catzs);
|
|
|
1872c6 |
}
|
|
|
1872c6 |
- done = all_done(view);
|
|
|
1872c6 |
UNLOCK(&view->lock);
|
|
|
1872c6 |
|
|
|
1872c6 |
/* Need to detach zones outside view lock */
|
|
|
1872c6 |
@@ -622,12 +616,9 @@ view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) {
|
|
|
1872c6 |
|
|
|
1872c6 |
if (rdzone != NULL)
|
|
|
1872c6 |
dns_zone_detach(&rdzone);
|
|
|
1872c6 |
- }
|
|
|
1872c6 |
-
|
|
|
1872c6 |
- *viewp = NULL;
|
|
|
1872c6 |
|
|
|
1872c6 |
- if (done)
|
|
|
1872c6 |
- destroy(view);
|
|
|
1872c6 |
+ dns_view_weakdetach(&view);
|
|
|
1872c6 |
+ }
|
|
|
1872c6 |
}
|
|
|
1872c6 |
|
|
|
1872c6 |
void
|
|
|
1872c6 |
@@ -661,9 +652,7 @@ dns_view_weakattach(dns_view_t *source, dns_view_t **targetp) {
|
|
|
1872c6 |
REQUIRE(DNS_VIEW_VALID(source));
|
|
|
1872c6 |
REQUIRE(targetp != NULL && *targetp == NULL);
|
|
|
1872c6 |
|
|
|
1872c6 |
- LOCK(&source->lock);
|
|
|
1872c6 |
- source->weakrefs++;
|
|
|
1872c6 |
- UNLOCK(&source->lock);
|
|
|
1872c6 |
+ isc_refcount_increment(&source->weakrefs, NULL);
|
|
|
1872c6 |
|
|
|
1872c6 |
*targetp = source;
|
|
|
1872c6 |
}
|
|
|
1872c6 |
@@ -671,30 +660,22 @@ dns_view_weakattach(dns_view_t *source, dns_view_t **targetp) {
|
|
|
1872c6 |
void
|
|
|
1872c6 |
dns_view_weakdetach(dns_view_t **viewp) {
|
|
|
1872c6 |
dns_view_t *view;
|
|
|
1872c6 |
- isc_boolean_t done = ISC_FALSE;
|
|
|
1872c6 |
+ unsigned int weakrefs;
|
|
|
1872c6 |
|
|
|
1872c6 |
REQUIRE(viewp != NULL);
|
|
|
1872c6 |
view = *viewp;
|
|
|
1872c6 |
REQUIRE(DNS_VIEW_VALID(view));
|
|
|
1872c6 |
-
|
|
|
1872c6 |
- LOCK(&view->lock);
|
|
|
1872c6 |
-
|
|
|
1872c6 |
- INSIST(view->weakrefs > 0);
|
|
|
1872c6 |
- view->weakrefs--;
|
|
|
1872c6 |
- done = all_done(view);
|
|
|
1872c6 |
-
|
|
|
1872c6 |
- UNLOCK(&view->lock);
|
|
|
1872c6 |
-
|
|
|
1872c6 |
*viewp = NULL;
|
|
|
1872c6 |
|
|
|
1872c6 |
- if (done)
|
|
|
1872c6 |
+ isc_refcount_decrement(&view->weakrefs, &weakrefs);
|
|
|
1872c6 |
+ if (weakrefs == 0) {
|
|
|
1872c6 |
destroy(view);
|
|
|
1872c6 |
+ }
|
|
|
1872c6 |
}
|
|
|
1872c6 |
|
|
|
1872c6 |
static void
|
|
|
1872c6 |
resolver_shutdown(isc_task_t *task, isc_event_t *event) {
|
|
|
1872c6 |
dns_view_t *view = event->ev_arg;
|
|
|
1872c6 |
- isc_boolean_t done;
|
|
|
1872c6 |
|
|
|
1872c6 |
REQUIRE(event->ev_type == DNS_EVENT_VIEWRESSHUTDOWN);
|
|
|
1872c6 |
REQUIRE(DNS_VIEW_VALID(view));
|
|
|
1872c6 |
@@ -705,20 +686,15 @@ resolver_shutdown(isc_task_t *task, isc_event_t *event) {
|
|
|
1872c6 |
isc_event_free(&event);
|
|
|
1872c6 |
|
|
|
1872c6 |
LOCK(&view->lock);
|
|
|
1872c6 |
-
|
|
|
1872c6 |
view->attributes |= DNS_VIEWATTR_RESSHUTDOWN;
|
|
|
1872c6 |
- done = all_done(view);
|
|
|
1872c6 |
-
|
|
|
1872c6 |
UNLOCK(&view->lock);
|
|
|
1872c6 |
|
|
|
1872c6 |
- if (done)
|
|
|
1872c6 |
- destroy(view);
|
|
|
1872c6 |
+ dns_view_weakdetach(&view);
|
|
|
1872c6 |
}
|
|
|
1872c6 |
|
|
|
1872c6 |
static void
|
|
|
1872c6 |
adb_shutdown(isc_task_t *task, isc_event_t *event) {
|
|
|
1872c6 |
dns_view_t *view = event->ev_arg;
|
|
|
1872c6 |
- isc_boolean_t done;
|
|
|
1872c6 |
|
|
|
1872c6 |
REQUIRE(event->ev_type == DNS_EVENT_VIEWADBSHUTDOWN);
|
|
|
1872c6 |
REQUIRE(DNS_VIEW_VALID(view));
|
|
|
1872c6 |
@@ -729,20 +705,15 @@ adb_shutdown(isc_task_t *task, isc_event_t *event) {
|
|
|
1872c6 |
isc_event_free(&event);
|
|
|
1872c6 |
|
|
|
1872c6 |
LOCK(&view->lock);
|
|
|
1872c6 |
-
|
|
|
1872c6 |
view->attributes |= DNS_VIEWATTR_ADBSHUTDOWN;
|
|
|
1872c6 |
- done = all_done(view);
|
|
|
1872c6 |
-
|
|
|
1872c6 |
UNLOCK(&view->lock);
|
|
|
1872c6 |
|
|
|
1872c6 |
- if (done)
|
|
|
1872c6 |
- destroy(view);
|
|
|
1872c6 |
+ dns_view_weakdetach(&view);
|
|
|
1872c6 |
}
|
|
|
1872c6 |
|
|
|
1872c6 |
static void
|
|
|
1872c6 |
req_shutdown(isc_task_t *task, isc_event_t *event) {
|
|
|
1872c6 |
dns_view_t *view = event->ev_arg;
|
|
|
1872c6 |
- isc_boolean_t done;
|
|
|
1872c6 |
|
|
|
1872c6 |
REQUIRE(event->ev_type == DNS_EVENT_VIEWREQSHUTDOWN);
|
|
|
1872c6 |
REQUIRE(DNS_VIEW_VALID(view));
|
|
|
1872c6 |
@@ -753,14 +724,10 @@ req_shutdown(isc_task_t *task, isc_event_t *event) {
|
|
|
1872c6 |
isc_event_free(&event);
|
|
|
1872c6 |
|
|
|
1872c6 |
LOCK(&view->lock);
|
|
|
1872c6 |
-
|
|
|
1872c6 |
view->attributes |= DNS_VIEWATTR_REQSHUTDOWN;
|
|
|
1872c6 |
- done = all_done(view);
|
|
|
1872c6 |
-
|
|
|
1872c6 |
UNLOCK(&view->lock);
|
|
|
1872c6 |
|
|
|
1872c6 |
- if (done)
|
|
|
1872c6 |
- destroy(view);
|
|
|
1872c6 |
+ dns_view_weakdetach(&view);
|
|
|
1872c6 |
}
|
|
|
1872c6 |
|
|
|
1872c6 |
isc_result_t
|
|
|
1872c6 |
@@ -809,6 +776,7 @@ dns_view_createresolver(dns_view_t *view,
|
|
|
1872c6 |
event = &view->resevent;
|
|
|
1872c6 |
dns_resolver_whenshutdown(view->resolver, view->task, &event);
|
|
|
1872c6 |
view->attributes &= ~DNS_VIEWATTR_RESSHUTDOWN;
|
|
|
1872c6 |
+ isc_refcount_increment(&view->weakrefs, NULL);
|
|
|
1872c6 |
|
|
|
1872c6 |
result = isc_mem_create(0, 0, &mctx);
|
|
|
1872c6 |
if (result != ISC_R_SUCCESS) {
|
|
|
1872c6 |
@@ -826,6 +794,7 @@ dns_view_createresolver(dns_view_t *view,
|
|
|
1872c6 |
event = &view->adbevent;
|
|
|
1872c6 |
dns_adb_whenshutdown(view->adb, view->task, &event);
|
|
|
1872c6 |
view->attributes &= ~DNS_VIEWATTR_ADBSHUTDOWN;
|
|
|
1872c6 |
+ isc_refcount_increment(&view->weakrefs, NULL);
|
|
|
1872c6 |
|
|
|
1872c6 |
result = dns_requestmgr_create(view->mctx, timermgr, socketmgr,
|
|
|
1872c6 |
dns_resolver_taskmgr(view->resolver),
|
|
|
1872c6 |
@@ -840,6 +809,7 @@ dns_view_createresolver(dns_view_t *view,
|
|
|
1872c6 |
event = &view->reqevent;
|
|
|
1872c6 |
dns_requestmgr_whenshutdown(view->requestmgr, view->task, &event);
|
|
|
1872c6 |
view->attributes &= ~DNS_VIEWATTR_REQSHUTDOWN;
|
|
|
1872c6 |
+ isc_refcount_increment(&view->weakrefs, NULL);
|
|
|
1872c6 |
|
|
|
1872c6 |
return (ISC_R_SUCCESS);
|
|
|
1872c6 |
}
|
|
|
1872c6 |
diff --git a/lib/isc/app_api.c b/lib/isc/app_api.c
|
|
|
1872c6 |
index 5563c7cc0b..40ec2d93b8 100644
|
|
|
1872c6 |
--- a/lib/isc/app_api.c
|
|
|
1872c6 |
+++ b/lib/isc/app_api.c
|
|
|
1872c6 |
@@ -23,6 +23,7 @@
|
|
|
1872c6 |
static isc_mutex_t createlock;
|
|
|
1872c6 |
static isc_once_t once = ISC_ONCE_INIT;
|
|
|
1872c6 |
static isc_appctxcreatefunc_t appctx_createfunc = NULL;
|
|
|
1872c6 |
+static isc_mutex_t runninglock;
|
|
|
1872c6 |
static isc_boolean_t is_running = ISC_FALSE;
|
|
|
1872c6 |
|
|
|
1872c6 |
#define ISCAPI_APPMETHODS_VALID(m) ISC_MAGIC_VALID(m, ISCAPI_APPMETHODS_MAGIC)
|
|
|
1872c6 |
@@ -30,6 +31,7 @@ static isc_boolean_t is_running = ISC_FALSE;
|
|
|
1872c6 |
static void
|
|
|
1872c6 |
initialize(void) {
|
|
|
1872c6 |
RUNTIME_CHECK(isc_mutex_init(&createlock) == ISC_R_SUCCESS);
|
|
|
1872c6 |
+ RUNTIME_CHECK(isc_mutex_init(&runninglock) == ISC_R_SUCCESS);
|
|
|
1872c6 |
}
|
|
|
1872c6 |
|
|
|
1872c6 |
isc_result_t
|
|
|
1872c6 |
@@ -196,9 +198,15 @@ isc_app_run() {
|
|
|
1872c6 |
if (isc_bind9) {
|
|
|
1872c6 |
isc_result_t result;
|
|
|
1872c6 |
|
|
|
1872c6 |
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
|
|
|
1872c6 |
+
|
|
|
1872c6 |
+ LOCK(&runninglock);
|
|
|
1872c6 |
is_running = ISC_TRUE;
|
|
|
1872c6 |
+ UNLOCK(&runninglock);
|
|
|
1872c6 |
result = isc__app_run();
|
|
|
1872c6 |
+ LOCK(&runninglock);
|
|
|
1872c6 |
is_running = ISC_FALSE;
|
|
|
1872c6 |
+ UNLOCK(&runninglock);
|
|
|
1872c6 |
|
|
|
1872c6 |
return (result);
|
|
|
1872c6 |
}
|
|
|
1872c6 |
@@ -208,7 +216,15 @@ isc_app_run() {
|
|
|
1872c6 |
|
|
|
1872c6 |
isc_boolean_t
|
|
|
1872c6 |
isc_app_isrunning() {
|
|
|
1872c6 |
- return (is_running);
|
|
|
1872c6 |
+ isc_boolean_t running;
|
|
|
1872c6 |
+
|
|
|
1872c6 |
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
|
|
|
1872c6 |
+
|
|
|
1872c6 |
+ LOCK(&runninglock);
|
|
|
1872c6 |
+ running = is_running;
|
|
|
1872c6 |
+ UNLOCK(&runninglock);
|
|
|
1872c6 |
+
|
|
|
1872c6 |
+ return (running);
|
|
|
1872c6 |
}
|
|
|
1872c6 |
|
|
|
1872c6 |
isc_result_t
|
|
|
1872c6 |
--
|
|
|
1872c6 |
2.21.1
|
|
|
1872c6 |
|