Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a0ace46001 | ||
|
|
c820513491 |
+22
-21
@@ -19,6 +19,7 @@
|
||||
#include <isc/json.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/print.h>
|
||||
#include <isc/refcount.h>
|
||||
#include <isc/string.h>
|
||||
#include <isc/stats.h>
|
||||
#include <isc/task.h>
|
||||
@@ -127,8 +128,10 @@ struct dns_cache {
|
||||
isc_mem_t *hmctx; /* Heap memory */
|
||||
char *name;
|
||||
|
||||
/* Atomic counter */
|
||||
isc_refcount_t references;
|
||||
|
||||
/* Locked by 'lock'. */
|
||||
int references;
|
||||
int live_tasks;
|
||||
dns_rdataclass_t rdclass;
|
||||
dns_db_t *db;
|
||||
@@ -213,7 +216,8 @@ dns_cache_create(isc_mem_t *cmctx, isc_mem_t *hmctx, isc_taskmgr_t *taskmgr,
|
||||
isc_mutex_init(&cache->lock);
|
||||
isc_mutex_init(&cache->filelock);
|
||||
|
||||
cache->references = 1;
|
||||
isc_refcount_init(&cache->references, 1);
|
||||
|
||||
cache->live_tasks = 0;
|
||||
cache->rdclass = rdclass;
|
||||
cache->serve_stale_ttl = 0;
|
||||
@@ -336,7 +340,7 @@ cache_free(dns_cache_t *cache) {
|
||||
int i;
|
||||
|
||||
REQUIRE(VALID_CACHE(cache));
|
||||
REQUIRE(cache->references == 0);
|
||||
REQUIRE(isc_refcount_current(&cache->references) == 0);
|
||||
|
||||
isc_mem_setwater(cache->mctx, NULL, NULL, 0, 0);
|
||||
|
||||
@@ -401,33 +405,28 @@ dns_cache_attach(dns_cache_t *cache, dns_cache_t **targetp) {
|
||||
REQUIRE(VALID_CACHE(cache));
|
||||
REQUIRE(targetp != NULL && *targetp == NULL);
|
||||
|
||||
LOCK(&cache->lock);
|
||||
cache->references++;
|
||||
UNLOCK(&cache->lock);
|
||||
isc_refcount_increment(&cache->references);
|
||||
|
||||
*targetp = cache;
|
||||
}
|
||||
|
||||
void
|
||||
dns_cache_detach(dns_cache_t **cachep) {
|
||||
dns_cache_t *cache;
|
||||
bool free_cache = false;
|
||||
dns_cache_t *cache;
|
||||
|
||||
REQUIRE(cachep != NULL);
|
||||
cache = *cachep;
|
||||
REQUIRE(VALID_CACHE(cache));
|
||||
REQUIRE(VALID_CACHE(*cachep));
|
||||
|
||||
LOCK(&cache->lock);
|
||||
REQUIRE(cache->references > 0);
|
||||
cache->references--;
|
||||
if (cache->references == 0) {
|
||||
cache->cleaner.overmem = false;
|
||||
free_cache = true;
|
||||
}
|
||||
cache = *cachep;
|
||||
|
||||
*cachep = NULL;
|
||||
|
||||
if (free_cache) {
|
||||
/* XXXOND: Is the lock here needed? */
|
||||
LOCK(&cache->lock);
|
||||
if (isc_refcount_decrement(&cache->references) == 1) {
|
||||
free_cache = true;
|
||||
cache->cleaner.overmem = false;
|
||||
/*
|
||||
* When the cache is shut down, dump it to a file if one is
|
||||
* specified.
|
||||
@@ -447,11 +446,11 @@ dns_cache_detach(dns_cache_t **cachep) {
|
||||
free_cache = false;
|
||||
}
|
||||
}
|
||||
|
||||
UNLOCK(&cache->lock);
|
||||
|
||||
if (free_cache)
|
||||
if (free_cache) {
|
||||
cache_free(cache);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1120,8 +1119,9 @@ cleaner_shutdown_action(isc_task_t *task, isc_event_t *event) {
|
||||
cache->live_tasks--;
|
||||
INSIST(cache->live_tasks == 0);
|
||||
|
||||
if (cache->references == 0)
|
||||
if (isc_refcount_current(&cache->references) == 0) {
|
||||
should_free = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* By detaching the timer in the context of its task,
|
||||
@@ -1136,8 +1136,9 @@ cleaner_shutdown_action(isc_task_t *task, isc_event_t *event) {
|
||||
|
||||
UNLOCK(&cache->lock);
|
||||
|
||||
if (should_free)
|
||||
if (should_free) {
|
||||
cache_free(cache);
|
||||
}
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
|
||||
+9
-28
@@ -25,10 +25,9 @@ struct dns_dbtable {
|
||||
unsigned int magic;
|
||||
isc_mem_t * mctx;
|
||||
dns_rdataclass_t rdclass;
|
||||
isc_mutex_t lock;
|
||||
isc_rwlock_t tree_lock;
|
||||
/* Locked by lock. */
|
||||
unsigned int references;
|
||||
/* Atomic counter */
|
||||
isc_refcount_t references;
|
||||
/* Locked by tree_lock. */
|
||||
dns_rbt_t * rbt;
|
||||
dns_db_t * default_db;
|
||||
@@ -65,8 +64,6 @@ dns_dbtable_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto clean1;
|
||||
|
||||
isc_mutex_init(&dbtable->lock);
|
||||
|
||||
result = isc_rwlock_init(&dbtable->tree_lock, 0, 0);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto clean3;
|
||||
@@ -76,15 +73,14 @@ dns_dbtable_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
|
||||
isc_mem_attach(mctx, &dbtable->mctx);
|
||||
dbtable->rdclass = rdclass;
|
||||
dbtable->magic = DBTABLE_MAGIC;
|
||||
dbtable->references = 1;
|
||||
|
||||
isc_refcount_init(&dbtable->references, 1);
|
||||
|
||||
*dbtablep = dbtable;
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
clean3:
|
||||
isc_mutex_destroy(&dbtable->lock);
|
||||
|
||||
dns_rbt_destroy(&dbtable->rbt);
|
||||
|
||||
clean1:
|
||||
@@ -120,13 +116,7 @@ dns_dbtable_attach(dns_dbtable_t *source, dns_dbtable_t **targetp) {
|
||||
REQUIRE(VALID_DBTABLE(source));
|
||||
REQUIRE(targetp != NULL && *targetp == NULL);
|
||||
|
||||
LOCK(&source->lock);
|
||||
|
||||
INSIST(source->references > 0);
|
||||
source->references++;
|
||||
INSIST(source->references != 0);
|
||||
|
||||
UNLOCK(&source->lock);
|
||||
isc_refcount_increment(&source->references);
|
||||
|
||||
*targetp = source;
|
||||
}
|
||||
@@ -134,25 +124,16 @@ dns_dbtable_attach(dns_dbtable_t *source, dns_dbtable_t **targetp) {
|
||||
void
|
||||
dns_dbtable_detach(dns_dbtable_t **dbtablep) {
|
||||
dns_dbtable_t *dbtable;
|
||||
bool free_dbtable = false;
|
||||
|
||||
REQUIRE(dbtablep != NULL);
|
||||
dbtable = *dbtablep;
|
||||
REQUIRE(VALID_DBTABLE(dbtable));
|
||||
|
||||
LOCK(&dbtable->lock);
|
||||
|
||||
INSIST(dbtable->references > 0);
|
||||
dbtable->references--;
|
||||
if (dbtable->references == 0)
|
||||
free_dbtable = true;
|
||||
|
||||
UNLOCK(&dbtable->lock);
|
||||
|
||||
if (free_dbtable)
|
||||
dbtable_free(dbtable);
|
||||
|
||||
*dbtablep = NULL;
|
||||
|
||||
if (isc_refcount_decrement(&dbtable->references) == 1) {
|
||||
dbtable_free(dbtable);
|
||||
}
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
|
||||
+27
-38
@@ -11,6 +11,7 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <isc/refcount.h>
|
||||
#include <isc/result.h>
|
||||
#include <isc/util.h>
|
||||
#include <isc/mutex.h>
|
||||
@@ -43,8 +44,10 @@ typedef struct dns_ecdb {
|
||||
dns_db_t common;
|
||||
isc_mutex_t lock;
|
||||
|
||||
/* Atomic */
|
||||
isc_refcount_t references;
|
||||
|
||||
/* Locked */
|
||||
unsigned int references;
|
||||
ISC_LIST(struct dns_ecdbnode) nodes;
|
||||
} dns_ecdb_t;
|
||||
|
||||
@@ -56,9 +59,11 @@ typedef struct dns_ecdbnode {
|
||||
dns_name_t name;
|
||||
ISC_LINK(struct dns_ecdbnode) link;
|
||||
|
||||
/* Atomic */
|
||||
isc_refcount_t references;
|
||||
|
||||
/* Locked */
|
||||
ISC_LIST(struct rdatasetheader) rdatasets;
|
||||
unsigned int references;
|
||||
} dns_ecdbnode_t;
|
||||
|
||||
typedef struct rdatasetheader {
|
||||
@@ -156,9 +161,7 @@ attach(dns_db_t *source, dns_db_t **targetp) {
|
||||
REQUIRE(VALID_ECDB(ecdb));
|
||||
REQUIRE(targetp != NULL && *targetp == NULL);
|
||||
|
||||
LOCK(&ecdb->lock);
|
||||
ecdb->references++;
|
||||
UNLOCK(&ecdb->lock);
|
||||
isc_refcount_increment(&ecdb->references);
|
||||
|
||||
*targetp = source;
|
||||
}
|
||||
@@ -184,22 +187,17 @@ destroy_ecdb(dns_ecdb_t **ecdbp) {
|
||||
static void
|
||||
detach(dns_db_t **dbp) {
|
||||
dns_ecdb_t *ecdb;
|
||||
bool need_destroy = false;
|
||||
|
||||
REQUIRE(dbp != NULL);
|
||||
ecdb = (dns_ecdb_t *)*dbp;
|
||||
REQUIRE(VALID_ECDB(ecdb));
|
||||
|
||||
LOCK(&ecdb->lock);
|
||||
ecdb->references--;
|
||||
if (ecdb->references == 0 && ISC_LIST_EMPTY(ecdb->nodes))
|
||||
need_destroy = true;
|
||||
UNLOCK(&ecdb->lock);
|
||||
|
||||
if (need_destroy)
|
||||
destroy_ecdb(&ecdb);
|
||||
|
||||
*dbp = NULL;
|
||||
|
||||
if (isc_refcount_decrement(&ecdb->references) == 1) {
|
||||
destroy_ecdb(&ecdb);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -211,11 +209,7 @@ attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) {
|
||||
REQUIRE(VALID_ECDBNODE(node));
|
||||
REQUIRE(targetp != NULL && *targetp == NULL);
|
||||
|
||||
LOCK(&node->lock);
|
||||
INSIST(node->references > 0);
|
||||
node->references++;
|
||||
INSIST(node->references != 0); /* Catch overflow. */
|
||||
UNLOCK(&node->lock);
|
||||
isc_refcount_increment(&node->references);
|
||||
|
||||
*targetp = node;
|
||||
}
|
||||
@@ -231,8 +225,10 @@ destroynode(dns_ecdbnode_t *node) {
|
||||
|
||||
LOCK(&ecdb->lock);
|
||||
ISC_LIST_UNLINK(ecdb->nodes, node, link);
|
||||
if (ecdb->references == 0 && ISC_LIST_EMPTY(ecdb->nodes))
|
||||
if (isc_refcount_current(&ecdb->references) == 0 &&
|
||||
ISC_LIST_EMPTY(ecdb->nodes)) {
|
||||
need_destroydb = true;
|
||||
}
|
||||
UNLOCK(&ecdb->lock);
|
||||
|
||||
dns_name_free(&node->name, mctx);
|
||||
@@ -260,26 +256,17 @@ static void
|
||||
detachnode(dns_db_t *db, dns_dbnode_t **nodep) {
|
||||
dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
|
||||
dns_ecdbnode_t *node;
|
||||
bool need_destroy = false;
|
||||
|
||||
REQUIRE(VALID_ECDB(ecdb));
|
||||
REQUIRE(nodep != NULL);
|
||||
node = (dns_ecdbnode_t *)*nodep;
|
||||
REQUIRE(VALID_ECDBNODE(node));
|
||||
|
||||
UNUSED(ecdb); /* in case REQUIRE() is empty */
|
||||
|
||||
LOCK(&node->lock);
|
||||
INSIST(node->references > 0);
|
||||
node->references--;
|
||||
if (node->references == 0)
|
||||
need_destroy = true;
|
||||
UNLOCK(&node->lock);
|
||||
|
||||
if (need_destroy)
|
||||
destroynode(node);
|
||||
|
||||
*nodep = NULL;
|
||||
|
||||
if (isc_refcount_decrement(&node->references) == 1) {
|
||||
destroynode(node);
|
||||
}
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
@@ -362,7 +349,9 @@ findnode(dns_db_t *db, const dns_name_t *name, bool create,
|
||||
return (result);
|
||||
}
|
||||
node->ecdb= ecdb;
|
||||
node->references = 1;
|
||||
|
||||
isc_refcount_init(&node->references, 1);
|
||||
|
||||
ISC_LIST_INIT(node->rdatasets);
|
||||
|
||||
ISC_LINK_INIT(node, link);
|
||||
@@ -413,8 +402,7 @@ bind_rdataset(dns_ecdb_t *ecdb, dns_ecdbnode_t *node,
|
||||
rdataset->privateuint4 = 0;
|
||||
rdataset->private5 = NULL;
|
||||
|
||||
INSIST(node->references > 0);
|
||||
node->references++;
|
||||
isc_refcount_increment(&node->references);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
@@ -618,7 +606,8 @@ dns_ecdb_create(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type,
|
||||
|
||||
isc_mutex_init(&ecdb->lock);
|
||||
|
||||
ecdb->references = 1;
|
||||
isc_refcount_init(&ecdb->references, 1);
|
||||
|
||||
ISC_LIST_INIT(ecdb->nodes);
|
||||
|
||||
ecdb->common.mctx = NULL;
|
||||
|
||||
@@ -50,8 +50,11 @@ struct dns_ntatable {
|
||||
isc_taskmgr_t *taskmgr;
|
||||
isc_timermgr_t *timermgr;
|
||||
isc_task_t *task;
|
||||
|
||||
/* Atomic */
|
||||
isc_refcount_t references;
|
||||
|
||||
/* Locked by rwlock. */
|
||||
uint32_t references;
|
||||
dns_rbt_t *table;
|
||||
};
|
||||
|
||||
|
||||
@@ -67,7 +67,9 @@ struct dns_tsig_keyring {
|
||||
unsigned int generated;
|
||||
unsigned int maxgenerated;
|
||||
ISC_LIST(dns_tsigkey_t) lru;
|
||||
unsigned int references;
|
||||
|
||||
/* Atomic */
|
||||
isc_refcount_t references;
|
||||
};
|
||||
|
||||
struct dns_tsigkey {
|
||||
|
||||
+16
-24
@@ -17,6 +17,7 @@
|
||||
#include <isc/hash.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/mutex.h>
|
||||
#include <isc/refcount.h>
|
||||
#include <isc/once.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
@@ -43,8 +44,7 @@ static isc_once_t init_once = ISC_ONCE_INIT;
|
||||
static isc_mem_t *dns_g_mctx = NULL;
|
||||
static dns_dbimplementation_t *dbimp = NULL;
|
||||
static bool initialize_done = false;
|
||||
static isc_mutex_t reflock;
|
||||
static unsigned int references = 0;
|
||||
static isc_refcount_t references = 0;
|
||||
|
||||
static void
|
||||
initialize(void) {
|
||||
@@ -64,8 +64,6 @@ initialize(void) {
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_db;
|
||||
|
||||
isc_mutex_init(&reflock);
|
||||
|
||||
initialize_done = true;
|
||||
return;
|
||||
|
||||
@@ -87,35 +85,29 @@ dns_lib_init(void) {
|
||||
* abort, on any failure.
|
||||
*/
|
||||
result = isc_once_do(&init_once, initialize);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
|
||||
if (!initialize_done)
|
||||
if (!initialize_done) {
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
|
||||
LOCK(&reflock);
|
||||
references++;
|
||||
UNLOCK(&reflock);
|
||||
isc_refcount_increment0(&references);
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
void
|
||||
dns_lib_shutdown(void) {
|
||||
bool cleanup_ok = false;
|
||||
if (isc_refcount_decrement(&references) == 1) {
|
||||
dst_lib_destroy();
|
||||
|
||||
LOCK(&reflock);
|
||||
if (--references == 0)
|
||||
cleanup_ok = true;
|
||||
UNLOCK(&reflock);
|
||||
|
||||
if (!cleanup_ok)
|
||||
return;
|
||||
|
||||
dst_lib_destroy();
|
||||
|
||||
if (dbimp != NULL)
|
||||
dns_ecdb_unregister(&dbimp);
|
||||
if (dns_g_mctx != NULL)
|
||||
isc_mem_detach(&dns_g_mctx);
|
||||
if (dbimp != NULL) {
|
||||
dns_ecdb_unregister(&dbimp);
|
||||
}
|
||||
if (dns_g_mctx != NULL) {
|
||||
isc_mem_detach(&dns_g_mctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+20
-27
@@ -14,11 +14,13 @@
|
||||
#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>
|
||||
@@ -136,11 +138,13 @@ struct dns_loadctx {
|
||||
/* 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;
|
||||
@@ -389,11 +393,7 @@ dns_loadctx_attach(dns_loadctx_t *source, dns_loadctx_t **target) {
|
||||
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;
|
||||
}
|
||||
@@ -401,22 +401,16 @@ dns_loadctx_attach(dns_loadctx_t *source, dns_loadctx_t **target) {
|
||||
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);
|
||||
|
||||
if (need_destroy)
|
||||
loadctx_destroy(lctx);
|
||||
*lctxp = NULL;
|
||||
|
||||
if (isc_refcount_decrement(&lctx->references) == 1) {
|
||||
loadctx_destroy(lctx);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -461,7 +455,6 @@ loadctx_destroy(dns_loadctx_t *lctx) {
|
||||
|
||||
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);
|
||||
@@ -532,7 +525,6 @@ loadctx_create(dns_masterformat_t format, isc_mem_t *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);
|
||||
@@ -613,10 +605,12 @@ loadctx_create(dns_masterformat_t format, isc_mem_t *mctx,
|
||||
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);
|
||||
@@ -3099,10 +3093,11 @@ load_quantum(isc_task_t *task, isc_event_t *event) {
|
||||
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);
|
||||
@@ -3130,9 +3125,7 @@ void
|
||||
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
|
||||
|
||||
+16
-24
@@ -15,11 +15,13 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <isc/atomic.h>
|
||||
#include <isc/buffer.h>
|
||||
#include <isc/event.h>
|
||||
#include <isc/file.h>
|
||||
#include <isc/magic.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/refcount.h>
|
||||
#include <isc/print.h>
|
||||
#include <isc/stdio.h>
|
||||
#include <isc/string.h>
|
||||
@@ -221,10 +223,10 @@ struct dns_dumpctx {
|
||||
unsigned int magic;
|
||||
isc_mem_t *mctx;
|
||||
isc_mutex_t lock;
|
||||
unsigned int references;
|
||||
bool canceled;
|
||||
bool first;
|
||||
bool do_date;
|
||||
isc_refcount_t references;
|
||||
atomic_bool canceled;
|
||||
bool first;
|
||||
bool do_date;
|
||||
isc_stdtime_t now;
|
||||
FILE *f;
|
||||
dns_db_t *db;
|
||||
@@ -1291,11 +1293,7 @@ dns_dumpctx_attach(dns_dumpctx_t *source, dns_dumpctx_t **target) {
|
||||
REQUIRE(DNS_DCTX_VALID(source));
|
||||
REQUIRE(target != NULL && *target == NULL);
|
||||
|
||||
LOCK(&source->lock);
|
||||
INSIST(source->references > 0);
|
||||
source->references++;
|
||||
INSIST(source->references != 0); /* Overflow? */
|
||||
UNLOCK(&source->lock);
|
||||
isc_refcount_increment(&source->references);
|
||||
|
||||
*target = source;
|
||||
}
|
||||
@@ -1303,7 +1301,6 @@ dns_dumpctx_attach(dns_dumpctx_t *source, dns_dumpctx_t **target) {
|
||||
void
|
||||
dns_dumpctx_detach(dns_dumpctx_t **dctxp) {
|
||||
dns_dumpctx_t *dctx;
|
||||
bool need_destroy = false;
|
||||
|
||||
REQUIRE(dctxp != NULL);
|
||||
dctx = *dctxp;
|
||||
@@ -1311,14 +1308,9 @@ dns_dumpctx_detach(dns_dumpctx_t **dctxp) {
|
||||
|
||||
*dctxp = NULL;
|
||||
|
||||
LOCK(&dctx->lock);
|
||||
INSIST(dctx->references != 0);
|
||||
dctx->references--;
|
||||
if (dctx->references == 0)
|
||||
need_destroy = true;
|
||||
UNLOCK(&dctx->lock);
|
||||
if (need_destroy)
|
||||
if (isc_refcount_decrement(&dctx->references) == 1) {
|
||||
dumpctx_destroy(dctx);
|
||||
}
|
||||
}
|
||||
|
||||
dns_dbversion_t *
|
||||
@@ -1337,9 +1329,7 @@ void
|
||||
dns_dumpctx_cancel(dns_dumpctx_t *dctx) {
|
||||
REQUIRE(DNS_DCTX_VALID(dctx));
|
||||
|
||||
LOCK(&dctx->lock);
|
||||
dctx->canceled = true;
|
||||
UNLOCK(&dctx->lock);
|
||||
atomic_store_release(&dctx->canceled, true);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
@@ -1421,10 +1411,11 @@ dump_quantum(isc_task_t *task, isc_event_t *event) {
|
||||
REQUIRE(event != NULL);
|
||||
dctx = event->ev_arg;
|
||||
REQUIRE(DNS_DCTX_VALID(dctx));
|
||||
if (dctx->canceled)
|
||||
if (atomic_load_acquire(&dctx->canceled)) {
|
||||
result = ISC_R_CANCELED;
|
||||
else
|
||||
} else {
|
||||
result = dumptostreaminc(dctx);
|
||||
}
|
||||
if (result == DNS_R_CONTINUE) {
|
||||
event->ev_arg = dctx;
|
||||
isc_task_send(task, &event);
|
||||
@@ -1478,7 +1469,7 @@ dumpctx_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
|
||||
dctx->task = NULL;
|
||||
dctx->nodes = 0;
|
||||
dctx->first = true;
|
||||
dctx->canceled = false;
|
||||
atomic_init(&dctx->canceled, false);
|
||||
dctx->file = NULL;
|
||||
dctx->tmpfile = NULL;
|
||||
dctx->format = format;
|
||||
@@ -1540,7 +1531,8 @@ dumpctx_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
|
||||
else if (!dns_db_iscache(db))
|
||||
dns_db_currentversion(dctx->db, &dctx->version);
|
||||
isc_mem_attach(mctx, &dctx->mctx);
|
||||
dctx->references = 1;
|
||||
|
||||
isc_refcount_init(&dctx->references, 1);
|
||||
dctx->magic = DNS_DCTX_MAGIC;
|
||||
*dctxp = dctx;
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
+11
-30
@@ -18,6 +18,7 @@
|
||||
#include <isc/log.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/print.h>
|
||||
#include <isc/refcount.h>
|
||||
#include <isc/rwlock.h>
|
||||
#include <isc/string.h>
|
||||
#include <isc/task.h>
|
||||
@@ -40,7 +41,7 @@ struct dns_nta {
|
||||
unsigned int magic;
|
||||
isc_refcount_t refcount;
|
||||
dns_ntatable_t *ntatable;
|
||||
bool forced;
|
||||
bool forced;
|
||||
isc_timer_t *timer;
|
||||
dns_fetch_t *fetch;
|
||||
dns_rdataset_t rdataset;
|
||||
@@ -53,15 +54,6 @@ struct dns_nta {
|
||||
#define NTA_MAGIC ISC_MAGIC('N', 'T', 'A', 'n')
|
||||
#define VALID_NTA(nn) ISC_MAGIC_VALID(nn, NTA_MAGIC)
|
||||
|
||||
/*
|
||||
* Obtain a reference to the nta object. Released by
|
||||
* nta_detach.
|
||||
*/
|
||||
static void
|
||||
nta_ref(dns_nta_t *nta) {
|
||||
isc_refcount_increment(&nta->refcount);
|
||||
}
|
||||
|
||||
static void
|
||||
nta_detach(isc_mem_t *mctx, dns_nta_t **ntap) {
|
||||
REQUIRE(ntap != NULL && VALID_NTA(*ntap));
|
||||
@@ -133,7 +125,8 @@ dns_ntatable_create(dns_view_t *view,
|
||||
ntatable->taskmgr = taskmgr;
|
||||
|
||||
ntatable->view = view;
|
||||
ntatable->references = 1;
|
||||
|
||||
isc_refcount_init(&ntatable->references, 1);
|
||||
|
||||
ntatable->magic = NTATABLE_MAGIC;
|
||||
*ntatablep = ntatable;
|
||||
@@ -157,20 +150,13 @@ dns_ntatable_attach(dns_ntatable_t *source, dns_ntatable_t **targetp) {
|
||||
REQUIRE(VALID_NTATABLE(source));
|
||||
REQUIRE(targetp != NULL && *targetp == NULL);
|
||||
|
||||
RWLOCK(&source->rwlock, isc_rwlocktype_write);
|
||||
|
||||
INSIST(source->references > 0);
|
||||
source->references++;
|
||||
INSIST(source->references != 0);
|
||||
|
||||
RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
|
||||
isc_refcount_increment(&source->references);
|
||||
|
||||
*targetp = source;
|
||||
}
|
||||
|
||||
void
|
||||
dns_ntatable_detach(dns_ntatable_t **ntatablep) {
|
||||
bool destroy = false;
|
||||
dns_ntatable_t *ntatable;
|
||||
|
||||
REQUIRE(ntatablep != NULL && VALID_NTATABLE(*ntatablep));
|
||||
@@ -178,18 +164,12 @@ dns_ntatable_detach(dns_ntatable_t **ntatablep) {
|
||||
ntatable = *ntatablep;
|
||||
*ntatablep = NULL;
|
||||
|
||||
RWLOCK(&ntatable->rwlock, isc_rwlocktype_write);
|
||||
INSIST(ntatable->references > 0);
|
||||
ntatable->references--;
|
||||
if (ntatable->references == 0)
|
||||
destroy = true;
|
||||
RWUNLOCK(&ntatable->rwlock, isc_rwlocktype_write);
|
||||
|
||||
if (destroy) {
|
||||
if (isc_refcount_decrement(&ntatable->references) == 1) {
|
||||
dns_rbt_destroy(&ntatable->table);
|
||||
isc_rwlock_destroy(&ntatable->rwlock);
|
||||
if (ntatable->task != NULL)
|
||||
if (ntatable->task != NULL) {
|
||||
isc_task_detach(&ntatable->task);
|
||||
}
|
||||
ntatable->timermgr = NULL;
|
||||
ntatable->taskmgr = NULL;
|
||||
ntatable->magic = 0;
|
||||
@@ -265,7 +245,7 @@ checkbogus(isc_task_t *task, isc_event_t *event) {
|
||||
|
||||
isc_event_free(&event);
|
||||
|
||||
nta_ref(nta);
|
||||
isc_refcount_increment(&nta->refcount);
|
||||
result = dns_resolver_createfetch(view->resolver, nta->name,
|
||||
dns_rdatatype_nsec,
|
||||
NULL, NULL, NULL, NULL, 0,
|
||||
@@ -274,8 +254,9 @@ checkbogus(isc_task_t *task, isc_event_t *event) {
|
||||
&nta->rdataset,
|
||||
&nta->sigrdataset,
|
||||
&nta->fetch);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
nta_detach(view->mctx, &nta);
|
||||
}
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
|
||||
+75
-91
@@ -268,12 +268,15 @@ struct fetchctx {
|
||||
isc_mem_t * mctx;
|
||||
isc_stdtime_t now;
|
||||
|
||||
/* Atomic */
|
||||
isc_refcount_t references;
|
||||
|
||||
|
||||
/*% Locked by appropriate bucket lock. */
|
||||
fetchstate state;
|
||||
bool want_shutdown;
|
||||
bool cloned;
|
||||
bool spilled;
|
||||
unsigned int references;
|
||||
bool want_shutdown;
|
||||
bool cloned;
|
||||
bool spilled;
|
||||
isc_event_t control_event;
|
||||
ISC_LINK(struct fetchctx) link;
|
||||
ISC_LIST(dns_fetchevent_t) events;
|
||||
@@ -434,7 +437,7 @@ typedef struct fctxbucket {
|
||||
isc_task_t * task;
|
||||
isc_mutex_t lock;
|
||||
ISC_LIST(fetchctx_t) fctxs;
|
||||
bool exiting;
|
||||
atomic_bool exiting;
|
||||
isc_mem_t * mctx;
|
||||
} fctxbucket_t;
|
||||
|
||||
@@ -472,7 +475,6 @@ struct dns_resolver {
|
||||
unsigned int magic;
|
||||
isc_mem_t * mctx;
|
||||
isc_mutex_t lock;
|
||||
isc_mutex_t nlock;
|
||||
isc_mutex_t primelock;
|
||||
dns_rdataclass_t rdclass;
|
||||
isc_socketmgr_t * socketmgr;
|
||||
@@ -516,12 +518,14 @@ struct dns_resolver {
|
||||
unsigned int retryinterval; /* in milliseconds */
|
||||
unsigned int nonbackofftries;
|
||||
|
||||
/* Atomic */
|
||||
isc_refcount_t references;
|
||||
atomic_bool exiting;
|
||||
|
||||
/* Locked by lock. */
|
||||
unsigned int references;
|
||||
bool exiting;
|
||||
isc_eventlist_t whenshutdown;
|
||||
unsigned int activebuckets;
|
||||
bool priming;
|
||||
bool priming;
|
||||
unsigned int spillat; /* clients-per-query */
|
||||
unsigned int zspill; /* fetches-per-zone */
|
||||
|
||||
@@ -529,8 +533,9 @@ struct dns_resolver {
|
||||
|
||||
/* Locked by primelock. */
|
||||
dns_fetch_t * primefetch;
|
||||
/* Locked by nlock. */
|
||||
unsigned int nfctx;
|
||||
|
||||
/* Atomic. */
|
||||
isc_refcount_t nfctx;
|
||||
};
|
||||
|
||||
#define RES_MAGIC ISC_MAGIC('R', 'e', 's', '!')
|
||||
@@ -1636,7 +1641,8 @@ fctx_sendevents(fetchctx_t *fctx, isc_result_t result, int line) {
|
||||
fctx->spilled &&
|
||||
(count < fctx->res->spillatmax || fctx->res->spillatmax == 0)) {
|
||||
LOCK(&fctx->res->lock);
|
||||
if (count == fctx->res->spillat && !fctx->res->exiting) {
|
||||
if (count == fctx->res->spillat &&
|
||||
!atomic_load_acquire(&fctx->res->exiting)) {
|
||||
old_spillat = fctx->res->spillat;
|
||||
fctx->res->spillat += 5;
|
||||
if (fctx->res->spillat > fctx->res->spillatmax &&
|
||||
@@ -3062,7 +3068,7 @@ fctx_finddone(isc_task_t *task, isc_event_t *event) {
|
||||
} else if (SHUTTINGDOWN(fctx) && fctx->pending == 0 &&
|
||||
fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators)) {
|
||||
|
||||
if (fctx->references == 0) {
|
||||
if (isc_refcount_current(&fctx->references) == 0) {
|
||||
bucket_empty = fctx_unlink(fctx);
|
||||
dodestroy = true;
|
||||
}
|
||||
@@ -4258,24 +4264,26 @@ fctx_unlink(fetchctx_t *fctx) {
|
||||
REQUIRE(ISC_LIST_EMPTY(fctx->finds));
|
||||
REQUIRE(ISC_LIST_EMPTY(fctx->altfinds));
|
||||
REQUIRE(fctx->pending == 0);
|
||||
REQUIRE(fctx->references == 0);
|
||||
REQUIRE(ISC_LIST_EMPTY(fctx->validators));
|
||||
|
||||
FCTXTRACE("unlink");
|
||||
|
||||
isc_refcount_destroy(&fctx->references);
|
||||
|
||||
res = fctx->res;
|
||||
bucketnum = fctx->bucketnum;
|
||||
|
||||
ISC_LIST_UNLINK(res->buckets[bucketnum].fctxs, fctx, link);
|
||||
|
||||
LOCK(&res->nlock);
|
||||
res->nfctx--;
|
||||
UNLOCK(&res->nlock);
|
||||
isc_refcount_decrement(&res->nfctx);
|
||||
|
||||
dec_stats(res, dns_resstatscounter_nfetch);
|
||||
|
||||
if (res->buckets[bucketnum].exiting &&
|
||||
if (atomic_load_acquire(&res->buckets[bucketnum].exiting) &&
|
||||
ISC_LIST_EMPTY(res->buckets[bucketnum].fctxs))
|
||||
{
|
||||
return (true);
|
||||
}
|
||||
|
||||
return (false);
|
||||
}
|
||||
@@ -4293,12 +4301,13 @@ fctx_destroy(fetchctx_t *fctx) {
|
||||
REQUIRE(ISC_LIST_EMPTY(fctx->finds));
|
||||
REQUIRE(ISC_LIST_EMPTY(fctx->altfinds));
|
||||
REQUIRE(fctx->pending == 0);
|
||||
REQUIRE(fctx->references == 0);
|
||||
REQUIRE(ISC_LIST_EMPTY(fctx->validators));
|
||||
REQUIRE(!ISC_LINK_LINKED(fctx, link));
|
||||
|
||||
FCTXTRACE("destroy");
|
||||
|
||||
isc_refcount_destroy(&fctx->references);
|
||||
|
||||
/*
|
||||
* Free bad.
|
||||
*/
|
||||
@@ -4503,8 +4512,11 @@ fctx_doshutdown(isc_task_t *task, isc_event_t *event) {
|
||||
fctx_sendevents(fctx, ISC_R_CANCELED, __LINE__);
|
||||
}
|
||||
|
||||
if (fctx->references == 0 && fctx->pending == 0 &&
|
||||
fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators)) {
|
||||
if (isc_refcount_current(&fctx->references) == 0 &&
|
||||
fctx->pending == 0 &&
|
||||
fctx->nqueries == 0 &&
|
||||
ISC_LIST_EMPTY(fctx->validators))
|
||||
{
|
||||
bucket_empty = fctx_unlink(fctx);
|
||||
dodestroy = true;
|
||||
}
|
||||
@@ -4553,7 +4565,7 @@ fctx_start(isc_task_t *task, isc_event_t *event) {
|
||||
INSIST(fctx->pending == 0);
|
||||
INSIST(fctx->nqueries == 0);
|
||||
INSIST(ISC_LIST_EMPTY(fctx->validators));
|
||||
if (fctx->references == 0) {
|
||||
if (isc_refcount_current(&fctx->references) == 0) {
|
||||
/*
|
||||
* It's now safe to destroy this fctx.
|
||||
*/
|
||||
@@ -4645,7 +4657,9 @@ fctx_join(fetchctx_t *fctx, isc_task_t *task, const isc_sockaddr_t *client,
|
||||
ISC_LIST_PREPEND(fctx->events, event, ev_link);
|
||||
else
|
||||
ISC_LIST_APPEND(fctx->events, event, ev_link);
|
||||
fctx->references++;
|
||||
|
||||
isc_refcount_increment(&fctx->references);
|
||||
|
||||
fctx->client = client;
|
||||
|
||||
fetch->magic = DNS_FETCH_MAGIC;
|
||||
@@ -4738,7 +4752,7 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
|
||||
* using it.
|
||||
*/
|
||||
fctx->res = res;
|
||||
fctx->references = 0;
|
||||
isc_refcount_init(&fctx->references, 0);
|
||||
fctx->bucketnum = bucketnum;
|
||||
fctx->dbucketnum = RES_NOBUCKET;
|
||||
fctx->state = fetchstate_init;
|
||||
@@ -4987,9 +5001,8 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
|
||||
|
||||
ISC_LIST_APPEND(res->buckets[bucketnum].fctxs, fctx, link);
|
||||
|
||||
LOCK(&res->nlock);
|
||||
res->nfctx++;
|
||||
UNLOCK(&res->nlock);
|
||||
isc_refcount_increment(&res->nfctx);
|
||||
|
||||
inc_stats(res, dns_resstatscounter_nfetch);
|
||||
|
||||
*fctxp = fctx;
|
||||
@@ -5287,7 +5300,9 @@ maybe_destroy(fetchctx_t *fctx, bool locked) {
|
||||
dns_validator_cancel(validator);
|
||||
}
|
||||
|
||||
if (fctx->references == 0 && ISC_LIST_EMPTY(fctx->validators)) {
|
||||
if (isc_refcount_current(&fctx->references) == 0 &&
|
||||
ISC_LIST_EMPTY(fctx->validators))
|
||||
{
|
||||
bucket_empty = fctx_unlink(fctx);
|
||||
dodestroy = true;
|
||||
}
|
||||
@@ -6985,9 +7000,7 @@ static void
|
||||
fctx_increference(fetchctx_t *fctx) {
|
||||
REQUIRE(VALID_FCTX(fctx));
|
||||
|
||||
LOCK(&fctx->res->buckets[fctx->bucketnum].lock);
|
||||
fctx->references++;
|
||||
UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
|
||||
isc_refcount_increment(&fctx->references);
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -6996,9 +7009,7 @@ fctx_decreference(fetchctx_t *fctx) {
|
||||
|
||||
REQUIRE(VALID_FCTX(fctx));
|
||||
|
||||
INSIST(fctx->references > 0);
|
||||
fctx->references--;
|
||||
if (fctx->references == 0) {
|
||||
if (isc_refcount_decrement(&fctx->references) == 1) {
|
||||
/*
|
||||
* No one cares about the result of this fetch anymore.
|
||||
*/
|
||||
@@ -7027,8 +7038,6 @@ resume_dslookup(isc_task_t *task, isc_event_t *event) {
|
||||
fetchctx_t *fctx;
|
||||
isc_result_t result;
|
||||
bool bucket_empty;
|
||||
bool locked = false;
|
||||
unsigned int bucketnum;
|
||||
dns_rdataset_t nameservers;
|
||||
dns_fixedname_t fixed;
|
||||
dns_name_t *domain;
|
||||
@@ -7160,23 +7169,20 @@ resume_dslookup(isc_task_t *task, isc_event_t *event) {
|
||||
}
|
||||
fctx_done(fctx, result, __LINE__);
|
||||
} else {
|
||||
LOCK(&res->buckets[bucketnum].lock);
|
||||
locked = true;
|
||||
fctx->references++;
|
||||
fctx_increference(fctx);
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
INSIST(event == NULL);
|
||||
INSIST(fevent == NULL);
|
||||
if (dns_rdataset_isassociated(&nameservers))
|
||||
if (dns_rdataset_isassociated(&nameservers)) {
|
||||
dns_rdataset_disassociate(&nameservers);
|
||||
if (!locked)
|
||||
LOCK(&res->buckets[bucketnum].lock);
|
||||
}
|
||||
bucket_empty = fctx_decreference(fctx);
|
||||
UNLOCK(&res->buckets[bucketnum].lock);
|
||||
if (bucket_empty)
|
||||
if (bucket_empty) {
|
||||
empty_bucket(res);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
@@ -7335,7 +7341,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
|
||||
|
||||
rctx_respinit(task, devent, query, fctx, &rctx);
|
||||
|
||||
if (fctx->res->exiting) {
|
||||
if (atomic_load_acquire(&fctx->res->exiting)) {
|
||||
result = ISC_R_SHUTTINGDOWN;
|
||||
FCTXTRACE("resolver shutting down");
|
||||
rctx_done(&rctx, result);
|
||||
@@ -9364,9 +9370,7 @@ rctx_resend(respctx_t *rctx, dns_adbaddrinfo_t *addrinfo) {
|
||||
}
|
||||
|
||||
fctx_done(fctx, result, __LINE__);
|
||||
LOCK(&fctx->res->buckets[fctx->bucketnum].lock);
|
||||
bucket_empty = fctx_decreference(fctx);
|
||||
UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
|
||||
if (bucket_empty) {
|
||||
empty_bucket(fctx->res);
|
||||
}
|
||||
@@ -9787,10 +9791,9 @@ destroy(dns_resolver_t *res) {
|
||||
|
||||
RTRACE("destroy");
|
||||
|
||||
INSIST(res->nfctx == 0);
|
||||
isc_refcount_destroy(&res->nfctx);
|
||||
|
||||
isc_mutex_destroy(&res->primelock);
|
||||
isc_mutex_destroy(&res->nlock);
|
||||
isc_mutex_destroy(&res->lock);
|
||||
for (i = 0; i < res->nbuckets; i++) {
|
||||
INSIST(ISC_LIST_EMPTY(res->buckets[i].fctxs));
|
||||
@@ -9879,7 +9882,7 @@ spillattimer_countdown(isc_task_t *task, isc_event_t *event) {
|
||||
UNUSED(task);
|
||||
|
||||
LOCK(&res->lock);
|
||||
INSIST(!res->exiting);
|
||||
INSIST(!atomic_load_acquire(&res->exiting));
|
||||
if (res->spillat > res->spillatmin) {
|
||||
res->spillat--;
|
||||
logit = true;
|
||||
@@ -10007,7 +10010,7 @@ dns_resolver_create(dns_view_t *view,
|
||||
isc_mem_setname(res->buckets[i].mctx, name, NULL);
|
||||
isc_task_setname(res->buckets[i].task, name, res);
|
||||
ISC_LIST_INIT(res->buckets[i].fctxs);
|
||||
res->buckets[i].exiting = false;
|
||||
atomic_store_release(&res->buckets[i].exiting, false);
|
||||
buckets_created++;
|
||||
}
|
||||
|
||||
@@ -10044,15 +10047,15 @@ dns_resolver_create(dns_view_t *view,
|
||||
res->querydscp4 = -1;
|
||||
res->querydscp6 = -1;
|
||||
res->references = 1;
|
||||
res->exiting = false;
|
||||
atomic_init(&res->exiting, false);
|
||||
res->frozen = false;
|
||||
ISC_LIST_INIT(res->whenshutdown);
|
||||
res->priming = false;
|
||||
res->primefetch = NULL;
|
||||
res->nfctx = 0;
|
||||
|
||||
isc_refcount_init(&res->nfctx, 0);
|
||||
|
||||
isc_mutex_init(&res->lock);
|
||||
isc_mutex_init(&res->nlock);
|
||||
isc_mutex_init(&res->primelock);
|
||||
|
||||
task = NULL;
|
||||
@@ -10101,7 +10104,6 @@ dns_resolver_create(dns_view_t *view,
|
||||
|
||||
cleanup_primelock:
|
||||
isc_mutex_destroy(&res->primelock);
|
||||
isc_mutex_destroy(&res->nlock);
|
||||
isc_mutex_destroy(&res->lock);
|
||||
|
||||
if (res->dispatches6 != NULL)
|
||||
@@ -10198,7 +10200,8 @@ dns_resolver_prime(dns_resolver_t *res) {
|
||||
|
||||
LOCK(&res->lock);
|
||||
|
||||
if (!res->exiting && !res->priming) {
|
||||
/* 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;
|
||||
@@ -10264,13 +10267,12 @@ dns_resolver_attach(dns_resolver_t *source, dns_resolver_t **targetp) {
|
||||
REQUIRE(targetp != NULL && *targetp == NULL);
|
||||
|
||||
RRTRACE(source, "attach");
|
||||
LOCK(&source->lock);
|
||||
REQUIRE(!source->exiting);
|
||||
|
||||
INSIST(source->references > 0);
|
||||
source->references++;
|
||||
INSIST(source->references != 0);
|
||||
UNLOCK(&source->lock);
|
||||
LOCK(&res->lock);
|
||||
REQUIRE(!atomic_load_acquire(&source->exiting));
|
||||
|
||||
isc_refcount_increment(&source->references);
|
||||
UNLOCK(&res->lock);
|
||||
|
||||
*targetp = source;
|
||||
}
|
||||
@@ -10290,7 +10292,7 @@ dns_resolver_whenshutdown(dns_resolver_t *res, isc_task_t *task,
|
||||
|
||||
LOCK(&res->lock);
|
||||
|
||||
if (res->exiting && res->activebuckets == 0) {
|
||||
if (atomic_load_acquire(&res->exiting) && res->activebuckets == 0) {
|
||||
/*
|
||||
* We're already shutdown. Send the event.
|
||||
*/
|
||||
@@ -10311,16 +10313,14 @@ dns_resolver_shutdown(dns_resolver_t *res) {
|
||||
unsigned int i;
|
||||
fetchctx_t *fctx;
|
||||
isc_result_t result;
|
||||
bool is_false = false;
|
||||
|
||||
REQUIRE(VALID_RESOLVER(res));
|
||||
|
||||
RTRACE("shutdown");
|
||||
|
||||
LOCK(&res->lock);
|
||||
|
||||
if (!res->exiting) {
|
||||
if (atomic_compare_exchange_strong(&res->exiting, &is_false, true)) {
|
||||
RTRACE("exiting");
|
||||
res->exiting = true;
|
||||
|
||||
for (i = 0; i < res->nbuckets; i++) {
|
||||
LOCK(&res->buckets[i].lock);
|
||||
@@ -10350,14 +10350,11 @@ dns_resolver_shutdown(dns_resolver_t *res) {
|
||||
NULL, true);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
UNLOCK(&res->lock);
|
||||
}
|
||||
|
||||
void
|
||||
dns_resolver_detach(dns_resolver_t **resp) {
|
||||
dns_resolver_t *res;
|
||||
bool need_destroy = false;
|
||||
|
||||
REQUIRE(resp != NULL);
|
||||
res = *resp;
|
||||
@@ -10365,21 +10362,13 @@ dns_resolver_detach(dns_resolver_t **resp) {
|
||||
|
||||
RTRACE("detach");
|
||||
|
||||
LOCK(&res->lock);
|
||||
|
||||
INSIST(res->references > 0);
|
||||
res->references--;
|
||||
if (res->references == 0) {
|
||||
INSIST(res->exiting && res->activebuckets == 0);
|
||||
need_destroy = true;
|
||||
}
|
||||
|
||||
UNLOCK(&res->lock);
|
||||
|
||||
if (need_destroy)
|
||||
destroy(res);
|
||||
|
||||
*resp = NULL;
|
||||
|
||||
if (isc_refcount_decrement(&res->references) == 1) {
|
||||
INSIST(atomic_load_acquire(&res->exiting));
|
||||
INSIST(res->activebuckets == 0);
|
||||
destroy(res);
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool
|
||||
@@ -10712,11 +10701,10 @@ dns_resolver_destroyfetch(dns_fetch_t **fetchp) {
|
||||
RUNTIME_CHECK(event->fetch != fetch);
|
||||
}
|
||||
}
|
||||
UNLOCK(&res->buckets[bucketnum].lock);
|
||||
|
||||
bucket_empty = fctx_decreference(fctx);
|
||||
|
||||
UNLOCK(&res->buckets[bucketnum].lock);
|
||||
|
||||
isc_mem_putanddetach(&fetch->mctx, fetch, sizeof(*fetch));
|
||||
*fetchp = NULL;
|
||||
|
||||
@@ -10810,11 +10798,7 @@ dns_resolver_setlamettl(dns_resolver_t *resolver, uint32_t lame_ttl) {
|
||||
|
||||
unsigned int
|
||||
dns_resolver_nrunning(dns_resolver_t *resolver) {
|
||||
unsigned int n;
|
||||
LOCK(&resolver->nlock);
|
||||
n = resolver->nfctx;
|
||||
UNLOCK(&resolver->nlock);
|
||||
return (n);
|
||||
return (isc_refcount_current(&resolver->nfctx));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
|
||||
+22
-44
@@ -22,6 +22,7 @@
|
||||
#include <isc/mem.h>
|
||||
#include <isc/once.h>
|
||||
#include <isc/print.h>
|
||||
#include <isc/refcount.h>
|
||||
#include <isc/region.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
@@ -56,9 +57,9 @@ struct dns_sdb {
|
||||
char *zone;
|
||||
dns_sdbimplementation_t *implementation;
|
||||
void *dbdata;
|
||||
isc_mutex_t lock;
|
||||
/* Locked */
|
||||
unsigned int references;
|
||||
|
||||
/* Atomic */
|
||||
isc_refcount_t references;
|
||||
};
|
||||
|
||||
struct dns_sdblookup {
|
||||
@@ -69,10 +70,10 @@ struct dns_sdblookup {
|
||||
ISC_LIST(isc_buffer_t) buffers;
|
||||
dns_name_t *name;
|
||||
ISC_LINK(dns_sdblookup_t) link;
|
||||
isc_mutex_t lock;
|
||||
dns_rdatacallbacks_t callbacks;
|
||||
/* Locked */
|
||||
unsigned int references;
|
||||
|
||||
/* Atomic */
|
||||
isc_refcount_t references;
|
||||
};
|
||||
|
||||
typedef struct dns_sdblookup dns_sdbnode_t;
|
||||
@@ -529,10 +530,7 @@ attach(dns_db_t *source, dns_db_t **targetp) {
|
||||
|
||||
REQUIRE(VALID_SDB(sdb));
|
||||
|
||||
LOCK(&sdb->lock);
|
||||
REQUIRE(sdb->references > 0);
|
||||
sdb->references++;
|
||||
UNLOCK(&sdb->lock);
|
||||
isc_refcount_increment(&sdb->references);
|
||||
|
||||
*targetp = source;
|
||||
}
|
||||
@@ -552,7 +550,6 @@ destroy(dns_sdb_t *sdb) {
|
||||
}
|
||||
|
||||
isc_mem_free(mctx, sdb->zone);
|
||||
isc_mutex_destroy(&sdb->lock);
|
||||
|
||||
sdb->common.magic = 0;
|
||||
sdb->common.impmagic = 0;
|
||||
@@ -566,20 +563,14 @@ destroy(dns_sdb_t *sdb) {
|
||||
static void
|
||||
detach(dns_db_t **dbp) {
|
||||
dns_sdb_t *sdb = (dns_sdb_t *)(*dbp);
|
||||
bool need_destroy = false;
|
||||
|
||||
REQUIRE(VALID_SDB(sdb));
|
||||
LOCK(&sdb->lock);
|
||||
REQUIRE(sdb->references > 0);
|
||||
sdb->references--;
|
||||
if (sdb->references == 0)
|
||||
need_destroy = true;
|
||||
UNLOCK(&sdb->lock);
|
||||
|
||||
if (need_destroy)
|
||||
destroy(sdb);
|
||||
|
||||
*dbp = NULL;
|
||||
|
||||
if (isc_refcount_decrement(&sdb->references) == 1) {
|
||||
destroy(sdb);
|
||||
}
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
@@ -661,9 +652,10 @@ createnode(dns_sdb_t *sdb, dns_sdbnode_t **nodep) {
|
||||
ISC_LIST_INIT(node->buffers);
|
||||
ISC_LINK_INIT(node, link);
|
||||
node->name = NULL;
|
||||
isc_mutex_init(&node->lock);
|
||||
dns_rdatacallbacks_init(&node->callbacks);
|
||||
node->references = 1;
|
||||
|
||||
isc_refcount_init(&node->references, 1);
|
||||
|
||||
node->magic = SDBLOOKUP_MAGIC;
|
||||
|
||||
*nodep = node;
|
||||
@@ -702,7 +694,7 @@ destroynode(dns_sdbnode_t *node) {
|
||||
dns_name_free(node->name, mctx);
|
||||
isc_mem_put(mctx, node->name, sizeof(dns_name_t));
|
||||
}
|
||||
isc_mutex_destroy(&node->lock);
|
||||
|
||||
node->magic = 0;
|
||||
isc_mem_put(mctx, node, sizeof(dns_sdbnode_t));
|
||||
detach((dns_db_t **) (void *)&sdb);
|
||||
@@ -1001,11 +993,7 @@ attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) {
|
||||
|
||||
UNUSED(sdb);
|
||||
|
||||
LOCK(&node->lock);
|
||||
INSIST(node->references > 0);
|
||||
node->references++;
|
||||
INSIST(node->references != 0); /* Catch overflow. */
|
||||
UNLOCK(&node->lock);
|
||||
isc_refcount_increment(&node->references);
|
||||
|
||||
*targetp = source;
|
||||
}
|
||||
@@ -1014,7 +1002,6 @@ static void
|
||||
detachnode(dns_db_t *db, dns_dbnode_t **targetp) {
|
||||
dns_sdb_t *sdb = (dns_sdb_t *)db;
|
||||
dns_sdbnode_t *node;
|
||||
bool need_destroy = false;
|
||||
|
||||
REQUIRE(VALID_SDB(sdb));
|
||||
REQUIRE(targetp != NULL && *targetp != NULL);
|
||||
@@ -1023,17 +1010,11 @@ detachnode(dns_db_t *db, dns_dbnode_t **targetp) {
|
||||
|
||||
node = (dns_sdbnode_t *)(*targetp);
|
||||
|
||||
LOCK(&node->lock);
|
||||
INSIST(node->references > 0);
|
||||
node->references--;
|
||||
if (node->references == 0)
|
||||
need_destroy = true;
|
||||
UNLOCK(&node->lock);
|
||||
|
||||
if (need_destroy)
|
||||
destroynode(node);
|
||||
|
||||
*targetp = NULL;
|
||||
|
||||
if (isc_refcount_decrement(&node->references) == 1) {
|
||||
destroynode(node);
|
||||
}
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
@@ -1323,8 +1304,6 @@ dns_sdb_create(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type,
|
||||
|
||||
isc_mem_attach(mctx, &sdb->common.mctx);
|
||||
|
||||
isc_mutex_init(&sdb->lock);
|
||||
|
||||
result = dns_name_dupwithoffsets(origin, mctx, &sdb->common.origin);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_lock;
|
||||
@@ -1351,7 +1330,7 @@ dns_sdb_create(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type,
|
||||
goto cleanup_zonestr;
|
||||
}
|
||||
|
||||
sdb->references = 1;
|
||||
isc_refcount_init(&sdb->references, 1);
|
||||
|
||||
sdb->common.magic = DNS_DB_MAGIC;
|
||||
sdb->common.impmagic = SDB_MAGIC;
|
||||
@@ -1365,7 +1344,6 @@ dns_sdb_create(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type,
|
||||
cleanup_origin:
|
||||
dns_name_free(&sdb->common.origin, mctx);
|
||||
cleanup_lock:
|
||||
isc_mutex_destroy(&sdb->lock);
|
||||
isc_mem_put(mctx, sdb, sizeof(dns_sdb_t));
|
||||
isc_mem_detach(&mctx);
|
||||
|
||||
|
||||
+24
-45
@@ -98,9 +98,11 @@ struct dns_sdlz_db {
|
||||
dns_db_t common;
|
||||
void *dbdata;
|
||||
dns_sdlzimplementation_t *dlzimp;
|
||||
isc_mutex_t refcnt_lock;
|
||||
|
||||
/* Atomic */
|
||||
isc_refcount_t references;
|
||||
|
||||
/* Locked */
|
||||
unsigned int references;
|
||||
dns_dbversion_t *future_version;
|
||||
int dummy_version;
|
||||
};
|
||||
@@ -113,10 +115,10 @@ struct dns_sdlzlookup {
|
||||
ISC_LIST(isc_buffer_t) buffers;
|
||||
dns_name_t *name;
|
||||
ISC_LINK(dns_sdlzlookup_t) link;
|
||||
isc_mutex_t lock;
|
||||
dns_rdatacallbacks_t callbacks;
|
||||
/* Locked */
|
||||
unsigned int references;
|
||||
|
||||
/* Atomic */
|
||||
isc_refcount_t references;
|
||||
};
|
||||
|
||||
typedef struct dns_sdlzlookup dns_sdlznode_t;
|
||||
@@ -318,10 +320,7 @@ attach(dns_db_t *source, dns_db_t **targetp) {
|
||||
|
||||
REQUIRE(VALID_SDLZDB(sdlz));
|
||||
|
||||
LOCK(&sdlz->refcnt_lock);
|
||||
REQUIRE(sdlz->references > 0);
|
||||
sdlz->references++;
|
||||
UNLOCK(&sdlz->refcnt_lock);
|
||||
isc_refcount_increment(&sdlz->references);
|
||||
|
||||
*targetp = source;
|
||||
}
|
||||
@@ -334,31 +333,25 @@ destroy(dns_sdlz_db_t *sdlz) {
|
||||
sdlz->common.magic = 0;
|
||||
sdlz->common.impmagic = 0;
|
||||
|
||||
isc_mutex_destroy(&sdlz->refcnt_lock);
|
||||
|
||||
dns_name_free(&sdlz->common.origin, mctx);
|
||||
|
||||
isc_mem_put(mctx, sdlz, sizeof(dns_sdlz_db_t));
|
||||
isc_mem_detach(&mctx);
|
||||
|
||||
isc_refcount_destroy(&sdlz->references);
|
||||
}
|
||||
|
||||
static void
|
||||
detach(dns_db_t **dbp) {
|
||||
dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)(*dbp);
|
||||
bool need_destroy = false;
|
||||
|
||||
REQUIRE(VALID_SDLZDB(sdlz));
|
||||
LOCK(&sdlz->refcnt_lock);
|
||||
REQUIRE(sdlz->references > 0);
|
||||
sdlz->references--;
|
||||
if (sdlz->references == 0)
|
||||
need_destroy = true;
|
||||
UNLOCK(&sdlz->refcnt_lock);
|
||||
|
||||
if (need_destroy)
|
||||
destroy(sdlz);
|
||||
|
||||
*dbp = NULL;
|
||||
|
||||
if (isc_refcount_decrement(&sdlz->references) == 1) {
|
||||
destroy(sdlz);
|
||||
}
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
@@ -476,9 +469,9 @@ createnode(dns_sdlz_db_t *sdlz, dns_sdlznode_t **nodep) {
|
||||
ISC_LIST_INIT(node->buffers);
|
||||
ISC_LINK_INIT(node, link);
|
||||
node->name = NULL;
|
||||
isc_mutex_init(&node->lock);
|
||||
dns_rdatacallbacks_init(&node->callbacks);
|
||||
node->references = 1;
|
||||
|
||||
isc_refcount_init(&node->references, 1);
|
||||
node->magic = SDLZLOOKUP_MAGIC;
|
||||
|
||||
*nodep = node;
|
||||
@@ -518,7 +511,8 @@ destroynode(dns_sdlznode_t *node) {
|
||||
dns_name_free(node->name, mctx);
|
||||
isc_mem_put(mctx, node->name, sizeof(dns_name_t));
|
||||
}
|
||||
isc_mutex_destroy(&node->lock);
|
||||
isc_refcount_destroy(&node->references);
|
||||
|
||||
node->magic = 0;
|
||||
isc_mem_put(mctx, node, sizeof(dns_sdlznode_t));
|
||||
db = &sdlz->common;
|
||||
@@ -734,11 +728,7 @@ attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) {
|
||||
|
||||
UNUSED(sdlz);
|
||||
|
||||
LOCK(&node->lock);
|
||||
INSIST(node->references > 0);
|
||||
node->references++;
|
||||
INSIST(node->references != 0); /* Catch overflow. */
|
||||
UNLOCK(&node->lock);
|
||||
isc_refcount_increment(&node->references);
|
||||
|
||||
*targetp = source;
|
||||
}
|
||||
@@ -747,7 +737,6 @@ static void
|
||||
detachnode(dns_db_t *db, dns_dbnode_t **targetp) {
|
||||
dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
|
||||
dns_sdlznode_t *node;
|
||||
bool need_destroy = false;
|
||||
|
||||
REQUIRE(VALID_SDLZDB(sdlz));
|
||||
REQUIRE(targetp != NULL && *targetp != NULL);
|
||||
@@ -755,18 +744,11 @@ detachnode(dns_db_t *db, dns_dbnode_t **targetp) {
|
||||
UNUSED(sdlz);
|
||||
|
||||
node = (dns_sdlznode_t *)(*targetp);
|
||||
|
||||
LOCK(&node->lock);
|
||||
INSIST(node->references > 0);
|
||||
node->references--;
|
||||
if (node->references == 0)
|
||||
need_destroy = true;
|
||||
UNLOCK(&node->lock);
|
||||
|
||||
if (need_destroy)
|
||||
destroynode(node);
|
||||
|
||||
*targetp = NULL;
|
||||
|
||||
if (isc_refcount_decrement(&node->references) == 1) {
|
||||
destroynode(node);
|
||||
}
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
@@ -1543,9 +1525,6 @@ dns_sdlzcreateDBP(isc_mem_t *mctx, void *driverarg, void *dbdata,
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto mem_cleanup;
|
||||
|
||||
/* initialize the reference count mutex */
|
||||
isc_mutex_init(&sdlzdb->refcnt_lock);
|
||||
|
||||
/* set the rest of the database structure attributes */
|
||||
sdlzdb->dlzimp = imp;
|
||||
sdlzdb->common.methods = &sdlzdb_methods;
|
||||
@@ -1553,7 +1532,7 @@ dns_sdlzcreateDBP(isc_mem_t *mctx, void *driverarg, void *dbdata,
|
||||
sdlzdb->common.rdclass = rdclass;
|
||||
sdlzdb->common.mctx = NULL;
|
||||
sdlzdb->dbdata = dbdata;
|
||||
sdlzdb->references = 1;
|
||||
isc_refcount_init(&sdlzdb->references, 1);
|
||||
|
||||
/* attach to the memory context */
|
||||
isc_mem_attach(mctx, &sdlzdb->common.mctx);
|
||||
|
||||
+9
-23
@@ -17,6 +17,7 @@
|
||||
#include <isc/mem.h>
|
||||
#include <isc/netaddr.h>
|
||||
#include <isc/print.h>
|
||||
#include <isc/refcount.h>
|
||||
#include <isc/result.h>
|
||||
#include <isc/string.h>
|
||||
#include <isc/util.h>
|
||||
@@ -51,8 +52,7 @@ struct dns_ssurule {
|
||||
struct dns_ssutable {
|
||||
unsigned int magic;
|
||||
isc_mem_t *mctx;
|
||||
unsigned int references;
|
||||
isc_mutex_t lock;
|
||||
isc_refcount_t references;
|
||||
dns_dlzdb_t *dlzdatabase;
|
||||
ISC_LIST(dns_ssurule_t) rules;
|
||||
};
|
||||
@@ -65,10 +65,10 @@ dns_ssutable_create(isc_mem_t *mctx, dns_ssutable_t **tablep) {
|
||||
REQUIRE(mctx != NULL);
|
||||
|
||||
table = isc_mem_get(mctx, sizeof(dns_ssutable_t));
|
||||
if (table == NULL)
|
||||
if (table == NULL) {
|
||||
return (ISC_R_NOMEMORY);
|
||||
isc_mutex_init(&table->lock);
|
||||
table->references = 1;
|
||||
}
|
||||
isc_refcount_init(&table->references, 1);
|
||||
table->mctx = NULL;
|
||||
isc_mem_attach(mctx, &table->mctx);
|
||||
ISC_LIST_INIT(table->rules);
|
||||
@@ -101,7 +101,7 @@ destroy(dns_ssutable_t *table) {
|
||||
rule->magic = 0;
|
||||
isc_mem_put(mctx, rule, sizeof(dns_ssurule_t));
|
||||
}
|
||||
isc_mutex_destroy(&table->lock);
|
||||
isc_refcount_destroy(&table->references);
|
||||
table->magic = 0;
|
||||
isc_mem_putanddetach(&table->mctx, table, sizeof(dns_ssutable_t));
|
||||
}
|
||||
@@ -111,13 +111,7 @@ dns_ssutable_attach(dns_ssutable_t *source, dns_ssutable_t **targetp) {
|
||||
REQUIRE(VALID_SSUTABLE(source));
|
||||
REQUIRE(targetp != NULL && *targetp == NULL);
|
||||
|
||||
LOCK(&source->lock);
|
||||
|
||||
INSIST(source->references > 0);
|
||||
source->references++;
|
||||
INSIST(source->references != 0);
|
||||
|
||||
UNLOCK(&source->lock);
|
||||
isc_refcount_increment(&source->references);
|
||||
|
||||
*targetp = source;
|
||||
}
|
||||
@@ -125,23 +119,15 @@ dns_ssutable_attach(dns_ssutable_t *source, dns_ssutable_t **targetp) {
|
||||
void
|
||||
dns_ssutable_detach(dns_ssutable_t **tablep) {
|
||||
dns_ssutable_t *table;
|
||||
bool done = false;
|
||||
|
||||
REQUIRE(tablep != NULL);
|
||||
table = *tablep;
|
||||
REQUIRE(VALID_SSUTABLE(table));
|
||||
|
||||
LOCK(&table->lock);
|
||||
|
||||
INSIST(table->references > 0);
|
||||
if (--table->references == 0)
|
||||
done = true;
|
||||
UNLOCK(&table->lock);
|
||||
|
||||
*tablep = NULL;
|
||||
|
||||
if (done)
|
||||
if (isc_refcount_decrement(&table->references) == 1) {
|
||||
destroy(table);
|
||||
}
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
|
||||
+6
-15
@@ -17,6 +17,7 @@
|
||||
|
||||
#include <isc/magic.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/refcount.h>
|
||||
#include <isc/stats.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
@@ -66,11 +67,10 @@ struct dns_stats {
|
||||
unsigned int magic;
|
||||
dns_statstype_t type;
|
||||
isc_mem_t *mctx;
|
||||
isc_mutex_t lock;
|
||||
isc_stats_t *counters;
|
||||
|
||||
/*% Locked by lock */
|
||||
unsigned int references;
|
||||
/*% Atomic */
|
||||
isc_refcount_t references;
|
||||
};
|
||||
|
||||
typedef struct rdatadumparg {
|
||||
@@ -93,9 +93,7 @@ dns_stats_attach(dns_stats_t *stats, dns_stats_t **statsp) {
|
||||
REQUIRE(DNS_STATS_VALID(stats));
|
||||
REQUIRE(statsp != NULL && *statsp == NULL);
|
||||
|
||||
LOCK(&stats->lock);
|
||||
stats->references++;
|
||||
UNLOCK(&stats->lock);
|
||||
isc_refcount_increment(&stats->references);
|
||||
|
||||
*statsp = stats;
|
||||
}
|
||||
@@ -109,13 +107,8 @@ dns_stats_detach(dns_stats_t **statsp) {
|
||||
stats = *statsp;
|
||||
*statsp = NULL;
|
||||
|
||||
LOCK(&stats->lock);
|
||||
stats->references--;
|
||||
UNLOCK(&stats->lock);
|
||||
|
||||
if (stats->references == 0) {
|
||||
if (isc_refcount_decrement(&stats->references) == 1) {
|
||||
isc_stats_detach(&stats->counters);
|
||||
isc_mutex_destroy(&stats->lock);
|
||||
isc_mem_putanddetach(&stats->mctx, stats, sizeof(*stats));
|
||||
}
|
||||
}
|
||||
@@ -135,9 +128,8 @@ create_stats(isc_mem_t *mctx, dns_statstype_t type, int ncounters,
|
||||
return (ISC_R_NOMEMORY);
|
||||
|
||||
stats->counters = NULL;
|
||||
stats->references = 1;
|
||||
|
||||
isc_mutex_init(&stats->lock);
|
||||
isc_refcount_init(&stats->references, 1);
|
||||
|
||||
result = isc_stats_create(mctx, &stats->counters, ncounters);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
@@ -152,7 +144,6 @@ create_stats(isc_mem_t *mctx, dns_statstype_t type, int ncounters,
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
clean_mutex:
|
||||
isc_mutex_destroy(&stats->lock);
|
||||
isc_mem_put(mctx, stats, sizeof(*stats));
|
||||
|
||||
return (result);
|
||||
|
||||
+7
-22
@@ -611,21 +611,15 @@ dns_tsigkeyring_dumpanddetach(dns_tsig_keyring_t **ringp, FILE *fp) {
|
||||
dns_rbtnode_t *node;
|
||||
dns_tsigkey_t *tkey;
|
||||
dns_tsig_keyring_t *ring;
|
||||
unsigned int references;
|
||||
|
||||
REQUIRE(ringp != NULL && *ringp != NULL);
|
||||
|
||||
ring = *ringp;
|
||||
*ringp = NULL;
|
||||
|
||||
RWLOCK(&ring->lock, isc_rwlocktype_write);
|
||||
INSIST(ring->references > 0);
|
||||
ring->references--;
|
||||
references = ring->references;
|
||||
RWUNLOCK(&ring->lock, isc_rwlocktype_write);
|
||||
|
||||
if (references != 0)
|
||||
if (isc_refcount_decrement(&ring->references) > 1) {
|
||||
return (DNS_R_CONTINUE);
|
||||
}
|
||||
|
||||
isc_stdtime_get(&now);
|
||||
dns_name_init(&foundname, NULL);
|
||||
@@ -1804,7 +1798,7 @@ dns_tsigkeyring_create(isc_mem_t *mctx, dns_tsig_keyring_t **ringp) {
|
||||
ring->maxgenerated = DNS_TSIG_MAXGENERATEDKEYS;
|
||||
ISC_LIST_INIT(ring->lru);
|
||||
isc_mem_attach(mctx, &ring->mctx);
|
||||
ring->references = 1;
|
||||
isc_refcount_init(&ring->references, 1);
|
||||
|
||||
*ringp = ring;
|
||||
return (ISC_R_SUCCESS);
|
||||
@@ -1829,18 +1823,14 @@ dns_tsigkeyring_attach(dns_tsig_keyring_t *source, dns_tsig_keyring_t **target)
|
||||
REQUIRE(source != NULL);
|
||||
REQUIRE(target != NULL && *target == NULL);
|
||||
|
||||
RWLOCK(&source->lock, isc_rwlocktype_write);
|
||||
INSIST(source->references > 0);
|
||||
source->references++;
|
||||
INSIST(source->references > 0);
|
||||
isc_refcount_increment(&source->references);
|
||||
|
||||
*target = source;
|
||||
RWUNLOCK(&source->lock, isc_rwlocktype_write);
|
||||
}
|
||||
|
||||
void
|
||||
dns_tsigkeyring_detach(dns_tsig_keyring_t **ringp) {
|
||||
dns_tsig_keyring_t *ring;
|
||||
unsigned int references;
|
||||
|
||||
REQUIRE(ringp != NULL);
|
||||
REQUIRE(*ringp != NULL);
|
||||
@@ -1848,14 +1838,9 @@ dns_tsigkeyring_detach(dns_tsig_keyring_t **ringp) {
|
||||
ring = *ringp;
|
||||
*ringp = NULL;
|
||||
|
||||
RWLOCK(&ring->lock, isc_rwlocktype_write);
|
||||
INSIST(ring->references > 0);
|
||||
ring->references--;
|
||||
references = ring->references;
|
||||
RWUNLOCK(&ring->lock, isc_rwlocktype_write);
|
||||
|
||||
if (references == 0)
|
||||
if (isc_refcount_decrement(&ring->references) == 1) {
|
||||
destroyring(ring);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+37
-51
@@ -45,10 +45,13 @@ struct dns_zt {
|
||||
dns_zt_allloaded_t loaddone;
|
||||
void * loaddone_arg;
|
||||
struct zt_load_params *loadparams;
|
||||
|
||||
/* Atomic */
|
||||
atomic_bool flush;
|
||||
isc_refcount_t references;
|
||||
isc_refcount_t loads_pending;
|
||||
|
||||
/* Locked by lock. */
|
||||
bool flush;
|
||||
uint32_t references;
|
||||
unsigned int loads_pending;
|
||||
dns_rbt_t *table;
|
||||
};
|
||||
|
||||
@@ -93,14 +96,14 @@ dns_zt_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_zt_t **ztp) {
|
||||
|
||||
zt->mctx = NULL;
|
||||
isc_mem_attach(mctx, &zt->mctx);
|
||||
zt->references = 1;
|
||||
zt->flush = false;
|
||||
isc_refcount_init(&zt->references, 1);
|
||||
isc_refcount_init(&zt->flush, false);
|
||||
zt->rdclass = rdclass;
|
||||
zt->magic = ZTMAGIC;
|
||||
zt->loaddone = NULL;
|
||||
zt->loaddone_arg = NULL;
|
||||
zt->loadparams = NULL;
|
||||
zt->loads_pending = 0;
|
||||
isc_refcount_init(&zt->loads_pending, 0);
|
||||
*ztp = zt;
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
@@ -209,13 +212,7 @@ dns_zt_attach(dns_zt_t *zt, dns_zt_t **ztp) {
|
||||
REQUIRE(VALID_ZT(zt));
|
||||
REQUIRE(ztp != NULL && *ztp == NULL);
|
||||
|
||||
RWLOCK(&zt->rwlock, isc_rwlocktype_write);
|
||||
|
||||
INSIST(zt->references > 0);
|
||||
zt->references++;
|
||||
INSIST(zt->references != 0);
|
||||
|
||||
RWUNLOCK(&zt->rwlock, isc_rwlocktype_write);
|
||||
isc_refcount_increment(&zt->references);
|
||||
|
||||
*ztp = zt;
|
||||
}
|
||||
@@ -238,28 +235,20 @@ zt_destroy(dns_zt_t *zt) {
|
||||
|
||||
static void
|
||||
zt_flushanddetach(dns_zt_t **ztp, bool need_flush) {
|
||||
bool destroy = false;
|
||||
dns_zt_t *zt;
|
||||
|
||||
REQUIRE(ztp != NULL && VALID_ZT(*ztp));
|
||||
|
||||
zt = *ztp;
|
||||
|
||||
RWLOCK(&zt->rwlock, isc_rwlocktype_write);
|
||||
|
||||
INSIST(zt->references > 0);
|
||||
zt->references--;
|
||||
if (zt->references == 0)
|
||||
destroy = true;
|
||||
if (need_flush)
|
||||
zt->flush = true;
|
||||
|
||||
RWUNLOCK(&zt->rwlock, isc_rwlocktype_write);
|
||||
|
||||
if (destroy)
|
||||
zt_destroy(zt);
|
||||
|
||||
*ztp = NULL;
|
||||
|
||||
if (need_flush) {
|
||||
atomic_store(&zt->flush, true);
|
||||
}
|
||||
|
||||
if (isc_refcount_decrement(&zt->references) == 1) {
|
||||
zt_destroy(zt);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -309,11 +298,15 @@ dns_zt_asyncload(dns_zt_t *zt, bool newonly,
|
||||
}
|
||||
zt->loadparams->dl = doneloading;
|
||||
zt->loadparams->newonly = newonly;
|
||||
|
||||
RWLOCK(&zt->rwlock, isc_rwlocktype_write);
|
||||
INSIST(zt->loads_pending == 0);
|
||||
|
||||
INSIST(isc_refcount_current(&zt->loads_pending) == 0);
|
||||
|
||||
result = dns_zt_apply(zt, false, NULL, asyncload, zt);
|
||||
|
||||
pending = zt->loads_pending;
|
||||
pending = isc_refcount_current(&zt->loads_pending);
|
||||
|
||||
if (pending != 0) {
|
||||
zt->loaddone = alldone;
|
||||
zt->loaddone_arg = arg;
|
||||
@@ -340,15 +333,16 @@ asyncload(dns_zone_t *zone, void *zt_) {
|
||||
isc_result_t result;
|
||||
struct dns_zt *zt = (dns_zt_t*) zt_;
|
||||
REQUIRE(zone != NULL);
|
||||
INSIST(zt->references > 0);
|
||||
zt->references++;
|
||||
zt->loads_pending++;
|
||||
|
||||
isc_refcount_increment(&zt->references);
|
||||
|
||||
isc_refcount_increment(&zt->loads_pending);
|
||||
|
||||
result = dns_zone_asyncload(zone, zt->loadparams->newonly, *zt->loadparams->dl, zt);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
zt->references--;
|
||||
zt->loads_pending--;
|
||||
INSIST(zt->references > 0);
|
||||
|
||||
isc_refcount_decrement(&zt->references);
|
||||
isc_refcount_decrement(&zt->loads_pending);
|
||||
}
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
@@ -537,7 +531,6 @@ dns_zt_apply(dns_zt_t *zt, bool stop, isc_result_t *sub,
|
||||
*/
|
||||
static isc_result_t
|
||||
doneloading(dns_zt_t *zt, dns_zone_t *zone, isc_task_t *task) {
|
||||
bool destroy = false;
|
||||
dns_zt_allloaded_t alldone = NULL;
|
||||
void *arg = NULL;
|
||||
|
||||
@@ -546,28 +539,21 @@ doneloading(dns_zt_t *zt, dns_zone_t *zone, isc_task_t *task) {
|
||||
|
||||
REQUIRE(VALID_ZT(zt));
|
||||
|
||||
RWLOCK(&zt->rwlock, isc_rwlocktype_write);
|
||||
INSIST(zt->loads_pending != 0);
|
||||
INSIST(zt->references != 0);
|
||||
zt->references--;
|
||||
if (zt->references == 0)
|
||||
destroy = true;
|
||||
zt->loads_pending--;
|
||||
if (zt->loads_pending == 0) {
|
||||
if (isc_refcount_decrement(&zt->loads_pending) == 1) {
|
||||
alldone = zt->loaddone;
|
||||
arg = zt->loaddone_arg;
|
||||
zt->loaddone = NULL;
|
||||
zt->loaddone_arg = NULL;
|
||||
isc_mem_put(zt->mctx, zt->loadparams, sizeof(struct zt_load_params));
|
||||
zt->loadparams = NULL;
|
||||
if (alldone != NULL) {
|
||||
alldone(arg);
|
||||
}
|
||||
}
|
||||
RWUNLOCK(&zt->rwlock, isc_rwlocktype_write);
|
||||
|
||||
if (alldone != NULL)
|
||||
alldone(arg);
|
||||
|
||||
if (destroy)
|
||||
if (isc_refcount_decrement(&zt->references) == 1) {
|
||||
zt_destroy(zt);
|
||||
}
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
+13
-17
@@ -18,6 +18,7 @@
|
||||
#include <isc/counter.h>
|
||||
#include <isc/magic.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/refcount.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#define COUNTER_MAGIC ISC_MAGIC('C', 'n', 't', 'r')
|
||||
@@ -26,7 +27,7 @@
|
||||
struct isc_counter {
|
||||
unsigned int magic;
|
||||
isc_mem_t *mctx;
|
||||
atomic_uint_fast32_t references;
|
||||
isc_refcount_t references;
|
||||
atomic_uint_fast32_t limit;
|
||||
atomic_uint_fast32_t used;
|
||||
};
|
||||
@@ -44,9 +45,9 @@ isc_counter_create(isc_mem_t *mctx, int limit, isc_counter_t **counterp) {
|
||||
counter->mctx = NULL;
|
||||
isc_mem_attach(mctx, &counter->mctx);
|
||||
|
||||
atomic_store(&counter->references, 1);
|
||||
atomic_store(&counter->limit, limit);
|
||||
atomic_store(&counter->used, 0);
|
||||
isc_refcount_init(&counter->references, 1);
|
||||
atomic_init(&counter->limit, limit);
|
||||
atomic_init(&counter->used, 0);
|
||||
|
||||
counter->magic = COUNTER_MAGIC;
|
||||
*counterp = counter;
|
||||
@@ -55,22 +56,21 @@ isc_counter_create(isc_mem_t *mctx, int limit, isc_counter_t **counterp) {
|
||||
|
||||
isc_result_t
|
||||
isc_counter_increment(isc_counter_t *counter) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
uint32_t used = atomic_fetch_add_relaxed(&counter->used, 1) + 1;
|
||||
uint32_t limit = atomic_load_acquire(&counter->limit);
|
||||
|
||||
uint32_t used = atomic_fetch_add(&counter->used, 1) + 1;
|
||||
if (atomic_load(&counter->limit) != 0 &&
|
||||
used >= atomic_load(&counter->limit)) {
|
||||
result = ISC_R_QUOTA;
|
||||
if (limit != 0 && used >= limit) {
|
||||
return (ISC_R_QUOTA);
|
||||
}
|
||||
|
||||
return (result);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
isc_counter_used(isc_counter_t *counter) {
|
||||
REQUIRE(VALID_COUNTER(counter));
|
||||
|
||||
return (atomic_load(&counter->used));
|
||||
return (atomic_load_acquire(&counter->used));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -85,7 +85,7 @@ isc_counter_attach(isc_counter_t *source, isc_counter_t **targetp) {
|
||||
REQUIRE(VALID_COUNTER(source));
|
||||
REQUIRE(targetp != NULL && *targetp == NULL);
|
||||
|
||||
INSIST(atomic_fetch_add(&source->references, 1) > 0);
|
||||
isc_refcount_increment(&source->references);
|
||||
|
||||
*targetp = source;
|
||||
}
|
||||
@@ -99,7 +99,6 @@ destroy(isc_counter_t *counter) {
|
||||
void
|
||||
isc_counter_detach(isc_counter_t **counterp) {
|
||||
isc_counter_t *counter;
|
||||
uint32_t oldrefs;
|
||||
|
||||
REQUIRE(counterp != NULL && *counterp != NULL);
|
||||
counter = *counterp;
|
||||
@@ -107,10 +106,7 @@ isc_counter_detach(isc_counter_t **counterp) {
|
||||
|
||||
*counterp = NULL;
|
||||
|
||||
oldrefs = atomic_fetch_sub(&counter->references, 1);
|
||||
INSIST(oldrefs > 0);
|
||||
|
||||
if (oldrefs == 1) {
|
||||
if (isc_refcount_decrement(&counter->references) == 1) {
|
||||
destroy(counter);
|
||||
}
|
||||
}
|
||||
|
||||
+13
-13
@@ -21,27 +21,27 @@
|
||||
|
||||
void
|
||||
isc_quota_init(isc_quota_t *quota, unsigned int max) {
|
||||
atomic_store("a->max, max);
|
||||
atomic_store("a->used, 0);
|
||||
atomic_init("a->max, max);
|
||||
atomic_init("a->used, 0);
|
||||
atomic_store("a->soft, 0);
|
||||
}
|
||||
|
||||
void
|
||||
isc_quota_destroy(isc_quota_t *quota) {
|
||||
INSIST(atomic_load("a->used) == 0);
|
||||
atomic_store("a->max, 0);
|
||||
atomic_store("a->used, 0);
|
||||
atomic_store("a->soft, 0);
|
||||
atomic_store_release("a->max, 0);
|
||||
atomic_store_release("a->used, 0);
|
||||
atomic_store_release("a->soft, 0);
|
||||
}
|
||||
|
||||
void
|
||||
isc_quota_soft(isc_quota_t *quota, unsigned int soft) {
|
||||
atomic_store("a->soft, soft);
|
||||
atomic_store_release("a->soft, soft);
|
||||
}
|
||||
|
||||
void
|
||||
isc_quota_max(isc_quota_t *quota, unsigned int max) {
|
||||
atomic_store("a->max, max);
|
||||
atomic_store_release("a->max, max);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
@@ -62,9 +62,9 @@ isc_quota_getused(isc_quota_t *quota) {
|
||||
isc_result_t
|
||||
isc_quota_reserve(isc_quota_t *quota) {
|
||||
isc_result_t result;
|
||||
uint32_t max = atomic_load("a->max);
|
||||
uint32_t soft = atomic_load("a->soft);
|
||||
uint32_t used = atomic_fetch_add("a->used, 1);
|
||||
uint32_t max = atomic_load_acquire("a->max);
|
||||
uint32_t soft = atomic_load_acquire("a->soft);
|
||||
uint32_t used = atomic_fetch_add_relaxed("a->used, 1);
|
||||
if (max == 0 || used < max) {
|
||||
if (soft == 0 || used < soft) {
|
||||
result = ISC_R_SUCCESS;
|
||||
@@ -72,7 +72,7 @@ isc_quota_reserve(isc_quota_t *quota) {
|
||||
result = ISC_R_SOFTQUOTA;
|
||||
}
|
||||
} else {
|
||||
INSIST(atomic_fetch_sub("a->used, 1) > 0);
|
||||
INSIST(atomic_fetch_sub_release("a->used, 1) > 0);
|
||||
result = ISC_R_QUOTA;
|
||||
}
|
||||
return (result);
|
||||
@@ -80,7 +80,7 @@ isc_quota_reserve(isc_quota_t *quota) {
|
||||
|
||||
void
|
||||
isc_quota_release(isc_quota_t *quota) {
|
||||
INSIST(atomic_fetch_sub("a->used, 1) > 0);
|
||||
INSIST(atomic_fetch_sub_release("a->used, 1) > 0);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
@@ -93,7 +93,7 @@ doattach(isc_quota_t *quota, isc_quota_t **p, bool force) {
|
||||
*p = quota;
|
||||
} else if (result == ISC_R_QUOTA && force) {
|
||||
/* attach anyway */
|
||||
atomic_fetch_add("a->used, 1);
|
||||
atomic_fetch_add_relaxed("a->used, 1);
|
||||
*p = quota;
|
||||
result = ISC_R_SUCCESS;
|
||||
}
|
||||
|
||||
+4
-4
@@ -33,7 +33,7 @@ typedef atomic_int_fast64_t isc_stat_t;
|
||||
struct isc_stats {
|
||||
unsigned int magic;
|
||||
isc_mem_t *mctx;
|
||||
isc_refcount_t refs;
|
||||
isc_refcount_t references;
|
||||
int ncounters;
|
||||
isc_stat_t *counters;
|
||||
};
|
||||
@@ -46,7 +46,7 @@ create_stats(isc_mem_t *mctx, int ncounters, isc_stats_t **statsp) {
|
||||
|
||||
stats = isc_mem_get(mctx, sizeof(*stats));
|
||||
stats->counters = isc_mem_get(mctx, sizeof(isc_stat_t) * ncounters);
|
||||
isc_refcount_init(&stats->refs, 1);
|
||||
isc_refcount_init(&stats->references, 1);
|
||||
memset(stats->counters, 0, sizeof(isc_stat_t) * ncounters);
|
||||
stats->mctx = NULL;
|
||||
isc_mem_attach(mctx, &stats->mctx);
|
||||
@@ -62,7 +62,7 @@ isc_stats_attach(isc_stats_t *stats, isc_stats_t **statsp) {
|
||||
REQUIRE(ISC_STATS_VALID(stats));
|
||||
REQUIRE(statsp != NULL && *statsp == NULL);
|
||||
|
||||
isc_refcount_increment(&stats->refs);
|
||||
isc_refcount_increment(&stats->references);
|
||||
*statsp = stats;
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ isc_stats_detach(isc_stats_t **statsp) {
|
||||
stats = *statsp;
|
||||
*statsp = NULL;
|
||||
|
||||
if (isc_refcount_decrement(&stats->refs) == 1) {
|
||||
if (isc_refcount_decrement(&stats->referencess) == 1) {
|
||||
isc_mem_put(stats->mctx, stats->counters,
|
||||
sizeof(isc_stat_t) * stats->ncounters);
|
||||
isc_mem_putanddetach(&stats->mctx, stats, sizeof(*stats));
|
||||
|
||||
+13
-14
@@ -30,6 +30,7 @@
|
||||
#include <isc/print.h>
|
||||
#include <isc/string.h>
|
||||
#include <isc/random.h>
|
||||
#include <isc/refcount.h>
|
||||
#include <isc/task.h>
|
||||
#include <isc/thread.h>
|
||||
#include <isc/time.h>
|
||||
@@ -94,7 +95,7 @@ struct isc__task {
|
||||
isc_mutex_t lock;
|
||||
/* Locked by task lock. */
|
||||
task_state_t state;
|
||||
unsigned int references;
|
||||
isc_refcount_t references;
|
||||
isc_eventlist_t events;
|
||||
isc_eventlist_t on_shutdown;
|
||||
unsigned int nevents;
|
||||
@@ -288,7 +289,8 @@ isc_task_create_bound(isc_taskmgr_t *manager0, unsigned int quantum,
|
||||
|
||||
isc_mutex_init(&task->lock);
|
||||
task->state = task_state_idle;
|
||||
task->references = 1;
|
||||
|
||||
isc_refcount_init(&task->references, 1);
|
||||
INIT_LIST(task->events);
|
||||
INIT_LIST(task->on_shutdown);
|
||||
task->nevents = 0;
|
||||
@@ -338,9 +340,7 @@ isc_task_attach(isc_task_t *source0, isc_task_t **targetp) {
|
||||
|
||||
XTTRACE(source, "isc_task_attach");
|
||||
|
||||
LOCK(&source->lock);
|
||||
source->references++;
|
||||
UNLOCK(&source->lock);
|
||||
isc_refcount_increment(&source->references);
|
||||
|
||||
*targetp = (isc_task_t *)source;
|
||||
}
|
||||
@@ -413,12 +413,11 @@ task_detach(isc__task_t *task) {
|
||||
* Caller must be holding the task lock.
|
||||
*/
|
||||
|
||||
REQUIRE(task->references > 0);
|
||||
|
||||
XTRACE("detach");
|
||||
|
||||
task->references--;
|
||||
if (task->references == 0 && task->state == task_state_idle) {
|
||||
if (isc_refcount_decrement(&task->references) == 1 &&
|
||||
task->state == task_state_idle)
|
||||
{
|
||||
INSIST(EMPTY(task->events));
|
||||
/*
|
||||
* There are no references to this task, and no
|
||||
@@ -1133,7 +1132,7 @@ dispatch(isc__taskmgr_t *manager, unsigned int threadid) {
|
||||
dispatch_count++;
|
||||
}
|
||||
|
||||
if (task->references == 0 &&
|
||||
if (isc_refcount_current(&task->references) == 0 &&
|
||||
EMPTY(task->events) &&
|
||||
!TASK_SHUTTINGDOWN(task)) {
|
||||
bool was_idle;
|
||||
@@ -1170,7 +1169,7 @@ dispatch(isc__taskmgr_t *manager, unsigned int threadid) {
|
||||
* right now.
|
||||
*/
|
||||
XTRACE("empty");
|
||||
if (task->references == 0 &&
|
||||
if (isc_refcount_current(&task->references) == 0 &&
|
||||
TASK_SHUTTINGDOWN(task)) {
|
||||
/*
|
||||
* The task is done.
|
||||
@@ -1724,8 +1723,8 @@ isc_taskmgr_renderxml(isc_taskmgr_t *mgr0, xmlTextWriterPtr writer) {
|
||||
|
||||
TRY0(xmlTextWriterStartElement(writer,
|
||||
ISC_XMLCHAR "references"));
|
||||
TRY0(xmlTextWriterWriteFormatString(writer, "%d",
|
||||
task->references));
|
||||
TRY0(xmlTextWriterWriteFormatString(writer, "%" PRIuFAST32,
|
||||
isc_refcount_current(&task->references)));
|
||||
TRY0(xmlTextWriterEndElement(writer)); /* references */
|
||||
|
||||
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "id"));
|
||||
@@ -1834,7 +1833,7 @@ isc_taskmgr_renderjson(isc_taskmgr_t *mgr0, json_object *tasks) {
|
||||
json_object_object_add(taskobj, "name", obj);
|
||||
}
|
||||
|
||||
obj = json_object_new_int(task->references);
|
||||
obj = json_object_new_int(isc_refcount_current(&task->references));
|
||||
CHECKMEM(obj);
|
||||
json_object_object_add(taskobj, "references", obj);
|
||||
|
||||
|
||||
+10
-16
@@ -23,6 +23,7 @@
|
||||
#include <isc/once.h>
|
||||
#include <isc/platform.h>
|
||||
#include <isc/print.h>
|
||||
#include <isc/refcount.h>
|
||||
#include <isc/task.h>
|
||||
#include <isc/thread.h>
|
||||
#include <isc/time.h>
|
||||
@@ -61,8 +62,9 @@ struct isc__timer {
|
||||
isc_timer_t common;
|
||||
isc__timermgr_t * manager;
|
||||
isc_mutex_t lock;
|
||||
/* Atomic */
|
||||
isc_refcount_t references;
|
||||
/*! Locked by timer lock. */
|
||||
unsigned int references;
|
||||
isc_time_t idle;
|
||||
/*! Locked by manager lock. */
|
||||
isc_timertype_t type;
|
||||
@@ -284,7 +286,8 @@ isc_timer_create(isc_timermgr_t *manager0, isc_timertype_t type,
|
||||
return (ISC_R_NOMEMORY);
|
||||
|
||||
timer->manager = manager;
|
||||
timer->references = 1;
|
||||
|
||||
isc_refcount_init(&timer->references, 1);
|
||||
|
||||
if (type == isc_timertype_once && !isc_interval_iszero(interval)) {
|
||||
result = isc_time_add(&now, interval, &timer->idle);
|
||||
@@ -480,9 +483,7 @@ isc_timer_attach(isc_timer_t *timer0, isc_timer_t **timerp) {
|
||||
REQUIRE(VALID_TIMER(timer));
|
||||
REQUIRE(timerp != NULL && *timerp == NULL);
|
||||
|
||||
LOCK(&timer->lock);
|
||||
timer->references++;
|
||||
UNLOCK(&timer->lock);
|
||||
isc_refcount_increment(&timer->references);
|
||||
|
||||
*timerp = (isc_timer_t *)timer;
|
||||
}
|
||||
@@ -490,7 +491,6 @@ isc_timer_attach(isc_timer_t *timer0, isc_timer_t **timerp) {
|
||||
void
|
||||
isc_timer_detach(isc_timer_t **timerp) {
|
||||
isc__timer_t *timer;
|
||||
bool free_timer = false;
|
||||
|
||||
/*
|
||||
* Detach *timerp from its timer.
|
||||
@@ -500,17 +500,11 @@ isc_timer_detach(isc_timer_t **timerp) {
|
||||
timer = (isc__timer_t *)*timerp;
|
||||
REQUIRE(VALID_TIMER(timer));
|
||||
|
||||
LOCK(&timer->lock);
|
||||
REQUIRE(timer->references > 0);
|
||||
timer->references--;
|
||||
if (timer->references == 0)
|
||||
free_timer = true;
|
||||
UNLOCK(&timer->lock);
|
||||
|
||||
if (free_timer)
|
||||
destroy(timer);
|
||||
|
||||
*timerp = NULL;
|
||||
|
||||
if (isc_refcount_decrement(&timer->references) == 1) {
|
||||
destroy(timer);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+25
-22
@@ -223,7 +223,7 @@ struct isc_socket {
|
||||
|
||||
/* Locked by socket lock. */
|
||||
ISC_LINK(isc_socket_t) link;
|
||||
unsigned int references; /* EXTERNAL references */
|
||||
isc_refcount_t references; /* EXTERNAL references */
|
||||
SOCKET fd; /* file handle */
|
||||
int pf; /* protocol family */
|
||||
char name[16];
|
||||
@@ -383,7 +383,7 @@ sock_dump(isc_socket_t *sock) {
|
||||
|
||||
printf("\n\t\tSock Dump\n");
|
||||
printf("\t\tfd: %Iu\n", sock->fd);
|
||||
printf("\t\treferences: %u\n", sock->references);
|
||||
printf("\t\treferences: %u\n", isc_refcount_current(sock->references));
|
||||
printf("\t\tpending_accept: %u\n", sock->pending_accept);
|
||||
printf("\t\tconnecting: %u\n", sock->pending_connect);
|
||||
printf("\t\tconnected: %u\n", sock->connected);
|
||||
@@ -1311,7 +1311,7 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type,
|
||||
return (ISC_R_NOMEMORY);
|
||||
|
||||
sock->magic = 0;
|
||||
sock->references = 0;
|
||||
isc_refcount_init(&sock->references, 0);
|
||||
|
||||
sock->manager = manager;
|
||||
sock->type = type;
|
||||
@@ -1440,7 +1440,7 @@ maybe_free_socket(isc_socket_t **socketp, int lineno) {
|
||||
|| sock->pending_recv > 0
|
||||
|| sock->pending_send > 0
|
||||
|| sock->pending_accept > 0
|
||||
|| sock->references > 0
|
||||
|| isc_refcount_current(sock->references) > 0
|
||||
|| sock->pending_connect == 1
|
||||
|| !ISC_LIST_EMPTY(sock->recv_list)
|
||||
|| !ISC_LIST_EMPTY(sock->send_list)
|
||||
@@ -1533,7 +1533,7 @@ socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
|
||||
"con_reset_fix_failed",
|
||||
sock->pending_recv,
|
||||
sock->pending_send,
|
||||
sock->references);
|
||||
isc_refcount_current(sock->references));
|
||||
closesocket(sock->fd);
|
||||
_set_state(sock, SOCK_CLOSED);
|
||||
sock->fd = INVALID_SOCKET;
|
||||
@@ -1581,10 +1581,11 @@ socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
|
||||
|
||||
result = make_nonblock(sock->fd);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
|
||||
socket_log(__LINE__, sock, NULL, EVENT,
|
||||
"closed %d %d %d make_nonblock_failed",
|
||||
sock->pending_recv, sock->pending_send,
|
||||
sock->references);
|
||||
"closed %d %d %d make_nonblock_failed",
|
||||
sock->pending_recv, sock->pending_send,
|
||||
isc_refcount_current(sock->references));
|
||||
closesocket(sock->fd);
|
||||
sock->fd = INVALID_SOCKET;
|
||||
free_socket(&sock, __LINE__);
|
||||
@@ -1638,7 +1639,7 @@ socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
|
||||
#endif /* defined(USE_CMSG) || defined(SO_RCVBUF) */
|
||||
|
||||
_set_state(sock, SOCK_OPEN);
|
||||
sock->references = 1;
|
||||
isc_refcount_init(&sock->references, 1);
|
||||
*socketp = sock;
|
||||
|
||||
iocompletionport_update(sock);
|
||||
@@ -1714,9 +1715,10 @@ isc_socket_attach(isc_socket_t *sock, isc_socket_t **socketp) {
|
||||
|
||||
LOCK(&sock->lock);
|
||||
CONSISTENT(sock);
|
||||
sock->references++;
|
||||
UNLOCK(&sock->lock);
|
||||
|
||||
isc_refcount_increment(&sock->references);
|
||||
|
||||
*socketp = sock;
|
||||
}
|
||||
|
||||
@@ -1727,6 +1729,7 @@ isc_socket_attach(isc_socket_t *sock, isc_socket_t **socketp) {
|
||||
void
|
||||
isc_socket_detach(isc_socket_t **socketp) {
|
||||
isc_socket_t *sock;
|
||||
uint32_t refs;
|
||||
|
||||
REQUIRE(socketp != NULL);
|
||||
sock = *socketp;
|
||||
@@ -1734,21 +1737,21 @@ isc_socket_detach(isc_socket_t **socketp) {
|
||||
|
||||
LOCK(&sock->lock);
|
||||
CONSISTENT(sock);
|
||||
REQUIRE(sock->references > 0);
|
||||
sock->references--;
|
||||
|
||||
references = isc_refcount_decrement(&socket->references);
|
||||
|
||||
socket_log(__LINE__, sock, NULL, EVENT,
|
||||
"detach_socket %d %d %d",
|
||||
sock->pending_recv, sock->pending_send,
|
||||
sock->references);
|
||||
"detach_socket %d %d %d",
|
||||
sock->pending_recv, sock->pending_send,
|
||||
isc_refcount_current(sock->references));
|
||||
|
||||
if (sock->references == 0 && sock->fd != INVALID_SOCKET) {
|
||||
if (references == 1 && sock->fd != INVALID_SOCKET) {
|
||||
closesocket(sock->fd);
|
||||
sock->fd = INVALID_SOCKET;
|
||||
_set_state(sock, SOCK_CLOSED);
|
||||
}
|
||||
|
||||
maybe_free_socket(&sock, __LINE__);
|
||||
maybe_free_socket(&sock, __LINE__); /* Also unlocks the socket lock */
|
||||
|
||||
*socketp = NULL;
|
||||
}
|
||||
@@ -2406,7 +2409,7 @@ SocketIoThread(LPVOID ThreadContext) {
|
||||
if (acceptdone_is_active(sock, lpo->adev)) {
|
||||
closesocket(lpo->adev->newsocket->fd);
|
||||
lpo->adev->newsocket->fd = INVALID_SOCKET;
|
||||
lpo->adev->newsocket->references--;
|
||||
isc_refcount_decrement(&lpo->adev->newsocket->references);
|
||||
free_socket(&lpo->adev->newsocket, __LINE__);
|
||||
lpo->adev->result = isc_result;
|
||||
socket_log(__LINE__, sock, NULL, EVENT,
|
||||
@@ -3100,7 +3103,7 @@ isc_socket_accept(isc_socket_t *sock,
|
||||
UNLOCK(&sock->lock);
|
||||
return (ISC_R_SHUTTINGDOWN);
|
||||
}
|
||||
nsock->references++;
|
||||
isc_refcount_decrement(&nsock->references);
|
||||
|
||||
adev->ev_sender = ntask;
|
||||
adev->newsocket = nsock;
|
||||
@@ -3437,7 +3440,7 @@ isc_socket_cancel(isc_socket_t *sock, isc_task_t *task, unsigned int how) {
|
||||
|
||||
if ((task == NULL) || (task == current_task)) {
|
||||
|
||||
dev->newsocket->references--;
|
||||
isc_refcount_decrement(&dev->newsocket->references);
|
||||
closesocket(dev->newsocket->fd);
|
||||
dev->newsocket->fd = INVALID_SOCKET;
|
||||
free_socket(&dev->newsocket, __LINE__);
|
||||
@@ -3661,7 +3664,7 @@ isc_socketmgr_renderxml(isc_socketmgr_t *mgr, xmlTextWriterPtr writer)
|
||||
TRY0(xmlTextWriterStartElement(writer,
|
||||
ISC_XMLCHAR "references"));
|
||||
TRY0(xmlTextWriterWriteFormatString(writer, "%d",
|
||||
sock->references));
|
||||
isc_refcount_current(sock->references)));
|
||||
TRY0(xmlTextWriterEndElement(writer));
|
||||
|
||||
TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "type",
|
||||
@@ -3780,7 +3783,7 @@ isc_socketmgr_renderjson(isc_socketmgr_t *mgr, json_object *stats) {
|
||||
json_object_object_add(entry, "name", obj);
|
||||
}
|
||||
|
||||
obj = json_object_new_int(sock->references);
|
||||
obj = json_object_new_int(isc_refcount_current(&sock->references));
|
||||
CHECKMEM(obj);
|
||||
json_object_object_add(entry, "references", obj);
|
||||
|
||||
|
||||
+11
-8
@@ -489,7 +489,7 @@ exit_check(ns_client_t *client) {
|
||||
}
|
||||
|
||||
if (! (client->nsends == 0 && client->nrecvs == 0 &&
|
||||
client->references == 0))
|
||||
isc_refcount_current(&client->references) == 0))
|
||||
{
|
||||
/*
|
||||
* Still waiting for I/O cancel completion.
|
||||
@@ -3175,7 +3175,7 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) {
|
||||
client->nrecvs = 0;
|
||||
client->nupdates = 0;
|
||||
client->nctls = 0;
|
||||
client->references = 0;
|
||||
isc_refcount_init(&client->references, 0);
|
||||
client->attributes = 0;
|
||||
client->view = NULL;
|
||||
client->dispatch = NULL;
|
||||
@@ -3549,10 +3549,11 @@ ns_client_attach(ns_client_t *source, ns_client_t **targetp) {
|
||||
REQUIRE(NS_CLIENT_VALID(source));
|
||||
REQUIRE(targetp != NULL && *targetp == NULL);
|
||||
|
||||
source->references++;
|
||||
uint32_t references = isc_refcount_increment(&source->references) + 1;
|
||||
|
||||
ns_client_log(source, NS_LOGCATEGORY_CLIENT,
|
||||
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10),
|
||||
"ns_client_attach: ref = %d", source->references);
|
||||
"ns_client_attach: ref = %d", references);
|
||||
*targetp = source;
|
||||
}
|
||||
|
||||
@@ -3560,12 +3561,13 @@ void
|
||||
ns_client_detach(ns_client_t **clientp) {
|
||||
ns_client_t *client = *clientp;
|
||||
|
||||
client->references--;
|
||||
INSIST(client->references >= 0);
|
||||
*clientp = NULL;
|
||||
|
||||
uint32_t references = isc_refcount_decrement(&client->references) - 1;
|
||||
|
||||
ns_client_log(client, NS_LOGCATEGORY_CLIENT,
|
||||
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(10),
|
||||
"ns_client_detach: ref = %d", client->references);
|
||||
"ns_client_detach: ref = %d", references);
|
||||
(void)exit_check(client);
|
||||
}
|
||||
|
||||
@@ -3924,7 +3926,8 @@ ns__clientmgr_getclient(ns_clientmgr_t *manager, ns_interface_t *ifp,
|
||||
INSIST(client->recursionquota == NULL);
|
||||
|
||||
client->dscp = ifp->dscp;
|
||||
client->references++;
|
||||
|
||||
isc_refcount_increment(&client->references);
|
||||
|
||||
if (tcp) {
|
||||
client->attributes |= NS_CLIENTATTR_TCP;
|
||||
|
||||
@@ -101,7 +101,7 @@ struct ns_client {
|
||||
int nrecvs;
|
||||
int nupdates;
|
||||
int nctls;
|
||||
int references;
|
||||
isc_refcount_t references;
|
||||
bool tcpactive;
|
||||
bool needshutdown; /*
|
||||
* Used by clienttest to get
|
||||
|
||||
@@ -68,7 +68,7 @@ struct ns_interface {
|
||||
unsigned int magic; /*%< Magic number. */
|
||||
ns_interfacemgr_t * mgr; /*%< Interface manager. */
|
||||
isc_mutex_t lock;
|
||||
int references; /*%< Locked */
|
||||
isc_refcount_t references; /*%< Atomic */
|
||||
unsigned int generation; /*%< Generation number. */
|
||||
isc_sockaddr_t addr; /*%< Address and port. */
|
||||
unsigned int flags; /*%< Interface characteristics */
|
||||
|
||||
+19
-31
@@ -64,7 +64,7 @@
|
||||
/*% nameserver interface manager structure */
|
||||
struct ns_interfacemgr {
|
||||
unsigned int magic; /*%< Magic number. */
|
||||
int references;
|
||||
isc_refcount_t references;
|
||||
isc_mutex_t lock;
|
||||
isc_mem_t * mctx; /*%< Memory context. */
|
||||
ns_server_t * sctx; /*%< Server context. */
|
||||
@@ -251,11 +251,12 @@ ns_interfacemgr_create(isc_mem_t *mctx,
|
||||
}
|
||||
|
||||
mgr->task = NULL;
|
||||
if (mgr->route != NULL)
|
||||
if (mgr->route != NULL) {
|
||||
isc_task_attach(task, &mgr->task);
|
||||
mgr->references = (mgr->route != NULL) ? 2 : 1;
|
||||
}
|
||||
isc_refcount_init(&mgr->references, (mgr->route != NULL) ? 2 : 1);
|
||||
#else
|
||||
mgr->references = 1;
|
||||
isc_refcount_init(&mgr->references, 1);
|
||||
#endif
|
||||
mgr->magic = IFMGR_MAGIC;
|
||||
*mgrp = mgr;
|
||||
@@ -332,28 +333,21 @@ ns_interfacemgr_getaclenv(ns_interfacemgr_t *mgr) {
|
||||
void
|
||||
ns_interfacemgr_attach(ns_interfacemgr_t *source, ns_interfacemgr_t **target) {
|
||||
REQUIRE(NS_INTERFACEMGR_VALID(source));
|
||||
LOCK(&source->lock);
|
||||
INSIST(source->references > 0);
|
||||
source->references++;
|
||||
UNLOCK(&source->lock);
|
||||
isc_refcount_increment(&source->references);
|
||||
*target = source;
|
||||
}
|
||||
|
||||
void
|
||||
ns_interfacemgr_detach(ns_interfacemgr_t **targetp) {
|
||||
isc_result_t need_destroy = false;
|
||||
ns_interfacemgr_t *target = *targetp;
|
||||
REQUIRE(target != NULL);
|
||||
REQUIRE(NS_INTERFACEMGR_VALID(target));
|
||||
LOCK(&target->lock);
|
||||
REQUIRE(target->references > 0);
|
||||
target->references--;
|
||||
if (target->references == 0)
|
||||
need_destroy = true;
|
||||
UNLOCK(&target->lock);
|
||||
if (need_destroy)
|
||||
ns_interfacemgr_destroy(target);
|
||||
|
||||
*targetp = NULL;
|
||||
|
||||
if (isc_refcount_decrement(&target->references) == 1) {
|
||||
ns_interfacemgr_destroy(target);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -435,7 +429,8 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
|
||||
ns_interfacemgr_attach(mgr, &ifp->mgr);
|
||||
ISC_LIST_APPEND(mgr->interfaces, ifp, link);
|
||||
|
||||
ifp->references = 1;
|
||||
isc_refcount_init(&ifp->references, 1);
|
||||
|
||||
ifp->magic = IFACE_MAGIC;
|
||||
*ifpret = ifp;
|
||||
|
||||
@@ -667,28 +662,21 @@ ns_interface_destroy(ns_interface_t *ifp) {
|
||||
void
|
||||
ns_interface_attach(ns_interface_t *source, ns_interface_t **target) {
|
||||
REQUIRE(NS_INTERFACE_VALID(source));
|
||||
LOCK(&source->lock);
|
||||
INSIST(source->references > 0);
|
||||
source->references++;
|
||||
UNLOCK(&source->lock);
|
||||
isc_refcount_increment(&source->references);
|
||||
*target = source;
|
||||
}
|
||||
|
||||
void
|
||||
ns_interface_detach(ns_interface_t **targetp) {
|
||||
isc_result_t need_destroy = false;
|
||||
ns_interface_t *target = *targetp;
|
||||
REQUIRE(target != NULL);
|
||||
REQUIRE(NS_INTERFACE_VALID(target));
|
||||
LOCK(&target->lock);
|
||||
REQUIRE(target->references > 0);
|
||||
target->references--;
|
||||
if (target->references == 0)
|
||||
need_destroy = true;
|
||||
UNLOCK(&target->lock);
|
||||
if (need_destroy)
|
||||
ns_interface_destroy(target);
|
||||
|
||||
*targetp = NULL;
|
||||
|
||||
if (isc_refcount_decrement(&target->references) == 1) {
|
||||
ns_interface_destroy(target);
|
||||
}
|
||||
}
|
||||
|
||||
/*%
|
||||
|
||||
+8
-19
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <isc/mem.h>
|
||||
#include <isc/mutex.h>
|
||||
#include <isc/refcount.h>
|
||||
#include <isc/once.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
@@ -38,8 +39,7 @@ LIBNS_EXTERNAL_DATA unsigned int ns_pps = 0U;
|
||||
static isc_once_t init_once = ISC_ONCE_INIT;
|
||||
static isc_mem_t *ns_g_mctx = NULL;
|
||||
static bool initialize_done = false;
|
||||
static isc_mutex_t reflock;
|
||||
static unsigned int references = 0;
|
||||
static isc_refcount_t references = 0;
|
||||
|
||||
static void
|
||||
initialize(void) {
|
||||
@@ -51,8 +51,6 @@ initialize(void) {
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return;
|
||||
|
||||
isc_mutex_init(&reflock);
|
||||
|
||||
initialize_done = true;
|
||||
return;
|
||||
}
|
||||
@@ -73,25 +71,16 @@ ns_lib_init(void) {
|
||||
if (!initialize_done)
|
||||
return (ISC_R_FAILURE);
|
||||
|
||||
LOCK(&reflock);
|
||||
references++;
|
||||
UNLOCK(&reflock);
|
||||
isc_refcount_increment0(&references);
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
void
|
||||
ns_lib_shutdown(void) {
|
||||
bool cleanup_ok = false;
|
||||
|
||||
LOCK(&reflock);
|
||||
if (--references == 0)
|
||||
cleanup_ok = true;
|
||||
UNLOCK(&reflock);
|
||||
|
||||
if (!cleanup_ok)
|
||||
return;
|
||||
|
||||
if (ns_g_mctx != NULL)
|
||||
isc_mem_detach(&ns_g_mctx);
|
||||
if (isc_refcount_decrement(&references) == 1) {
|
||||
if (ns_g_mctx != NULL) {
|
||||
isc_mem_detach(&ns_g_mctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
-20
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <isc/magic.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/refcount.h>
|
||||
#include <isc/stats.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
@@ -25,11 +26,8 @@ struct ns_stats {
|
||||
/*% Unlocked */
|
||||
unsigned int magic;
|
||||
isc_mem_t *mctx;
|
||||
isc_mutex_t lock;
|
||||
isc_stats_t *counters;
|
||||
|
||||
/*% Locked by lock */
|
||||
unsigned int references;
|
||||
isc_refcount_t references;
|
||||
};
|
||||
|
||||
void
|
||||
@@ -37,9 +35,7 @@ ns_stats_attach(ns_stats_t *stats, ns_stats_t **statsp) {
|
||||
REQUIRE(NS_STATS_VALID(stats));
|
||||
REQUIRE(statsp != NULL && *statsp == NULL);
|
||||
|
||||
LOCK(&stats->lock);
|
||||
stats->references++;
|
||||
UNLOCK(&stats->lock);
|
||||
isc_refcount_increment(&stats->references);
|
||||
|
||||
*statsp = stats;
|
||||
}
|
||||
@@ -53,14 +49,10 @@ ns_stats_detach(ns_stats_t **statsp) {
|
||||
stats = *statsp;
|
||||
*statsp = NULL;
|
||||
|
||||
LOCK(&stats->lock);
|
||||
stats->references--;
|
||||
UNLOCK(&stats->lock);
|
||||
|
||||
if (stats->references == 0) {
|
||||
if (isc_refcount_decrement(&stats->references) == 1) {
|
||||
isc_stats_detach(&stats->counters);
|
||||
isc_mutex_destroy(&stats->lock);
|
||||
isc_mem_putanddetach(&stats->mctx, stats, sizeof(*stats));
|
||||
isc_refcount_destroy(&stats->references);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,17 +64,18 @@ ns_stats_create(isc_mem_t *mctx, int ncounters, ns_stats_t **statsp) {
|
||||
REQUIRE(statsp != NULL && *statsp == NULL);
|
||||
|
||||
stats = isc_mem_get(mctx, sizeof(*stats));
|
||||
if (stats == NULL)
|
||||
if (stats == NULL) {
|
||||
return (ISC_R_NOMEMORY);
|
||||
}
|
||||
|
||||
stats->counters = NULL;
|
||||
stats->references = 1;
|
||||
|
||||
isc_mutex_init(&stats->lock);
|
||||
isc_refcount_init(&stats->references, 1);
|
||||
|
||||
result = isc_stats_create(mctx, &stats->counters, ncounters);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto clean_mutex;
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto clean_mem;
|
||||
}
|
||||
|
||||
stats->magic = NS_STATS_MAGIC;
|
||||
stats->mctx = NULL;
|
||||
@@ -91,8 +84,7 @@ ns_stats_create(isc_mem_t *mctx, int ncounters, ns_stats_t **statsp) {
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
clean_mutex:
|
||||
isc_mutex_destroy(&stats->lock);
|
||||
clean_mem:
|
||||
isc_mem_put(mctx, stats, sizeof(*stats));
|
||||
|
||||
return (result);
|
||||
|
||||
Reference in New Issue
Block a user