goto cleanup; \
} while (0)
-static isc_mutex_t dt_mutex;
-static bool dt_initialized = false;
-static isc_thread_key_t dt_key;
-static isc_once_t mutex_once = ISC_ONCE_INIT;
-static isc_mem_t *dt_mctx = NULL;
-/*
- * Change under task exclusive.
- */
-static unsigned int generation;
-
-static void
-mutex_init(void) {
- isc_mutex_init(&dt_mutex);
-}
-
-static void
-dtfree(void *arg) {
- free(arg);
- isc_thread_key_setspecific(dt_key, NULL);
-}
-
-static isc_result_t
-dt_init(void) {
- isc_result_t result;
-
- result = isc_once_do(&mutex_once, mutex_init);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- if (dt_initialized)
- return (ISC_R_SUCCESS);
+typedef struct ioq {
+ unsigned int generation;
+ struct fstrm_iothr_queue *ioq;
+} dt__ioq_t;
- LOCK(&dt_mutex);
- if (!dt_initialized) {
- int ret;
- if (dt_mctx == NULL) {
- isc_mem_create(&dt_mctx);
- }
- isc_mem_setname(dt_mctx, "dt", NULL);
- isc_mem_setdestroycheck(dt_mctx, false);
+ISC_THREAD_LOCAL dt__ioq_t dt_ioq = { 0 };
- ret = isc_thread_key_create(&dt_key, dtfree);
- if (ret == 0)
- dt_initialized = true;
- else
- result = ISC_R_FAILURE;
- }
- UNLOCK(&dt_mutex);
-
- return (result);
-}
+static atomic_uint_fast32_t global_generation;
isc_result_t
dns_dt_create(isc_mem_t *mctx, dns_dtmode_t mode, const char *path,
DNS_LOGMODULE_DNSTAP, ISC_LOG_INFO,
"opening dnstap destination '%s'", path);
- generation++;
+ atomic_fetch_add_release(&global_generation, 1);
env = isc_mem_get(mctx, sizeof(dns_dtenv_t));
(roll < 0) ? "reopening" : "rolling",
env->path);
- generation++;
+ atomic_fetch_add_release(&global_generation, 1);
if (env->iothr != NULL) {
fstrm_iothr_destroy(&env->iothr);
return (toregion(env, &env->version, version));
}
+static void
+set_dt_ioq(unsigned int generation, struct fstrm_iothr_queue *ioq) {
+ dt_ioq.generation = generation;
+ dt_ioq.ioq = ioq;
+}
+
static struct fstrm_iothr_queue *
dt_queue(dns_dtenv_t *env) {
- isc_result_t result;
- struct ioq {
- unsigned int generation;
- struct fstrm_iothr_queue *ioq;
- } *ioq;
-
REQUIRE(VALID_DTENV(env));
- if (env->iothr == NULL)
- return (NULL);
+ unsigned int generation;
- result = dt_init();
- if (result != ISC_R_SUCCESS)
+ if (env->iothr == NULL) {
return (NULL);
+ }
- ioq = (struct ioq *)isc_thread_key_getspecific(dt_key);
- if (ioq != NULL && ioq->generation != generation) {
- result = isc_thread_key_setspecific(dt_key, NULL);
- if (result != ISC_R_SUCCESS)
- return (NULL);
- free(ioq);
- ioq = NULL;
+ generation = atomic_load_acquire(&global_generation);
+ if (dt_ioq.ioq != NULL && dt_ioq.generation != generation) {
+ set_dt_ioq(0, NULL);
}
- if (ioq == NULL) {
- ioq = malloc(sizeof(*ioq));
- if (ioq == NULL)
- return (NULL);
- ioq->generation = generation;
- ioq->ioq = fstrm_iothr_get_input_queue(env->iothr);
- if (ioq->ioq == NULL) {
- free(ioq);
- return (NULL);
- }
- result = isc_thread_key_setspecific(dt_key, ioq);
- if (result != ISC_R_SUCCESS) {
- free(ioq);
- return (NULL);
- }
+ if (dt_ioq.ioq == NULL) {
+ struct fstrm_iothr_queue *ioq =
+ fstrm_iothr_get_input_queue(env->iothr);
+ set_dt_ioq(generation, ioq);
}
- return (ioq->ioq);
+ return (dt_ioq.ioq);
}
void
"closing dnstap");
env->magic = 0;
- generation++;
+ atomic_fetch_add(&global_generation, 1);
if (env->iothr != NULL)
fstrm_iothr_destroy(&env->iothr);
send_dt(view->dtenv, dm.buf, dm.len);
}
-void
-dns_dt_shutdown() {
- if (dt_mctx != NULL)
- isc_mem_detach(&dt_mctx);
-}
-
static isc_result_t
putstr(isc_buffer_t **b, const char *str) {
isc_result_t result;