atomic_bool priming;
/* Locked by lock. */
- isc_eventlist_t whenshutdown;
isc_refcount_t activebuckets;
unsigned int spillat; /* clients-per-query */
fctx_minimize_qname(fetchctx_t *fctx);
static void
fctx_destroy(fetchctx_t *fctx, bool exiting);
-static void
-send_shutdown_events(dns_resolver_t *res);
static isc_result_t
ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t minttl,
isc_sockaddr_t *sa = NULL, *next_sa = NULL;
struct tried *tried = NULL;
unsigned int bucketnum;
- bool bucket_empty = false;
REQUIRE(VALID_FCTX(fctx));
REQUIRE(ISC_LIST_EMPTY(fctx->events));
LOCK(&res->buckets[bucketnum].lock);
REQUIRE(fctx->state != fetchstate_active);
-
ISC_LIST_UNLINK(res->buckets[bucketnum].fctxs, fctx, link);
INSIST(atomic_fetch_sub_release(&res->nfctx, 1) > 0);
dec_stats(res, dns_resstatscounter_nfetch);
- if (atomic_load_acquire(&res->buckets[bucketnum].exiting) &&
+ if (exiting && atomic_load_acquire(&res->buckets[bucketnum].exiting) &&
ISC_LIST_EMPTY(res->buckets[bucketnum].fctxs))
{
- bucket_empty = true;
+ isc_refcount_decrement(&res->activebuckets);
}
UNLOCK(&res->buckets[bucketnum].lock);
- if (bucket_empty && exiting &&
- isc_refcount_decrement(&res->activebuckets) == 1) {
- LOCK(&res->lock);
- send_shutdown_events(res);
- UNLOCK(&res->lock);
- }
-
isc_refcount_destroy(&fctx->references);
/*
REQUIRE(atomic_load_acquire(&res->nfctx) == 0);
+ /* These must be run before zeroing the magic number */
+ dns_resolver_reset_algorithms(res);
+ dns_resolver_reset_ds_digests(res);
+ dns_resolver_resetmustbesecure(res);
+
+ res->magic = 0;
+
if (res->querystats != NULL) {
dns_stats_detach(&res->querystats);
}
}
isc_mem_put(res->mctx, a, sizeof(*a));
}
- dns_resolver_reset_algorithms(res);
- dns_resolver_reset_ds_digests(res);
dns_badcache_destroy(&res->badcache);
- dns_resolver_resetmustbesecure(res);
isc_timer_destroy(&res->spillattimer);
- res->magic = 0;
+ dns_view_weakdetach(&res->view);
isc_mem_putanddetach(&res->mctx, res, sizeof(*res));
}
-static void
-send_shutdown_events(dns_resolver_t *res) {
- isc_event_t *event, *next_event;
- isc_task_t *etask;
-
- /*
- * Caller must be holding the resolver lock.
- */
-
- for (event = ISC_LIST_HEAD(res->whenshutdown); event != NULL;
- event = next_event)
- {
- next_event = ISC_LIST_NEXT(event, ev_link);
- ISC_LIST_UNLINK(res->whenshutdown, event, ev_link);
- etask = event->ev_sender;
- event->ev_sender = res;
- isc_task_sendanddetach(&etask, &event);
- }
-}
-
static void
spillattimer_countdown(isc_task_t *task, isc_event_t *event) {
dns_resolver_t *res = event->ev_arg;
.timermgr = timermgr,
.taskmgr = taskmgr,
.dispatchmgr = dispatchmgr,
- .view = view,
.options = options,
.udpsize = DEFAULT_EDNS_BUFSIZE,
.spillatmin = 10,
atomic_init(&res->activebuckets, ntasks);
+ dns_view_weakattach(view, &res->view);
isc_mem_attach(view->mctx, &res->mctx);
res->quotaresp[dns_quotatype_zone] = DNS_R_DROP;
res->quotaresp[dns_quotatype_server] = DNS_R_SERVFAIL;
isc_refcount_init(&res->references, 1);
- ISC_LIST_INIT(res->whenshutdown);
ISC_LIST_INIT(res->alternates);
result = dns_badcache_init(res->mctx, DNS_RESOLVER_BADCACHESIZE,
dns_badcache_destroy(&res->badcache);
cleanup_res:
+ dns_view_weakdetach(&res->view);
isc_mem_putanddetach(&res->mctx, res, sizeof(*res));
return (result);
}
*targetp = source;
}
-void
-dns_resolver_whenshutdown(dns_resolver_t *res, isc_task_t *task,
- isc_event_t **eventp) {
- isc_event_t *event = NULL;
-
- REQUIRE(VALID_RESOLVER(res));
- REQUIRE(eventp != NULL);
-
- event = *eventp;
- *eventp = NULL;
-
- LOCK(&res->lock);
-
- if (atomic_load_acquire(&res->exiting) &&
- atomic_load_acquire(&res->activebuckets) == 0)
- {
- /*
- * We're already shutdown. Send the event.
- */
- event->ev_sender = res;
- isc_task_send(task, &event);
- } else {
- isc_task_attach(task, &(isc_task_t *){ NULL });
- event->ev_sender = task;
- ISC_LIST_APPEND(res->whenshutdown, event, ev_link);
- }
-
- UNLOCK(&res->lock);
-}
-
void
dns_resolver_shutdown(dns_resolver_t *res) {
unsigned int i;
fetchctx_t *fctx;
isc_result_t result;
bool is_false = false;
- bool is_done = false;
REQUIRE(VALID_RESOLVER(res));
}
atomic_store(&res->buckets[i].exiting, true);
if (ISC_LIST_EMPTY(res->buckets[i].fctxs)) {
- if (isc_refcount_decrement(
- &res->activebuckets) == 1) {
- is_done = true;
- }
+ isc_refcount_decrement(&res->activebuckets);
}
UNLOCK(&res->buckets[i].lock);
}
- if (is_done) {
- send_shutdown_events(res);
- }
result = isc_timer_reset(res->spillattimer,
isc_timertype_inactive, NULL, true);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
#define DNS_VIEW_DELONLYHASH 111
#define DNS_VIEW_FAILCACHESIZE 1021
-static void
-resolver_shutdown(isc_task_t *task, isc_event_t *event);
static void
req_shutdown(isc_task_t *task, isc_event_t *event);
ISC_LINK_INIT(view, link);
- ISC_EVENT_INIT(&view->resevent, sizeof(view->resevent), 0, NULL,
- DNS_EVENT_VIEWRESSHUTDOWN, resolver_shutdown, view, NULL,
- NULL, NULL);
ISC_EVENT_INIT(&view->reqevent, sizeof(view->reqevent), 0, NULL,
DNS_EVENT_VIEWREQSHUTDOWN, req_shutdown, view, NULL,
NULL, NULL);
if (view->resolver != NULL) {
dns_resolver_shutdown(view->resolver);
+ dns_resolver_detach(&view->resolver);
}
if (view->adb != NULL) {
dns_adb_shutdown(view->adb);
}
}
-static void
-resolver_shutdown(isc_task_t *task, isc_event_t *event) {
- dns_view_t *view = event->ev_arg;
-
- REQUIRE(event->ev_type == DNS_EVENT_VIEWRESSHUTDOWN);
- REQUIRE(DNS_VIEW_VALID(view));
- REQUIRE(view->task == task);
-
- UNUSED(task);
-
- isc_event_free(&event);
-
- dns_view_weakdetach(&view);
-}
-
static void
req_shutdown(isc_task_t *task, isc_event_t *event) {
dns_view_t *view = event->ev_arg;
return (result);
}
- dns_view_weakattach(view, &(dns_view_t *){ NULL });
- event = &view->resevent;
- dns_resolver_whenshutdown(view->resolver, view->task, &event);
-
isc_mem_create(&mctx);
isc_mem_setname(mctx, "ADB");
result = dns_adb_create(mctx, view, taskmgr, &view->adb);
isc_mem_detach(&mctx);
if (result != ISC_R_SUCCESS) {
- dns_resolver_shutdown(view->resolver);
- return (result);
+ goto cleanup_resolver;
}
result = dns_requestmgr_create(
dns_resolver_dispatchmgr(view->resolver), dispatchv4,
dispatchv6, &view->requestmgr);
if (result != ISC_R_SUCCESS) {
- dns_adb_shutdown(view->adb);
- dns_adb_detach(&view->adb);
- dns_resolver_shutdown(view->resolver);
- return (result);
+ goto cleanup_adb;
}
dns_view_weakattach(view, &(dns_view_t *){ NULL });
dns_requestmgr_whenshutdown(view->requestmgr, view->task, &event);
return (ISC_R_SUCCESS);
+
+cleanup_adb:
+ dns_adb_shutdown(view->adb);
+ dns_adb_detach(&view->adb);
+
+cleanup_resolver:
+ dns_resolver_shutdown(view->resolver);
+ dns_resolver_detach(&view->resolver);
+
+ return (result);
}
void