#include <inttypes.h>
#include <stdbool.h>
+#include <isc/atomic.h>
#include <isc/event.h>
#include <isc/lex.h>
#include <isc/magic.h>
#include <isc/mem.h>
#include <isc/print.h>
+#include <isc/refcount.h>
#include <isc/serial.h>
#include <isc/stdio.h>
#include <isc/stdtime.h>
/* Which fixed buffers we are using? */
unsigned int loop_cnt; /*% records per quantum,
* 0 => all. */
- bool canceled;
- isc_mutex_t lock;
isc_result_t result;
+
+ /* Atomic */
+ isc_refcount_t references;
+ atomic_bool canceled;
+
/* locked by lock */
- uint32_t references;
dns_incctx_t *inc;
uint32_t resign;
isc_stdtime_t now;
REQUIRE(target != NULL && *target == NULL);
REQUIRE(DNS_LCTX_VALID(source));
- LOCK(&source->lock);
- INSIST(source->references > 0);
- source->references++;
- INSIST(source->references != 0); /* Overflow? */
- UNLOCK(&source->lock);
+ isc_refcount_increment(&source->references);
*target = source;
}
void
dns_loadctx_detach(dns_loadctx_t **lctxp) {
dns_loadctx_t *lctx;
- bool need_destroy = false;
REQUIRE(lctxp != NULL);
lctx = *lctxp;
REQUIRE(DNS_LCTX_VALID(lctx));
- LOCK(&lctx->lock);
- INSIST(lctx->references > 0);
- lctx->references--;
- if (lctx->references == 0)
- need_destroy = true;
- UNLOCK(&lctx->lock);
+ *lctxp = NULL;
- if (need_destroy)
+ if (isc_refcount_decrement(&lctx->references) == 1) {
loadctx_destroy(lctx);
- *lctxp = NULL;
+ }
}
static void
if (lctx->task != NULL)
isc_task_detach(&lctx->task);
- isc_mutex_destroy(&lctx->lock);
mctx = NULL;
isc_mem_attach(lctx->mctx, &mctx);
isc_mem_detach(&lctx->mctx);
lctx = isc_mem_get(mctx, sizeof(*lctx));
if (lctx == NULL)
return (ISC_R_NOMEMORY);
- isc_mutex_init(&lctx->lock);
lctx->inc = NULL;
result = incctx_create(mctx, origin, &lctx->inc);
isc_task_attach(task, &lctx->task);
lctx->done = done;
lctx->done_arg = done_arg;
- lctx->canceled = false;
+ atomic_init(&lctx->canceled, false);
lctx->mctx = NULL;
isc_mem_attach(mctx, &lctx->mctx);
- lctx->references = 1; /* Implicit attach. */
+
+ isc_refcount_init(&lctx->references, 1); /* Implicit attach. */
+
lctx->magic = DNS_LCTX_MAGIC;
*lctxp = lctx;
return (ISC_R_SUCCESS);
lctx = event->ev_arg;
REQUIRE(DNS_LCTX_VALID(lctx));
- if (lctx->canceled)
+ if (atomic_load_acquire(&lctx->canceled)) {
result = ISC_R_CANCELED;
- else
+ } else {
result = (lctx->load)(lctx);
+ }
if (result == DNS_R_CONTINUE) {
event->ev_arg = lctx;
isc_task_send(task, &event);
dns_loadctx_cancel(dns_loadctx_t *lctx) {
REQUIRE(DNS_LCTX_VALID(lctx));
- LOCK(&lctx->lock);
- lctx->canceled = true;
- UNLOCK(&lctx->lock);
+ atomic_store_release(&lctx->canceled, true);
}
void