#define RBTDB_LOCK(l, t) RWLOCK((l), (t))
#define RBTDB_UNLOCK(l, t) RWUNLOCK((l), (t))
-/*
- * Since node locking is sensitive to both performance and memory footprint,
- * we need some trick here. If we have both high-performance rwlock and
- * high performance and small-memory reference counters, we use rwlock for
- * node lock and isc_refcount for node references. In this case, we don't have
- * to protect the access to the counters by locks.
- */
typedef isc_rwlock_t nodelock_t;
+#ifdef DNS_RBTDB_STRONG_RWLOCK_CHECK
+
+#define NODE_INITLOCK(l) isc_rwlock_init((l), 0, 0)
+#define NODE_DESTROYLOCK(l) isc_rwlock_destroy(l)
+#define NODE_LOCK(l, t, tp) \
+ { \
+ REQUIRE(*tp == isc_rwlocktype_none); \
+ RWLOCK((l), (t)); \
+ *tp = t; \
+ }
+#define NODE_RDLOCK(l, tp) NODE_LOCK(l, isc_rwlocktype_read, tp);
+#define NODE_WRLOCK(l, tp) NODE_LOCK(l, isc_rwlocktype_write, tp);
+
+#define NODE_UNLOCK(l, tp) \
+ { \
+ REQUIRE(*tp != isc_rwlocktype_none); \
+ RWUNLOCK(l, *tp); \
+ *tp = isc_rwlocktype_none; \
+ }
+#define NODE_TRYLOCK(l, t, tp) \
+ ({ \
+ REQUIRE(*tp == isc_rwlocktype_none); \
+ isc_result_t _result = isc_rwlock_trylock(l, t); \
+ if (_result == ISC_R_SUCCESS) { \
+ *tp = t; \
+ }; \
+ _result; \
+ })
+#define NODE_TRYRDLOCK(l, tp) NODE_TRYLOCK(l, isc_rwlocktype_read, tp)
+#define NODE_TRYWRLOCK(l, tp) NODE_TRYLOCK(l, isc_rwlocktype_write, tp)
+#define NODE_TRYUPGRADE(l, tp) \
+ ({ \
+ REQUIRE(*tp == isc_rwlocktype_read); \
+ isc_result_t _result = isc_rwlock_tryupgrade(l); \
+ if (_result == ISC_R_SUCCESS) { \
+ *tp = isc_rwlocktype_write; \
+ }; \
+ _result; \
+ })
+
+typedef isc_rwlock_t treelock_t;
+
+#define TREE_INITLOCK(l) isc_rwlock_init(l, 0, 0)
+#define TREE_DESTROYLOCK(l) isc_rwlock_destroy(l)
+#define TREE_LOCK(l, t, tp) \
+ { \
+ REQUIRE(*tp == isc_rwlocktype_none); \
+ RWLOCK(l, t); \
+ *tp = t; \
+ }
+#define TREE_RDLOCK(l, tp) TREE_LOCK(l, isc_rwlocktype_read, tp);
+#define TREE_WRLOCK(l, tp) TREE_LOCK(l, isc_rwlocktype_write, tp);
+#define TREE_UNLOCK(l, tp) \
+ { \
+ REQUIRE(*tp != isc_rwlocktype_none); \
+ RWUNLOCK(l, *tp); \
+ *tp = isc_rwlocktype_none; \
+ }
+#define TREE_TRYLOCK(l, t, tp) \
+ ({ \
+ REQUIRE(*tp == isc_rwlocktype_none); \
+ isc_result_t _result = isc_rwlock_trylock(l, t); \
+ if (_result == ISC_R_SUCCESS) { \
+ *tp = t; \
+ }; \
+ _result; \
+ })
+#define TREE_TRYRDLOCK(l, tp) TREE_TRYLOCK(l, isc_rwlocktype_read, tp)
+#define TREE_TRYWRLOCK(l, tp) TREE_TRYLOCK(l, isc_rwlocktype_write, tp)
+#define TREE_TRYUPGRADE(l, tp) \
+ ({ \
+ REQUIRE(*tp == isc_rwlocktype_read); \
+ isc_result_t _result = isc_rwlock_tryupgrade(l); \
+ if (_result == ISC_R_SUCCESS) { \
+ *tp = isc_rwlocktype_write; \
+ }; \
+ _result; \
+ })
+
+#else /* DNS_RBTDB_STRONG_RWLOCK_CHECK */
+
#define NODE_INITLOCK(l) isc_rwlock_init((l), 0, 0)
#define NODE_DESTROYLOCK(l) isc_rwlock_destroy(l)
-#define NODE_LOCK(l, t) RWLOCK((l), (t))
-#define NODE_UNLOCK(l, t) RWUNLOCK((l), (t))
-#define NODE_TRYUPGRADE(l) isc_rwlock_tryupgrade(l)
+#define NODE_LOCK(l, t, tp) \
+ { \
+ RWLOCK((l), (t)); \
+ *tp = t; \
+ }
+#define NODE_RDLOCK(l, tp) NODE_LOCK(l, isc_rwlocktype_read, tp);
+#define NODE_WRLOCK(l, tp) NODE_LOCK(l, isc_rwlocktype_write, tp);
+
+#define NODE_UNLOCK(l, tp) \
+ { \
+ RWUNLOCK(l, *tp); \
+ *tp = isc_rwlocktype_none; \
+ }
+#define NODE_TRYLOCK(l, t, tp) \
+ ({ \
+ isc_result_t _result = isc_rwlock_trylock(l, t); \
+ if (_result == ISC_R_SUCCESS) { \
+ *tp = t; \
+ }; \
+ _result; \
+ })
+#define NODE_TRYRDLOCK(l, tp) NODE_TRYLOCK(l, isc_rwlocktype_read, tp)
+#define NODE_TRYWRLOCK(l, tp) NODE_TRYLOCK(l, isc_rwlocktype_write, tp)
+#define NODE_TRYUPGRADE(l, tp) \
+ ({ \
+ isc_result_t _result = isc_rwlock_tryupgrade(l); \
+ if (_result == ISC_R_SUCCESS) { \
+ *tp = isc_rwlocktype_write; \
+ }; \
+ _result; \
+ })
+
+typedef isc_rwlock_t treelock_t;
+
+#define TREE_INITLOCK(l) isc_rwlock_init(l, 0, 0)
+#define TREE_DESTROYLOCK(l) isc_rwlock_destroy(l)
+#define TREE_LOCK(l, t, tp) \
+ { \
+ RWLOCK(l, t); \
+ *tp = t; \
+ }
+#define TREE_RDLOCK(l, tp) \
+ { \
+ TREE_LOCK(l, isc_rwlocktype_read, tp); \
+ }
+#define TREE_WRLOCK(l, tp) \
+ { \
+ TREE_LOCK(l, isc_rwlocktype_write, tp); \
+ }
+#define TREE_UNLOCK(l, tp) \
+ { \
+ RWUNLOCK(l, *tp); \
+ *tp = isc_rwlocktype_none; \
+ }
+#define TREE_TRYLOCK(l, t, tp) \
+ ({ \
+ isc_result_t _result = isc_rwlock_trylock(l, t); \
+ if (_result == ISC_R_SUCCESS) { \
+ *tp = t; \
+ }; \
+ _result; \
+ })
+#define TREE_TRYRDLOCK(l, tp) TREE_TRYLOCK(l, isc_rwlocktype_read, tp)
+#define TREE_TRYWRLOCK(l, tp) TREE_TRYLOCK(l, isc_rwlocktype_write, tp)
+#define TREE_TRYUPGRADE(l, tp) \
+ ({ \
+ isc_result_t _result = isc_rwlock_tryupgrade(l); \
+ if (_result == ISC_R_SUCCESS) { \
+ *tp = isc_rwlocktype_write; \
+ }; \
+ _result; \
+ })
+
+#endif
/*%
* Whether to rate-limit updating the LRU to avoid possible thread contention.
/* Locks the data in this struct */
isc_rwlock_t lock;
/* Locks the tree structure (prevents nodes appearing/disappearing) */
- isc_rwlock_t tree_lock;
+ treelock_t tree_lock;
/* Locks for individual tree nodes */
unsigned int node_lock_count;
rbtdb_nodelock_t *node_locks;
isc_mem_put(rbtdb->common.mctx, rbtdb->node_locks,
rbtdb->node_lock_count * sizeof(rbtdb_nodelock_t));
- isc_rwlock_destroy(&rbtdb->tree_lock);
+ TREE_DESTROYLOCK(&rbtdb->tree_lock);
isc_refcount_destroy(&rbtdb->references);
if (rbtdb->task != NULL) {
isc_task_detach(&rbtdb->task);
* may be nodes in use.
*/
for (i = 0; i < rbtdb->node_lock_count; i++) {
- NODE_LOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_write);
+ isc_rwlocktype_t nodelock = isc_rwlocktype_none;
+ NODE_WRLOCK(&rbtdb->node_locks[i].lock, &nodelock);
rbtdb->node_locks[i].exiting = true;
if (isc_refcount_current(&rbtdb->node_locks[i].references) == 0)
{
inactive++;
}
- NODE_UNLOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_write);
+ NODE_UNLOCK(&rbtdb->node_locks[i].lock, &nodelock);
}
if (inactive != 0) {
static void
reactivate_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
isc_rwlocktype_t tlocktype) {
- isc_rwlocktype_t nlocktype = isc_rwlocktype_read;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
nodelock_t *nodelock = &rbtdb->node_locks[node->locknum].lock;
bool maybe_cleanup = false;
POST(nlocktype);
- NODE_LOCK(nodelock, nlocktype);
+ NODE_RDLOCK(nodelock, &nlocktype);
/*
* Check if we can possibly cleanup the dead node. If so, upgrade
/*
* Upgrade the lock and test if we still need to unlink.
*/
- NODE_UNLOCK(nodelock, nlocktype);
- nlocktype = isc_rwlocktype_write;
+ if (NODE_TRYUPGRADE(nodelock, &nlocktype) != ISC_R_SUCCESS) {
+ NODE_UNLOCK(nodelock, &nlocktype);
+ NODE_WRLOCK(nodelock, &nlocktype);
+ }
POST(nlocktype);
- NODE_LOCK(nodelock, nlocktype);
if (ISC_LINK_LINKED(node, deadlink)) {
ISC_LIST_UNLINK(rbtdb->deadnodes[node->locknum], node,
deadlink);
new_reference(rbtdb, node, nlocktype);
- NODE_UNLOCK(nodelock, nlocktype);
+ NODE_UNLOCK(nodelock, &nlocktype);
}
/*
*/
static bool
decrement_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
- rbtdb_serial_t least_serial, isc_rwlocktype_t *nlocktype,
- isc_rwlocktype_t *tlocktype, bool pruning) {
+ rbtdb_serial_t least_serial, isc_rwlocktype_t *nlocktypep,
+ isc_rwlocktype_t *tlocktypep, bool pruning) {
isc_result_t result;
- bool locked = *tlocktype != isc_rwlocktype_none;
+ bool locked = *tlocktypep != isc_rwlocktype_none;
bool write_locked = false;
rbtdb_nodelock_t *nodelock;
int bucket = node->locknum;
bool no_reference = true;
uint_fast32_t refs;
- REQUIRE(*nlocktype != isc_rwlocktype_none);
+ REQUIRE(*nlocktypep != isc_rwlocktype_none);
nodelock = &rbtdb->node_locks[bucket];
}
/* Upgrade the lock? */
- if (*nlocktype == isc_rwlocktype_read) {
- NODE_UNLOCK(&nodelock->lock, *nlocktype);
- *nlocktype = isc_rwlocktype_write;
- NODE_LOCK(&nodelock->lock, *nlocktype);
+ if (*nlocktypep == isc_rwlocktype_read) {
+ if (NODE_TRYUPGRADE(&nodelock->lock, nlocktypep) !=
+ ISC_R_SUCCESS) {
+ NODE_UNLOCK(&nodelock->lock, nlocktypep);
+ NODE_WRLOCK(&nodelock->lock, nlocktypep);
+ }
}
if (isc_refcount_decrement(&node->references) > 1) {
* the node lock before acquiring the tree write lock because
* we only do a trylock.
*/
- switch (*tlocktype) {
+ switch (*tlocktypep) {
case isc_rwlocktype_write:
result = ISC_R_SUCCESS;
break;
case isc_rwlocktype_read:
- result = isc_rwlock_tryupgrade(&rbtdb->tree_lock);
+ result = TREE_TRYUPGRADE(&rbtdb->tree_lock, tlocktypep);
break;
case isc_rwlocktype_none:
- result = isc_rwlock_trylock(&rbtdb->tree_lock,
- isc_rwlocktype_write);
+ result = TREE_TRYWRLOCK(&rbtdb->tree_lock, tlocktypep);
break;
default:
UNREACHABLE();
RUNTIME_CHECK(result == ISC_R_SUCCESS || result == ISC_R_LOCKBUSY);
if (result == ISC_R_SUCCESS) {
write_locked = true;
- *tlocktype = isc_rwlocktype_write;
}
refs = isc_refcount_decrement(&nodelock->references);
* Relock a read lock, or unlock the write lock if no lock was held.
*/
if (!locked && write_locked) {
- RWUNLOCK(&rbtdb->tree_lock, *tlocktype);
- *tlocktype = isc_rwlocktype_none;
+ TREE_UNLOCK(&rbtdb->tree_lock, tlocktypep);
}
return (no_reference);
dns_rbtnode_t *node = event->ev_arg;
dns_rbtnode_t *parent;
unsigned int locknum;
- isc_rwlocktype_t tlocktype = isc_rwlocktype_write;
- isc_rwlocktype_t nlocktype = isc_rwlocktype_write;
+ isc_rwlocktype_t tlocktype = isc_rwlocktype_none;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
UNUSED(task);
isc_event_free(&event);
- RWLOCK(&rbtdb->tree_lock, tlocktype);
+ TREE_WRLOCK(&rbtdb->tree_lock, &tlocktype);
locknum = node->locknum;
- NODE_LOCK(&rbtdb->node_locks[locknum].lock, nlocktype);
+ NODE_WRLOCK(&rbtdb->node_locks[locknum].lock, &nlocktype);
do {
parent = node->parent;
decrement_reference(rbtdb, node, 0, &nlocktype, &tlocktype,
*/
if (parent->locknum != locknum) {
NODE_UNLOCK(&rbtdb->node_locks[locknum].lock,
- nlocktype);
+ &nlocktype);
locknum = parent->locknum;
- NODE_LOCK(&rbtdb->node_locks[locknum].lock,
- nlocktype);
+ NODE_WRLOCK(&rbtdb->node_locks[locknum].lock,
+ &nlocktype);
}
/*
node = parent;
} while (node != NULL);
- NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, nlocktype);
+ NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, &nlocktype);
RWUNLOCK(&rbtdb->tree_lock, tlocktype);
detach((dns_db_t **)&rbtdb);
unsigned char *raw; /* RDATASLAB */
unsigned int count, length;
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
+ isc_rwlocktype_t tlocktype = isc_rwlocktype_none;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
- RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
+ TREE_RDLOCK(&rbtdb->tree_lock, &tlocktype);
version->havensec3 = false;
node = rbtdb->origin_node;
- NODE_LOCK(&(rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
+ NODE_RDLOCK(&(rbtdb->node_locks[node->locknum].lock), &nlocktype);
for (header = node->data; header != NULL; header = header_next) {
header_next = header->next;
do {
}
}
unlock:
- NODE_UNLOCK(&(rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
+ NODE_UNLOCK(&(rbtdb->node_locks[node->locknum].lock), &nlocktype);
+ TREE_UNLOCK(&rbtdb->tree_lock, &tlocktype);
}
static void
dns_rbtdb_t *rbtdb = event->ev_arg;
bool again = false;
unsigned int locknum;
+ isc_rwlocktype_t tlocktype = isc_rwlocktype_none;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
- RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
+ TREE_WRLOCK(&rbtdb->tree_lock, &tlocktype);
for (locknum = 0; locknum < rbtdb->node_lock_count; locknum++) {
- NODE_LOCK(&rbtdb->node_locks[locknum].lock,
- isc_rwlocktype_write);
+ NODE_WRLOCK(&rbtdb->node_locks[locknum].lock, &nlocktype);
cleanup_dead_nodes(rbtdb, locknum);
if (ISC_LIST_HEAD(rbtdb->deadnodes[locknum]) != NULL) {
again = true;
}
- NODE_UNLOCK(&rbtdb->node_locks[locknum].lock,
- isc_rwlocktype_write);
+ NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, &nlocktype);
}
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
+ TREE_UNLOCK(&rbtdb->tree_lock, &tlocktype);
if (again) {
isc_task_send(task, &event);
} else {
header = HEAD(resigned_list)) {
nodelock_t *lock;
isc_rwlocktype_t tlocktype = isc_rwlocktype_none;
- isc_rwlocktype_t nlocktype = isc_rwlocktype_write;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
ISC_LIST_UNLINK(resigned_list, header, link);
lock = &rbtdb->node_locks[header->node->locknum].lock;
- NODE_LOCK(lock, nlocktype);
+ NODE_WRLOCK(lock, &nlocktype);
if (rollback && !IGNORE(header)) {
resign_insert(rbtdb, header->node->locknum, header);
}
decrement_reference(rbtdb, header->node, least_serial,
&nlocktype, &tlocktype, false);
- NODE_UNLOCK(lock, nlocktype);
+ NODE_UNLOCK(lock, &nlocktype);
INSIST(tlocktype == isc_rwlocktype_none);
}
* expensive, but this event should be rare enough
* to justify the cost.
*/
- tlocktype = isc_rwlocktype_write;
- RWLOCK(&rbtdb->tree_lock, tlocktype);
+ TREE_WRLOCK(&rbtdb->tree_lock, &tlocktype);
}
for (changed = HEAD(cleanup_list); changed != NULL;
changed = next_changed) {
nodelock_t *lock;
- isc_rwlocktype_t nlocktype = isc_rwlocktype_write;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
next_changed = NEXT(changed, link);
rbtnode = changed->node;
lock = &rbtdb->node_locks[rbtnode->locknum].lock;
- NODE_LOCK(lock, nlocktype);
+ NODE_WRLOCK(lock, &nlocktype);
/*
* This is a good opportunity to purge any dead nodes,
* so use it.
decrement_reference(rbtdb, rbtnode, least_serial,
&nlocktype, &tlocktype, false);
- NODE_UNLOCK(lock, nlocktype);
+ NODE_UNLOCK(lock, &nlocktype);
isc_mem_put(rbtdb->common.mctx, changed,
sizeof(*changed));
isc_refcount_increment(&rbtdb->references);
isc_task_send(rbtdb->task, &event);
} else {
- RWUNLOCK(&rbtdb->tree_lock, tlocktype);
- tlocktype = isc_rwlocktype_none;
+ TREE_UNLOCK(&rbtdb->tree_lock, &tlocktype);
}
INSIST(tlocktype == isc_rwlocktype_none);
dns_rbtnode_t *node = NULL;
dns_name_t nodename;
isc_result_t result;
- isc_rwlocktype_t tlocktype = isc_rwlocktype_read;
+ isc_rwlocktype_t tlocktype = isc_rwlocktype_none;
INSIST(tree == rbtdb->tree || tree == rbtdb->nsec3);
dns_name_init(&nodename, NULL);
- RWLOCK(&rbtdb->tree_lock, tlocktype);
+ TREE_RDLOCK(&rbtdb->tree_lock, &tlocktype);
result = dns_rbt_findnode(tree, name, NULL, &node, NULL,
DNS_RBTFIND_EMPTYDATA, NULL, NULL);
if (result != ISC_R_SUCCESS) {
goto unlock;
}
/*
- * It would be nice to try to upgrade the lock instead of
- * unlocking then relocking.
+ * Try to upgrade the lock and if that fails unlock then relock.
*/
- RWUNLOCK(&rbtdb->tree_lock, tlocktype);
- tlocktype = isc_rwlocktype_write;
- RWLOCK(&rbtdb->tree_lock, tlocktype);
+ if (TREE_TRYUPGRADE(&rbtdb->tree_lock, &tlocktype) !=
+ ISC_R_SUCCESS) {
+ TREE_UNLOCK(&rbtdb->tree_lock, &tlocktype);
+ TREE_WRLOCK(&rbtdb->tree_lock, &tlocktype);
+ }
node = NULL;
result = dns_rbt_addnode(tree, name, &node);
if (result == ISC_R_SUCCESS) {
*nodep = (dns_dbnode_t *)node;
unlock:
- RWUNLOCK(&rbtdb->tree_lock, tlocktype);
+ TREE_UNLOCK(&rbtdb->tree_lock, &tlocktype);
return (result);
}
rdatasetheader_t *found;
isc_result_t result;
dns_rbtnode_t *onode;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
/*
* We only want to remember the topmost zone cut, since it's the one
result = DNS_R_CONTINUE;
onode = search->rbtdb->origin_node;
- NODE_LOCK(&(search->rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
+ NODE_RDLOCK(&(search->rbtdb->node_locks[node->locknum].lock),
+ &nlocktype);
/*
* Look for an NS or DNAME rdataset active in our version.
}
NODE_UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
+ &nlocktype);
return (result);
}
search->need_cleanup = false;
}
if (rdataset != NULL) {
- NODE_LOCK(&(search->rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
+ NODE_RDLOCK(&(search->rbtdb->node_locks[node->locknum].lock),
+ &nlocktype);
bind_rdataset(search->rbtdb, node, search->zonecut_rdataset,
search->now, isc_rwlocktype_read, rdataset);
if (sigrdataset != NULL && search->zonecut_sigrdataset != NULL)
isc_rwlocktype_read, sigrdataset);
}
NODE_UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
+ &nlocktype);
}
if (type == dns_rdatatype_dname) {
result = dns_rbtnodechain_next(chain, NULL, NULL);
while (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) {
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
node = NULL;
result = dns_rbtnodechain_current(chain, &prefix, origin,
&node);
if (result != ISC_R_SUCCESS) {
break;
}
- NODE_LOCK(&(rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
+ NODE_RDLOCK(&(rbtdb->node_locks[node->locknum].lock),
+ &nlocktype);
for (header = node->data; header != NULL; header = header->next)
{
if (header->serial <= search->serial &&
}
}
NODE_UNLOCK(&(rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
+ &nlocktype);
if (header != NULL) {
break;
}
chain = search->chain;
do {
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
node = NULL;
result = dns_rbtnodechain_current(&chain, &name, origin, &node);
if (result != ISC_R_SUCCESS) {
break;
}
- NODE_LOCK(&(rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
+ NODE_RDLOCK(&(rbtdb->node_locks[node->locknum].lock),
+ &nlocktype);
for (header = node->data; header != NULL; header = header->next)
{
if (header->serial <= search->serial &&
}
}
NODE_UNLOCK(&(rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
+ &nlocktype);
if (header != NULL) {
break;
}
result = dns_rbtnodechain_next(&chain, NULL, NULL);
while (result == ISC_R_SUCCESS || result == DNS_R_NEWORIGIN) {
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
node = NULL;
result = dns_rbtnodechain_current(&chain, &name, origin, &node);
if (result != ISC_R_SUCCESS) {
break;
}
- NODE_LOCK(&(rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
+ NODE_RDLOCK(&(rbtdb->node_locks[node->locknum].lock),
+ &nlocktype);
for (header = node->data; header != NULL; header = header->next)
{
if (header->serial <= search->serial &&
}
}
NODE_UNLOCK(&(rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
+ &nlocktype);
if (header != NULL) {
break;
}
done = false;
node = *nodep;
do {
- NODE_LOCK(&(rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
+ nodelock_t *lock = &rbtdb->node_locks[node->locknum].lock;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
+ NODE_RDLOCK(lock, &nlocktype);
/*
* First we try to figure out if this node is active in
wild = false;
}
- NODE_UNLOCK(&(rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
+ NODE_UNLOCK(lock, &nlocktype);
if (wild) {
/*
rbtdb->tree, wname, NULL, &wnode, &wchain,
DNS_RBTFIND_EMPTYDATA, NULL, NULL);
if (result == ISC_R_SUCCESS) {
- nodelock_t *lock;
-
/*
* We have found the wildcard node. If it
* is active in the search's version, we're
* done.
*/
lock = &rbtdb->node_locks[wnode->locknum].lock;
- NODE_LOCK(lock, isc_rwlocktype_read);
+ NODE_RDLOCK(lock, &nlocktype);
for (header = wnode->data; header != NULL;
header = header->next) {
if (header->serial <= search->serial &&
break;
}
}
- NODE_UNLOCK(lock, isc_rwlocktype_read);
+ NODE_UNLOCK(lock, &nlocktype);
if (header != NULL ||
activeempty(search, &wchain, wname)) {
if (activeemptynode(search, qname,
return (result);
}
do {
- NODE_LOCK(&(search->rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
+ NODE_RDLOCK(&(search->rbtdb->node_locks[node->locknum].lock),
+ &nlocktype);
found = NULL;
foundsig = NULL;
empty_node = true;
&nsecchain, &first);
}
NODE_UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
+ &nlocktype);
node = prevnode;
prevnode = NULL;
} while (empty_node && result == ISC_R_SUCCESS);
bool active;
nodelock_t *lock;
dns_rbt_t *tree;
- isc_rwlocktype_t nlocktype;
- isc_rwlocktype_t tlocktype;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
+ isc_rwlocktype_t tlocktype = isc_rwlocktype_none;
search.rbtdb = (dns_rbtdb_t *)db;
*/
wild = false;
- tlocktype = isc_rwlocktype_read;
- RWLOCK(&search.rbtdb->tree_lock, tlocktype);
+ TREE_RDLOCK(&search.rbtdb->tree_lock, &tlocktype);
/*
* Search down from the root of the tree. If, while going down, we
*/
lock = &search.rbtdb->node_locks[node->locknum].lock;
- nlocktype = isc_rwlocktype_read;
- NODE_LOCK(lock, nlocktype);
+ NODE_RDLOCK(lock, &nlocktype);
found = NULL;
foundsig = NULL;
*/
if (header->type == dns_rdatatype_nsec3 &&
!matchparams(header, &search)) {
- NODE_UNLOCK(lock, nlocktype);
+ NODE_UNLOCK(lock, &nlocktype);
goto partial_match;
}
/*
* we really have a partial match.
*/
if (!wild) {
- NODE_UNLOCK(lock, nlocktype);
+ NODE_UNLOCK(lock, &nlocktype);
goto partial_match;
}
}
*
* Return the delegation.
*/
- NODE_UNLOCK(lock, nlocktype);
+ NODE_UNLOCK(lock, &nlocktype);
result = setup_delegation(&search, nodep, foundname,
rdataset, sigrdataset);
goto tree_exit;
goto node_exit;
}
- NODE_UNLOCK(lock, nlocktype);
+ NODE_UNLOCK(lock, &nlocktype);
result = find_closest_nsec(&search, nodep, foundname,
rdataset, sigrdataset,
search.rbtdb->tree,
(search.options & DNS_DBFIND_VALIDATEGLUE) != 0 &&
!valid_glue(&search, foundname, type, node))
{
- NODE_UNLOCK(lock, nlocktype);
+ NODE_UNLOCK(lock, &nlocktype);
result = setup_delegation(&search, nodep, foundname,
rdataset, sigrdataset);
goto tree_exit;
}
node_exit:
- NODE_UNLOCK(lock, nlocktype);
+ NODE_UNLOCK(lock, &nlocktype);
tree_exit:
- RWUNLOCK(&search.rbtdb->tree_lock, tlocktype);
+ TREE_UNLOCK(&search.rbtdb->tree_lock, &tlocktype);
/*
* If we found a zonecut but aren't going to use it, we have to
* let go of it.
*/
if (search.need_cleanup) {
- nlocktype = isc_rwlocktype_read;
- tlocktype = isc_rwlocktype_none;
-
node = search.zonecut;
INSIST(node != NULL);
lock = &(search.rbtdb->node_locks[node->locknum].lock);
- NODE_LOCK(lock, nlocktype);
+ NODE_RDLOCK(lock, &nlocktype);
decrement_reference(search.rbtdb, node, 0, &nlocktype,
&tlocktype, false);
- NODE_UNLOCK(lock, nlocktype);
+ NODE_UNLOCK(lock, &nlocktype);
INSIST(tlocktype == isc_rwlocktype_none);
}
static bool
check_stale_header(dns_rbtnode_t *node, rdatasetheader_t *header,
- isc_rwlocktype_t *nlocktype, nodelock_t *lock,
+ isc_rwlocktype_t *nlocktypep, nodelock_t *lock,
rbtdb_search_t *search, rdatasetheader_t **header_prev) {
if (!ACTIVE(header, search->now)) {
dns_ttl_t stale = header->rdh_ttl +
* cleaned up later.
*/
if ((header->rdh_ttl < search->now - RBTDB_VIRTUAL) &&
- (*nlocktype == isc_rwlocktype_write ||
- NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS))
+ (*nlocktypep == isc_rwlocktype_write ||
+ NODE_TRYUPGRADE(lock, nlocktypep) == ISC_R_SUCCESS))
{
/*
* We update the node's status only when we can
* We won't downgrade the lock, since other
* rdatasets are probably stale, too.
*/
- *nlocktype = isc_rwlocktype_write;
if (isc_refcount_current(&node->references) == 0) {
isc_mem_t *mctx;
rdatasetheader_t *dname_header, *sigdname_header;
isc_result_t result;
nodelock_t *lock;
- isc_rwlocktype_t nlocktype;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
/* XXX comment */
UNUSED(name);
lock = &(search->rbtdb->node_locks[node->locknum].lock);
- nlocktype = isc_rwlocktype_read;
- NODE_LOCK(lock, nlocktype);
+ NODE_RDLOCK(lock, &nlocktype);
/*
* Look for a DNAME or RRSIG DNAME rdataset.
result = DNS_R_CONTINUE;
}
- NODE_UNLOCK(lock, nlocktype);
+ NODE_UNLOCK(lock, &nlocktype);
return (result);
}
dns_name_t name;
dns_rbtdb_t *rbtdb;
bool done;
- nodelock_t *lock;
- isc_rwlocktype_t nlocktype;
/*
* Caller must be holding the tree lock.
i = search->chain.level_matches;
done = false;
do {
- nlocktype = isc_rwlocktype_read;
- lock = &rbtdb->node_locks[node->locknum].lock;
- NODE_LOCK(lock, nlocktype);
+ nodelock_t *lock = &rbtdb->node_locks[node->locknum].lock;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
+
+ NODE_RDLOCK(lock, &nlocktype);
/*
* Look for NS and RRSIG NS rdatasets.
need_headerupdate(foundsig, search->now)))
{
if (nlocktype != isc_rwlocktype_write) {
- NODE_UNLOCK(lock, nlocktype);
- nlocktype = isc_rwlocktype_write;
- NODE_LOCK(lock, nlocktype);
+ if (NODE_TRYUPGRADE(lock, &nlocktype) !=
+ ISC_R_SUCCESS) {
+ NODE_UNLOCK(lock, &nlocktype);
+ NODE_WRLOCK(lock, &nlocktype);
+ }
POST(nlocktype);
}
if (need_headerupdate(found, search->now)) {
}
node_exit:
- NODE_UNLOCK(lock, nlocktype);
+ NODE_UNLOCK(lock, &nlocktype);
if (found == NULL && i > 0) {
i--;
dns_rbtnode_t *node = NULL;
dns_rbtnodechain_t chain;
isc_result_t result;
- isc_rwlocktype_t nlocktype;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
nodelock_t *lock = NULL;
rbtdb_rdatatype_t matchtype, sigmatchtype;
rdatasetheader_t *found = NULL, *foundsig = NULL;
target = dns_fixedname_initname(&ftarget);
fname = dns_fixedname_initname(&fixed);
- nlocktype = isc_rwlocktype_read;
matchtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_nsec, 0);
sigmatchtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig,
dns_rdatatype_nsec);
}
lock = &(search->rbtdb->node_locks[node->locknum].lock);
- NODE_LOCK(lock, nlocktype);
+ NODE_RDLOCK(lock, &nlocktype);
for (header = node->data; header != NULL; header = header_next) {
header_next = header->next;
if (check_stale_header(node, header, &nlocktype, lock, search,
} else {
result = ISC_R_NOTFOUND;
}
- NODE_UNLOCK(lock, nlocktype);
+ NODE_UNLOCK(lock, &nlocktype);
return (result);
}
bool all_negative = true;
bool empty_node;
nodelock_t *lock;
- isc_rwlocktype_t tlocktype;
- isc_rwlocktype_t nlocktype = isc_rwlocktype_read;
+ isc_rwlocktype_t tlocktype = isc_rwlocktype_none;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
rdatasetheader_t *header, *header_prev, *header_next;
rdatasetheader_t *found, *nsheader;
rdatasetheader_t *foundsig, *nssig, *cnamesig;
update = NULL;
updatesig = NULL;
- tlocktype = isc_rwlocktype_read;
- RWLOCK(&search.rbtdb->tree_lock, tlocktype);
+ TREE_RDLOCK(&search.rbtdb->tree_lock, &tlocktype);
/*
* Search down from the root of the tree. If, while going down, we
*/
lock = &(search.rbtdb->node_locks[node->locknum].lock);
- NODE_LOCK(lock, nlocktype);
+ NODE_RDLOCK(lock, &nlocktype);
found = NULL;
foundsig = NULL;
* extant rdatasets. That means that this node doesn't
* meaningfully exist, and that we really have a partial match.
*/
- NODE_UNLOCK(lock, nlocktype);
+ NODE_UNLOCK(lock, &nlocktype);
if ((search.options & DNS_DBFIND_COVERINGNSEC) != 0) {
result = find_coveringnsec(&search, name, nodep, now,
foundname, rdataset,
if (found == NULL && (found_noqname || all_negative) &&
(search.options & DNS_DBFIND_COVERINGNSEC) != 0)
{
- NODE_UNLOCK(lock, nlocktype);
+ NODE_UNLOCK(lock, &nlocktype);
result = find_coveringnsec(&search, name, nodep, now,
foundname, rdataset,
sigrdataset);
/*
* Go find the deepest zone cut.
*/
- NODE_UNLOCK(lock, nlocktype);
+ NODE_UNLOCK(lock, &nlocktype);
goto find_ns;
}
node_exit:
if ((update != NULL || updatesig != NULL) &&
nlocktype != isc_rwlocktype_write) {
- NODE_UNLOCK(lock, nlocktype);
- nlocktype = isc_rwlocktype_write;
- NODE_LOCK(lock, nlocktype);
+ if (NODE_TRYUPGRADE(lock, &nlocktype) != ISC_R_SUCCESS) {
+ NODE_UNLOCK(lock, &nlocktype);
+ NODE_WRLOCK(lock, &nlocktype);
+ }
POST(nlocktype);
}
if (update != NULL && need_headerupdate(update, search.now)) {
update_header(search.rbtdb, updatesig, search.now);
}
- NODE_UNLOCK(lock, nlocktype);
+ NODE_UNLOCK(lock, &nlocktype);
tree_exit:
- RWUNLOCK(&search.rbtdb->tree_lock, tlocktype);
+ TREE_UNLOCK(&search.rbtdb->tree_lock, &tlocktype);
/*
* If we found a zonecut but aren't going to use it, we have to
* let go of it.
*/
if (search.need_cleanup) {
- nlocktype = isc_rwlocktype_read;
- tlocktype = isc_rwlocktype_none;
-
node = search.zonecut;
INSIST(node != NULL);
lock = &(search.rbtdb->node_locks[node->locknum].lock);
- NODE_LOCK(lock, nlocktype);
+ NODE_RDLOCK(lock, &nlocktype);
decrement_reference(search.rbtdb, node, 0, &nlocktype,
&tlocktype, false);
- NODE_UNLOCK(lock, nlocktype);
+ NODE_UNLOCK(lock, &nlocktype);
INSIST(tlocktype == isc_rwlocktype_none);
}
rdatasetheader_t *header, *header_prev, *header_next;
rdatasetheader_t *found, *foundsig;
unsigned int rbtoptions = DNS_RBTFIND_EMPTYDATA;
- isc_rwlocktype_t tlocktype = isc_rwlocktype_read;
- isc_rwlocktype_t nlocktype = isc_rwlocktype_read;
+ isc_rwlocktype_t tlocktype = isc_rwlocktype_none;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
bool dcnull = (dcname == NULL);
search.rbtdb = (dns_rbtdb_t *)db;
rbtoptions |= DNS_RBTFIND_NOEXACT;
}
- tlocktype = isc_rwlocktype_read;
- RWLOCK(&search.rbtdb->tree_lock, tlocktype);
+ TREE_RDLOCK(&search.rbtdb->tree_lock, &tlocktype);
/*
* Search down from the root of the tree.
*/
lock = &(search.rbtdb->node_locks[node->locknum].lock);
- NODE_LOCK(lock, nlocktype);
+ NODE_RDLOCK(lock, &nlocktype);
found = NULL;
foundsig = NULL;
* zonecut we know about. If so, find the deepest
* zonecut from this node up and return that instead.
*/
- NODE_UNLOCK(lock, nlocktype);
+ NODE_UNLOCK(lock, &nlocktype);
result = find_deepest_zonecut(&search, node, nodep,
foundname, rdataset,
sigrdataset);
/*
* No NS records here.
*/
- NODE_UNLOCK(lock, nlocktype);
+ NODE_UNLOCK(lock, &nlocktype);
result = find_deepest_zonecut(&search, node, nodep, foundname,
rdataset, sigrdataset);
goto tree_exit;
(foundsig != NULL && need_headerupdate(foundsig, search.now)))
{
if (nlocktype != isc_rwlocktype_write) {
- NODE_UNLOCK(lock, nlocktype);
- nlocktype = isc_rwlocktype_write;
- NODE_LOCK(lock, nlocktype);
+ if (NODE_TRYUPGRADE(lock, &nlocktype) != ISC_R_SUCCESS)
+ {
+ NODE_UNLOCK(lock, &nlocktype);
+ NODE_WRLOCK(lock, &nlocktype);
+ }
POST(nlocktype);
}
if (need_headerupdate(found, search.now)) {
}
}
- NODE_UNLOCK(lock, nlocktype);
+ NODE_UNLOCK(lock, &nlocktype);
tree_exit:
- RWUNLOCK(&search.rbtdb->tree_lock, tlocktype);
+ TREE_UNLOCK(&search.rbtdb->tree_lock, &tlocktype);
INSIST(!search.need_cleanup);
bool want_free = false;
bool inactive = false;
rbtdb_nodelock_t *nodelock;
- isc_rwlocktype_t nlocktype = isc_rwlocktype_read;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
isc_rwlocktype_t tlocktype = isc_rwlocktype_none;
REQUIRE(VALID_RBTDB(rbtdb));
node = (dns_rbtnode_t *)(*targetp);
nodelock = &rbtdb->node_locks[node->locknum];
- NODE_LOCK(&nodelock->lock, nlocktype);
+ NODE_RDLOCK(&nodelock->lock, &nlocktype);
if (decrement_reference(rbtdb, node, 0, &nlocktype, &tlocktype, false))
{
}
}
- NODE_UNLOCK(&nodelock->lock, nlocktype);
+ NODE_UNLOCK(&nodelock->lock, &nlocktype);
INSIST(tlocktype == isc_rwlocktype_none);
*targetp = NULL;
isc_logmodule_t *module = DNS_LOGMODULE_CACHE;
int level = ISC_LOG_DEBUG(2);
char printname[DNS_NAME_FORMATSIZE];
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
REQUIRE(VALID_RBTDB(rbtdb));
* We may not need write access, but this code path is not performance
* sensitive, so it should be okay to always lock as a writer.
*/
- NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_write);
+ NODE_WRLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
for (header = rbtnode->data; header != NULL; header = header->next) {
if (header->rdh_ttl + STALE_TTL(header, rbtdb) <=
}
}
- NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_write);
+ NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
return (ISC_R_SUCCESS);
}
dns_rbtnode_t *rbtnode = node;
bool first;
uint32_t refs;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
REQUIRE(VALID_RBTDB(rbtdb));
- NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_read);
+ NODE_RDLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
refs = isc_refcount_current(&rbtnode->references);
fprintf(out, "node %p, %" PRIu32 " references, locknum = %u\n", rbtnode,
fprintf(out, "(empty)\n");
}
- NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_read);
+ NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
}
static isc_result_t
rbtdb_version_t *rbtversion = version;
bool close_version = false;
rbtdb_rdatatype_t matchtype, sigmatchtype;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
REQUIRE(VALID_RBTDB(rbtdb));
REQUIRE(type != dns_rdatatype_any);
serial = rbtversion->serial;
now = 0;
- NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_read);
+ NODE_RDLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
found = NULL;
foundsig = NULL;
}
}
- NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_read);
+ NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
if (close_version) {
closeversion(db, (dns_dbversion_t **)(void *)(&rbtversion),
rbtdb_rdatatype_t matchtype, sigmatchtype, negtype;
isc_result_t result;
nodelock_t *lock;
- isc_rwlocktype_t locktype;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
REQUIRE(VALID_RBTDB(rbtdb));
REQUIRE(type != dns_rdatatype_any);
}
lock = &rbtdb->node_locks[rbtnode->locknum].lock;
- locktype = isc_rwlocktype_read;
- NODE_LOCK(lock, locktype);
+ NODE_RDLOCK(lock, &nlocktype);
found = NULL;
foundsig = NULL;
if (!ACTIVE(header, now)) {
if ((header->rdh_ttl + STALE_TTL(header, rbtdb) <
now - RBTDB_VIRTUAL) &&
- (locktype == isc_rwlocktype_write ||
- NODE_TRYUPGRADE(lock) == ISC_R_SUCCESS))
+ (nlocktype == isc_rwlocktype_write ||
+ NODE_TRYUPGRADE(lock, &nlocktype) ==
+ ISC_R_SUCCESS))
{
/*
* We update the node's status only when we
* can get write access.
*/
- locktype = isc_rwlocktype_write;
/*
* We don't check if refcurrent(rbtnode) == 0
}
}
if (found != NULL) {
- bind_rdataset(rbtdb, rbtnode, found, now, locktype, rdataset);
+ bind_rdataset(rbtdb, rbtnode, found, now, nlocktype, rdataset);
if (!NEGATIVE(found) && foundsig != NULL) {
- bind_rdataset(rbtdb, rbtnode, foundsig, now, locktype,
+ bind_rdataset(rbtdb, rbtnode, foundsig, now, nlocktype,
sigrdataset);
}
}
- NODE_UNLOCK(lock, locktype);
+ NODE_UNLOCK(lock, &nlocktype);
if (found == NULL) {
return (ISC_R_NOTFOUND);
isc_result_t result;
bool delegating;
bool newnsec;
- isc_rwlocktype_t tlocktype = isc_rwlocktype_read;
- isc_rwlocktype_t nlocktype = isc_rwlocktype_write;
+ isc_rwlocktype_t tlocktype = isc_rwlocktype_none;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
bool cache_is_overmem = false;
dns_fixedname_t fixed;
dns_name_t *name;
node != rbtdb->origin_node) {
return (DNS_R_NOTZONETOP);
}
- RWLOCK(&rbtdb->tree_lock, tlocktype);
+ TREE_RDLOCK(&rbtdb->tree_lock, &tlocktype);
REQUIRE(((rbtnode->nsec == DNS_RBT_NSEC_NSEC3 &&
(rdataset->type == dns_rdatatype_nsec3 ||
rdataset->covers == dns_rdatatype_nsec3)) ||
(rbtnode->nsec != DNS_RBT_NSEC_NSEC3 &&
rdataset->type != dns_rdatatype_nsec3 &&
rdataset->covers != dns_rdatatype_nsec3)));
- RWUNLOCK(&rbtdb->tree_lock, tlocktype);
+ TREE_UNLOCK(&rbtdb->tree_lock, &tlocktype);
}
if (rbtversion == NULL) {
/*
* Add to the auxiliary NSEC tree if we're adding an NSEC record.
*/
- tlocktype = isc_rwlocktype_read;
- RWLOCK(&rbtdb->tree_lock, tlocktype);
+ TREE_RDLOCK(&rbtdb->tree_lock, &tlocktype);
if (rbtnode->nsec != DNS_RBT_NSEC_HAS_NSEC &&
rdataset->type == dns_rdatatype_nsec)
{
} else {
newnsec = false;
}
- RWUNLOCK(&rbtdb->tree_lock, tlocktype);
+ TREE_UNLOCK(&rbtdb->tree_lock, &tlocktype);
/*
* If we're adding a delegation type, adding to the auxiliary NSEC
cache_is_overmem = true;
}
if (delegating || newnsec || cache_is_overmem) {
- tlocktype = isc_rwlocktype_write;
- RWLOCK(&rbtdb->tree_lock, tlocktype);
- } else {
- tlocktype = isc_rwlocktype_none;
+ TREE_WRLOCK(&rbtdb->tree_lock, &tlocktype);
}
if (cache_is_overmem) {
overmem_purge(rbtdb, rbtnode->locknum, now, &tlocktype);
}
- NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, nlocktype);
+ NODE_WRLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
if (rbtdb->rrsetstats != NULL) {
RDATASET_ATTR_SET(newheader, RDATASET_ATTR_STATCOUNT);
*/
if (tlocktype == isc_rwlocktype_write && !delegating &&
!newnsec) {
- RWUNLOCK(&rbtdb->tree_lock, tlocktype);
- tlocktype = isc_rwlocktype_none;
+ TREE_UNLOCK(&rbtdb->tree_lock, &tlocktype);
}
}
rbtnode->find_callback = 1;
}
- NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, nlocktype);
+ NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
if (tlocktype != isc_rwlocktype_none) {
- RWUNLOCK(&rbtdb->tree_lock, tlocktype);
+ TREE_UNLOCK(&rbtdb->tree_lock, &tlocktype);
}
+ INSIST(tlocktype == isc_rwlocktype_none);
/*
* Update the zone's secure status. If version is non-NULL
isc_region_t region;
isc_result_t result;
rbtdb_changed_t *changed;
+ isc_rwlocktype_t tlocktype = isc_rwlocktype_none;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
REQUIRE(VALID_RBTDB(rbtdb));
REQUIRE(rbtversion != NULL && rbtversion->rbtdb == rbtdb);
if (rbtdb->common.methods == &zone_methods) {
- RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
+ TREE_RDLOCK(&rbtdb->tree_lock, &tlocktype);
REQUIRE(((rbtnode->nsec == DNS_RBT_NSEC_NSEC3 &&
(rdataset->type == dns_rdatatype_nsec3 ||
rdataset->covers == dns_rdatatype_nsec3)) ||
(rbtnode->nsec != DNS_RBT_NSEC_NSEC3 &&
rdataset->type != dns_rdatatype_nsec3 &&
rdataset->covers != dns_rdatatype_nsec3)));
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
+ TREE_UNLOCK(&rbtdb->tree_lock, &tlocktype);
}
nodefullname(db, node, nodename);
newheader->resign_lsb = 0;
}
- NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_write);
+ NODE_WRLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
changed = add_changed(rbtdb, rbtversion, rbtnode);
if (changed == NULL) {
free_rdataset(rbtdb, rbtdb->common.mctx, newheader);
NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_write);
+ &nlocktype);
return (ISC_R_NOMEMORY);
}
}
unlock:
- NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_write);
+ NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
/*
* Update the zone's secure status. If version is non-NULL
dns_name_t *nodename = dns_fixedname_initname(&fname);
isc_result_t result;
rdatasetheader_t *newheader;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
REQUIRE(VALID_RBTDB(rbtdb));
INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb);
nodefullname(db, node, nodename);
- NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_write);
+ NODE_WRLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
result = add32(rbtdb, rbtnode, nodename, rbtversion, newheader,
DNS_DBADD_FORCE, false, NULL, 0);
- NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_write);
+ NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
/*
* Update the zone's secure status. If version is non-NULL
isc_result_t result;
isc_region_t region;
rdatasetheader_t *newheader;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
REQUIRE(rdataset->rdclass == rbtdb->common.rdclass);
newheader->resign_lsb = 0;
}
- NODE_LOCK(&rbtdb->node_locks[node->locknum].lock, isc_rwlocktype_write);
+ NODE_WRLOCK(&rbtdb->node_locks[node->locknum].lock, &nlocktype);
result = add32(rbtdb, node, name, rbtdb->current_version, newheader,
DNS_DBADD_MERGE, true, NULL, 0);
- NODE_UNLOCK(&rbtdb->node_locks[node->locknum].lock,
- isc_rwlocktype_write);
+ NODE_UNLOCK(&rbtdb->node_locks[node->locknum].lock, &nlocktype);
if (result == ISC_R_SUCCESS &&
delegating_type(rbtdb, node, rdataset->type)) {
dns_rbtdb_t *rbtdb = arg;
rdatasetheader_t *current, *next;
unsigned int locknum;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
current = data;
locknum = current->node->locknum;
- NODE_LOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write);
+ NODE_WRLOCK(&rbtdb->node_locks[locknum].lock, &nlocktype);
while (current != NULL) {
next = current->next;
free_rdataset(rbtdb, rbtdb->common.mctx, current);
current = next;
}
- NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write);
+ NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, &nlocktype);
}
static bool
nodecount(dns_db_t *db, dns_dbtree_t tree) {
dns_rbtdb_t *rbtdb;
unsigned int count;
+ isc_rwlocktype_t tlocktype = isc_rwlocktype_none;
rbtdb = (dns_rbtdb_t *)db;
REQUIRE(VALID_RBTDB(rbtdb));
- RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
+ TREE_RDLOCK(&rbtdb->tree_lock, &tlocktype);
switch (tree) {
case dns_dbtree_main:
count = dns_rbt_nodecount(rbtdb->tree);
default:
UNREACHABLE();
}
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
+ TREE_UNLOCK(&rbtdb->tree_lock, &tlocktype);
return (count);
}
hashsize(dns_db_t *db) {
dns_rbtdb_t *rbtdb;
size_t size;
+ isc_rwlocktype_t tlocktype = isc_rwlocktype_none;
rbtdb = (dns_rbtdb_t *)db;
REQUIRE(VALID_RBTDB(rbtdb));
- RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
+ TREE_RDLOCK(&rbtdb->tree_lock, &tlocktype);
size = dns_rbt_hashsize(rbtdb->tree);
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
+ TREE_UNLOCK(&rbtdb->tree_lock, &tlocktype);
return (size);
}
setsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, isc_stdtime_t resign) {
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
rdatasetheader_t *header, oldheader;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
REQUIRE(VALID_RBTDB(rbtdb));
REQUIRE(!IS_CACHE(rbtdb));
header = rdataset->private3;
header--;
- NODE_LOCK(&rbtdb->node_locks[header->node->locknum].lock,
- isc_rwlocktype_write);
+ NODE_WRLOCK(&rbtdb->node_locks[header->node->locknum].lock, &nlocktype);
oldheader = *header;
/*
RDATASET_ATTR_SET(header, RDATASET_ATTR_RESIGN);
resign_insert(rbtdb, header->node->locknum, header);
}
- NODE_UNLOCK(&rbtdb->node_locks[header->node->locknum].lock,
- isc_rwlocktype_write);
+ NODE_UNLOCK(&rbtdb->node_locks[header->node->locknum].lock, &nlocktype);
return (ISC_R_SUCCESS);
}
unsigned int i;
isc_result_t result = ISC_R_NOTFOUND;
unsigned int locknum = 0;
+ isc_rwlocktype_t tlocktype = isc_rwlocktype_none;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
REQUIRE(VALID_RBTDB(rbtdb));
- RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
+ TREE_RDLOCK(&rbtdb->tree_lock, &tlocktype);
for (i = 0; i < rbtdb->node_lock_count; i++) {
- NODE_LOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_read);
+ NODE_RDLOCK(&rbtdb->node_locks[i].lock, &nlocktype);
/*
* Find for the earliest signing time among all of the
this = isc_heap_element(rbtdb->heaps[i], 1);
if (this == NULL) {
/* Nothing found; unlock and try the next heap. */
- NODE_UNLOCK(&rbtdb->node_locks[i].lock,
- isc_rwlocktype_read);
+ NODE_UNLOCK(&rbtdb->node_locks[i].lock, &nlocktype);
continue;
}
*/
header = this;
locknum = i;
+ nlocktype = isc_rwlocktype_none;
} else if (resign_sooner(this, header)) {
/*
* Found an earlier signing time; release the
* previous bucket lock and retain this one instead.
*/
NODE_UNLOCK(&rbtdb->node_locks[locknum].lock,
- isc_rwlocktype_read);
+ &nlocktype);
header = this;
locknum = i;
} else {
* Earliest signing time in this heap isn't
* an improvement; unlock and try the next heap.
*/
- NODE_UNLOCK(&rbtdb->node_locks[i].lock,
- isc_rwlocktype_read);
+ NODE_UNLOCK(&rbtdb->node_locks[i].lock, &nlocktype);
}
}
if (header != NULL) {
+ nlocktype = isc_rwlocktype_read;
/*
* Found something; pass back the answer and unlock
* the bucket.
dns_rbt_fullnamefromnode(header->node, foundname);
}
- NODE_UNLOCK(&rbtdb->node_locks[locknum].lock,
- isc_rwlocktype_read);
+ NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, &nlocktype);
result = ISC_R_SUCCESS;
}
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
+ TREE_UNLOCK(&rbtdb->tree_lock, &tlocktype);
return (result);
}
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
dns_rbtnode_t *node;
rdatasetheader_t *header;
+ isc_rwlocktype_t tlocktype = isc_rwlocktype_none;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
REQUIRE(VALID_RBTDB(rbtdb));
REQUIRE(rdataset != NULL);
return;
}
- RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
- NODE_LOCK(&rbtdb->node_locks[node->locknum].lock, isc_rwlocktype_write);
+ TREE_WRLOCK(&rbtdb->tree_lock, &tlocktype);
+ NODE_WRLOCK(&rbtdb->node_locks[node->locknum].lock, &nlocktype);
/*
* Delete from heap and save to re-signed list so that it can
* be restored if we backout of this change.
*/
resign_delete(rbtdb, rbtversion, header);
- NODE_UNLOCK(&rbtdb->node_locks[node->locknum].lock,
- isc_rwlocktype_write);
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
+ NODE_UNLOCK(&rbtdb->node_locks[node->locknum].lock, &nlocktype);
+ TREE_UNLOCK(&rbtdb->tree_lock, &tlocktype);
}
static isc_result_t
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node;
isc_result_t result;
+ isc_rwlocktype_t tlocktype = isc_rwlocktype_none;
REQUIRE(VALID_RBTDB(rbtdb));
REQUIRE(node != NULL);
REQUIRE(name != NULL);
- RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
+ TREE_RDLOCK(&rbtdb->tree_lock, &tlocktype);
result = dns_rbt_fullnamefromnode(rbtnode, name);
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
+ TREE_UNLOCK(&rbtdb->tree_lock, &tlocktype);
return (result);
}
RBTDB_INITLOCK(&rbtdb->lock);
- isc_rwlock_init(&rbtdb->tree_lock, 0, 0);
+ TREE_INITLOCK(&rbtdb->tree_lock);
/*
* Initialize node_lock_count in a generic way to support future
rbtdb->node_lock_count * sizeof(rbtdb_nodelock_t));
cleanup_tree_lock:
- isc_rwlock_destroy(&rbtdb->tree_lock);
+ TREE_DESTROYLOCK(&rbtdb->tree_lock);
RBTDB_DESTROYLOCK(&rbtdb->lock);
isc_mem_put(mctx, rbtdb, sizeof(*rbtdb));
return (result);
dns_rbtdb_t *rbtdb = rdataset->private1;
dns_rbtnode_t *rbtnode = rdataset->private2;
rdatasetheader_t *header = rdataset->private3;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
header--;
- NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_write);
+ NODE_WRLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
header->trust = rdataset->trust = trust;
- NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_write);
+ NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
}
static void
dns_rbtdb_t *rbtdb = rdataset->private1;
dns_rbtnode_t *rbtnode = rdataset->private2;
rdatasetheader_t *header = rdataset->private3;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
header--;
- NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_write);
+ NODE_WRLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
expire_header(rbtdb, header, false, expire_flush);
- NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_write);
+ NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
}
static void
dns_rbtdb_t *rbtdb = rdataset->private1;
dns_rbtnode_t *rbtnode = rdataset->private2;
rdatasetheader_t *header = rdataset->private3;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
header--;
- NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_write);
+ NODE_WRLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
RDATASET_ATTR_CLR(header, RDATASET_ATTR_PREFETCH);
- NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_write);
+ NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
}
/*
rbtdb_version_t *rbtversion = rbtiterator->common.version;
rdatasetheader_t *header, *top_next;
rbtdb_serial_t serial = 1;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
if (!IS_CACHE(rbtdb)) {
serial = rbtversion->serial;
}
- NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_read);
+ NODE_RDLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
for (header = rbtnode->data; header != NULL; header = top_next) {
top_next = header->next;
}
}
- NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_read);
+ NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
rbtiterator->current = header;
rbtdb_rdatatype_t type, negtype;
dns_rdatatype_t rdtype, covers;
rbtdb_serial_t serial = 1;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
header = rbtiterator->current;
if (header == NULL) {
serial = rbtversion->serial;
}
- NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_read);
+ NODE_RDLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
type = header->type;
rdtype = RBTDB_RDATATYPE_BASE(header->type);
}
}
- NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_read);
+ NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
rbtiterator->current = header;
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)(rbtiterator->common.db);
dns_rbtnode_t *rbtnode = rbtiterator->common.node;
rdatasetheader_t *header;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
header = rbtiterator->current;
REQUIRE(header != NULL);
- NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_read);
+ NODE_RDLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
bind_rdataset(rbtdb, rbtnode, header, rbtiterator->common.now,
isc_rwlocktype_read, rdataset);
- NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_read);
+ NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
}
/*
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)rbtdbiter->common.db;
dns_rbtnode_t *node = rbtdbiter->node;
nodelock_t *lock;
- isc_rwlocktype_t nlocktype = isc_rwlocktype_read;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
isc_rwlocktype_t tlocktype = rbtdbiter->tree_locked;
if (node == NULL) {
REQUIRE(tlocktype != isc_rwlocktype_write);
lock = &rbtdb->node_locks[node->locknum].lock;
- NODE_LOCK(lock, nlocktype);
+ NODE_RDLOCK(lock, &nlocktype);
decrement_reference(rbtdb, node, 0, &nlocktype, &rbtdbiter->tree_locked,
false);
- NODE_UNLOCK(lock, nlocktype);
+ NODE_UNLOCK(lock, &nlocktype);
if (tlocktype != rbtdbiter->tree_locked) {
- RWUNLOCK(&rbtdb->tree_lock, rbtdbiter->tree_locked);
- rbtdbiter->tree_locked = isc_rwlocktype_none;
+ TREE_UNLOCK(&rbtdb->tree_lock, &rbtdbiter->tree_locked);
if (tlocktype == isc_rwlocktype_read) {
- RWLOCK(&rbtdb->tree_lock, tlocktype);
- rbtdbiter->tree_locked = tlocktype;
+ TREE_RDLOCK(&rbtdb->tree_lock, &rbtdbiter->tree_locked);
}
}
INSIST(rbtdbiter->tree_locked == tlocktype);
rbtdbiter->delcnt, dns_rbt_nodecount(rbtdb->tree));
if (rbtdbiter->tree_locked == isc_rwlocktype_read) {
- RWUNLOCK(&rbtdb->tree_lock, tlocktype);
- rbtdbiter->tree_locked = isc_rwlocktype_none;
+ TREE_UNLOCK(&rbtdb->tree_lock, &rbtdbiter->tree_locked);
}
INSIST(rbtdbiter->tree_locked == isc_rwlocktype_none);
- rbtdbiter->tree_locked = isc_rwlocktype_write;
- RWLOCK(&rbtdb->tree_lock, rbtdbiter->tree_locked);
+ TREE_WRLOCK(&rbtdb->tree_lock, &rbtdbiter->tree_locked);
for (size_t i = 0; i < (size_t)rbtdbiter->delcnt; i++) {
- isc_rwlocktype_t nlocktype = isc_rwlocktype_read;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
dns_rbtnode_t *node = rbtdbiter->deletions[i];
nodelock_t *lock = &rbtdb->node_locks[node->locknum].lock;
- NODE_LOCK(lock, nlocktype);
+ NODE_RDLOCK(lock, &nlocktype);
decrement_reference(rbtdb, node, 0, &nlocktype,
&rbtdbiter->tree_locked, false);
- NODE_UNLOCK(lock, nlocktype);
+ NODE_UNLOCK(lock, &nlocktype);
}
rbtdbiter->delcnt = 0;
- RWUNLOCK(&rbtdb->tree_lock, rbtdbiter->tree_locked);
- rbtdbiter->tree_locked = isc_rwlocktype_none;
+ TREE_UNLOCK(&rbtdb->tree_lock, &rbtdbiter->tree_locked);
if (tlocktype == isc_rwlocktype_read) {
- RWLOCK(&rbtdb->tree_lock, tlocktype);
- rbtdbiter->tree_locked = tlocktype;
+ TREE_RDLOCK(&rbtdb->tree_lock, &rbtdbiter->tree_locked);
}
INSIST(rbtdbiter->tree_locked == tlocktype);
}
REQUIRE(rbtdbiter->paused);
REQUIRE(rbtdbiter->tree_locked == isc_rwlocktype_none);
- RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
- rbtdbiter->tree_locked = isc_rwlocktype_read;
+ TREE_RDLOCK(&rbtdb->tree_lock, &rbtdbiter->tree_locked);
rbtdbiter->paused = false;
}
dns_db_t *db = NULL;
if (rbtdbiter->tree_locked == isc_rwlocktype_read) {
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
- rbtdbiter->tree_locked = isc_rwlocktype_none;
+ TREE_UNLOCK(&rbtdb->tree_lock, &rbtdbiter->tree_locked);
}
INSIST(rbtdbiter->tree_locked == isc_rwlocktype_none);
rbtdbiter->paused = true;
if (rbtdbiter->tree_locked == isc_rwlocktype_read) {
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
- rbtdbiter->tree_locked = isc_rwlocktype_none;
+ TREE_UNLOCK(&rbtdb->tree_lock, &rbtdbiter->tree_locked);
}
INSIST(rbtdbiter->tree_locked == isc_rwlocktype_none);
dns_rbtnode_t *rbtnode = rdataset->private2;
unsigned char *raw = rdataset->private3; /* RDATASLAB */
rdatasetheader_t *header;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
header = (struct rdatasetheader *)(raw - sizeof(*header));
- NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_write);
+ NODE_WRLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
setownercase(header, name);
- NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_write);
+ NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
}
static void
rdatasetheader_t *header = NULL;
uint8_t mask = (1 << 7);
uint8_t bits = 0;
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
header = (struct rdatasetheader *)(raw - sizeof(*header));
- NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_read);
+ NODE_RDLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
if (!CASESET(header)) {
goto unlock;
}
unlock:
- NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
- isc_rwlocktype_read);
+ NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype);
}
struct rbtdb_glue {
locknum != locknum_start && purgecount > 0;
locknum = (locknum + 1) % rbtdb->node_lock_count)
{
- NODE_LOCK(&rbtdb->node_locks[locknum].lock,
- isc_rwlocktype_write);
+ isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
+ NODE_WRLOCK(&rbtdb->node_locks[locknum].lock, &nlocktype);
header = isc_heap_element(rbtdb->heaps[locknum], 1);
if (header && header->rdh_ttl < now - RBTDB_VIRTUAL) {
purgecount--;
}
- NODE_UNLOCK(&rbtdb->node_locks[locknum].lock,
- isc_rwlocktype_write);
+ NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, &nlocktype);
}
}