isc_refcount_t references;
atomic_uint_fast32_t zspill; /* fetches-per-zone */
atomic_bool exiting;
+ atomic_bool priming;
/* Locked by lock. */
isc_eventlist_t whenshutdown;
unsigned int activebuckets;
- bool priming;
unsigned int spillat; /* clients-per-query */
dns_badcache_t *badcache; /* Bad cache. */
alternate_t *a;
REQUIRE(atomic_load(&res->references) == 0);
- REQUIRE(!res->priming);
+ REQUIRE(!atomic_load_acquire(&res->priming));
REQUIRE(res->primefetch == NULL);
RTRACE("destroy");
atomic_init(&res->exiting, false);
res->frozen = false;
ISC_LIST_INIT(res->whenshutdown);
- res->priming = false;
+ atomic_init(&res->priming, false);
res->primefetch = NULL;
atomic_init(&res->nfctx, 0);
UNUSED(task);
- LOCK(&res->lock);
-
- INSIST(res->priming);
- res->priming = false;
LOCK(&res->primelock);
fetch = res->primefetch;
res->primefetch = NULL;
UNLOCK(&res->primelock);
- UNLOCK(&res->lock);
+ INSIST(atomic_compare_exchange_strong_acq_rel(&res->priming,
+ &(bool){ true }, false));
if (fevent->result == ISC_R_SUCCESS && res->view->cache != NULL &&
res->view->hints != NULL)
RTRACE("dns_resolver_prime");
- LOCK(&res->lock);
-
- /* XXXOND: cas needs to be used here */
- if (!atomic_load_acquire(&res->exiting) && !res->priming) {
- INSIST(res->primefetch == NULL);
- res->priming = true;
- want_priming = true;
+ if (!atomic_load_acquire(&res->exiting)) {
+ want_priming = atomic_compare_exchange_strong_acq_rel(
+ &res->priming, &(bool){ false }, true);
}
- UNLOCK(&res->lock);
-
if (want_priming) {
/*
* To avoid any possible recursive locking problems, we
RTRACE("priming");
rdataset = isc_mem_get(res->mctx, sizeof(*rdataset));
dns_rdataset_init(rdataset);
+
LOCK(&res->primelock);
+ INSIST(res->primefetch == NULL);
result = dns_resolver_createfetch(
res, dns_rootname, dns_rdatatype_ns, NULL, NULL, NULL,
NULL, 0, DNS_FETCHOPT_NOFORWARD, 0, NULL,
res->buckets[0].task, prime_done, res, rdataset, NULL,
&res->primefetch);
UNLOCK(&res->primelock);
+
if (result != ISC_R_SUCCESS) {
isc_mem_put(res->mctx, rdataset, sizeof(*rdataset));
- LOCK(&res->lock);
- INSIST(res->priming);
- res->priming = false;
- UNLOCK(&res->lock);
+ INSIST(atomic_compare_exchange_strong_acq_rel(
+ &res->priming, &(bool){ true }, false));
}
inc_stats(res, dns_resstatscounter_priming);
}
#define atomic_compare_exchange_strong_relaxed(o, e, d) \
atomic_compare_exchange_strong_explicit( \
(o), (e), (d), memory_order_relaxed, memory_order_relaxed)
-#define atomic_compare_exchange_strong_acq_rel(o, e, d) \
+#define atomic_compare_exchange_strong_acq_rel(o, e, d) \
atomic_compare_exchange_strong_explicit( \
(o), (e), (d), memory_order_acq_rel, memory_order_acquire)
do { \
if ((elt)->link.next != NULL) \
(elt)->link.next->link.prev = (elt)->link.prev; \
- else { \
+ else \
+ { \
ISC_INSIST((list).tail == (elt)); \
(list).tail = (elt)->link.prev; \
} \
if ((elt)->link.prev != NULL) \
(elt)->link.prev->link.next = (elt)->link.next; \
- else { \
+ else \
+ { \
ISC_INSIST((list).head == (elt)); \
(list).head = (elt)->link.next; \
} \
do { \
if ((before)->link.prev == NULL) \
ISC_LIST_PREPEND(list, elt, link); \
- else { \
+ else \
+ { \
(elt)->link.prev = (before)->link.prev; \
(before)->link.prev = (elt); \
(elt)->link.prev->link.next = (elt); \
do { \
if ((after)->link.next == NULL) \
ISC_LIST_APPEND(list, elt, link); \
- else { \
+ else \
+ { \
(elt)->link.next = (after)->link.next; \
(after)->link.next = (elt); \
(elt)->link.next->link.prev = (elt); \
do { \
if (ISC_LIST_EMPTY(list1)) \
(list1) = (list2); \
- else if (!ISC_LIST_EMPTY(list2)) { \
+ else if (!ISC_LIST_EMPTY(list2)) \
+ { \
(list1).tail->link.next = (list2).head; \
(list2).head->link.prev = (list1).tail; \
(list1).tail = (list2).tail; \
do { \
if (ISC_LIST_EMPTY(list1)) \
(list1) = (list2); \
- else if (!ISC_LIST_EMPTY(list2)) { \
+ else if (!ISC_LIST_EMPTY(list2)) \
+ { \
(list2).tail->link.next = (list1).head; \
(list1).head->link.prev = (list2).tail; \
(list1).head = (list2).head; \