mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-04 08:35:31 +00:00
Use C-RW-WP lock in the dns_adb unit
Replace the isc_mutex in the dns_adb unit with isc_rwlock for better performance. Both ADB names and ADB entries hashtables and LRU are now using isc_rwlock.
This commit is contained in:
202
lib/dns/adb.c
202
lib/dns/adb.c
@@ -33,6 +33,7 @@
|
|||||||
#include <isc/print.h>
|
#include <isc/print.h>
|
||||||
#include <isc/random.h>
|
#include <isc/random.h>
|
||||||
#include <isc/result.h>
|
#include <isc/result.h>
|
||||||
|
#include <isc/rwlock.h>
|
||||||
#include <isc/stats.h>
|
#include <isc/stats.h>
|
||||||
#include <isc/string.h>
|
#include <isc/string.h>
|
||||||
#include <isc/task.h>
|
#include <isc/task.h>
|
||||||
@@ -118,12 +119,12 @@ struct dns_adb {
|
|||||||
dns_adbnamelist_t names_lru;
|
dns_adbnamelist_t names_lru;
|
||||||
isc_stdtime_t names_last_update;
|
isc_stdtime_t names_last_update;
|
||||||
isc_hashmap_t *names;
|
isc_hashmap_t *names;
|
||||||
isc_mutex_t names_lock;
|
isc_rwlock_t names_lock;
|
||||||
|
|
||||||
dns_adbentrylist_t entries_lru;
|
dns_adbentrylist_t entries_lru;
|
||||||
isc_stdtime_t entries_last_update;
|
isc_stdtime_t entries_last_update;
|
||||||
isc_hashmap_t *entries;
|
isc_hashmap_t *entries;
|
||||||
isc_mutex_t entries_lock;
|
isc_rwlock_t entries_lock;
|
||||||
|
|
||||||
isc_stats_t *stats;
|
isc_stats_t *stats;
|
||||||
|
|
||||||
@@ -372,6 +373,8 @@ maybe_expire_name(dns_adbname_t *adbname, isc_stdtime_t now);
|
|||||||
static void
|
static void
|
||||||
expire_name(dns_adbname_t *adbname, isc_eventtype_t evtype);
|
expire_name(dns_adbname_t *adbname, isc_eventtype_t evtype);
|
||||||
static bool
|
static bool
|
||||||
|
entry_expired(dns_adbentry_t *adbentry, isc_stdtime_t now);
|
||||||
|
static bool
|
||||||
maybe_expire_entry(dns_adbentry_t *adbentry, isc_stdtime_t now);
|
maybe_expire_entry(dns_adbentry_t *adbentry, isc_stdtime_t now);
|
||||||
static void
|
static void
|
||||||
expire_entry(dns_adbentry_t *adbentry);
|
expire_entry(dns_adbentry_t *adbentry);
|
||||||
@@ -762,7 +765,7 @@ static void
|
|||||||
shutdown_names(dns_adb_t *adb) {
|
shutdown_names(dns_adb_t *adb) {
|
||||||
dns_adbname_t *next = NULL;
|
dns_adbname_t *next = NULL;
|
||||||
|
|
||||||
LOCK(&adb->names_lock);
|
RWLOCK(&adb->names_lock, isc_rwlocktype_write);
|
||||||
for (dns_adbname_t *name = ISC_LIST_HEAD(adb->names_lru); name != NULL;
|
for (dns_adbname_t *name = ISC_LIST_HEAD(adb->names_lru); name != NULL;
|
||||||
name = next)
|
name = next)
|
||||||
{
|
{
|
||||||
@@ -779,20 +782,20 @@ shutdown_names(dns_adb_t *adb) {
|
|||||||
UNLOCK(&name->lock);
|
UNLOCK(&name->lock);
|
||||||
dns_adbname_detach(&name);
|
dns_adbname_detach(&name);
|
||||||
}
|
}
|
||||||
UNLOCK(&adb->names_lock);
|
RWUNLOCK(&adb->names_lock, isc_rwlocktype_write);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
shutdown_entries(dns_adb_t *adb) {
|
shutdown_entries(dns_adb_t *adb) {
|
||||||
dns_adbentry_t *next = NULL;
|
dns_adbentry_t *next = NULL;
|
||||||
LOCK(&adb->entries_lock);
|
RWLOCK(&adb->entries_lock, isc_rwlocktype_write);
|
||||||
for (dns_adbentry_t *adbentry = ISC_LIST_HEAD(adb->entries_lru);
|
for (dns_adbentry_t *adbentry = ISC_LIST_HEAD(adb->entries_lru);
|
||||||
adbentry != NULL; adbentry = next)
|
adbentry != NULL; adbentry = next)
|
||||||
{
|
{
|
||||||
next = ISC_LIST_NEXT(adbentry, link);
|
next = ISC_LIST_NEXT(adbentry, link);
|
||||||
expire_entry(adbentry);
|
expire_entry(adbentry);
|
||||||
}
|
}
|
||||||
UNLOCK(&adb->entries_lock);
|
RWUNLOCK(&adb->entries_lock, isc_rwlocktype_write);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1342,6 +1345,7 @@ get_attached_and_locked_name(dns_adb_t *adb, const dns_name_t *name,
|
|||||||
isc_time_t timenow;
|
isc_time_t timenow;
|
||||||
isc_stdtime_t last_update;
|
isc_stdtime_t last_update;
|
||||||
adbnamekey_t key;
|
adbnamekey_t key;
|
||||||
|
isc_rwlocktype_t locktype = isc_rwlocktype_read;
|
||||||
|
|
||||||
isc_time_set(&timenow, now, 0);
|
isc_time_set(&timenow, now, 0);
|
||||||
|
|
||||||
@@ -1351,54 +1355,65 @@ get_attached_and_locked_name(dns_adb_t *adb, const dns_name_t *name,
|
|||||||
|
|
||||||
hashval = isc_hashmap_hash(adb->names, &key.key, key.size);
|
hashval = isc_hashmap_hash(adb->names, &key.key, key.size);
|
||||||
|
|
||||||
LOCK(&adb->names_lock);
|
RWLOCK(&adb->names_lock, locktype);
|
||||||
last_update = adb->names_last_update;
|
last_update = adb->names_last_update;
|
||||||
if (last_update + ADB_STALE_MARGIN < now ||
|
|
||||||
|
if (last_update + ADB_STALE_MARGIN >= now ||
|
||||||
atomic_load_relaxed(&adb->is_overmem))
|
atomic_load_relaxed(&adb->is_overmem))
|
||||||
{
|
{
|
||||||
last_update = adb->names_last_update = now;
|
last_update = now;
|
||||||
|
UPGRADELOCK(&adb->names_lock, locktype);
|
||||||
purge_stale_names(adb, now);
|
purge_stale_names(adb, now);
|
||||||
|
adb->names_last_update = last_update;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = isc_hashmap_find(adb->names, &hashval, key.key, key.size,
|
result = isc_hashmap_find(adb->names, &hashval, key.key, key.size,
|
||||||
(void **)&adbname);
|
(void **)&adbname);
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case ISC_R_NOTFOUND:
|
case ISC_R_NOTFOUND:
|
||||||
|
UPGRADELOCK(&adb->names_lock, locktype);
|
||||||
|
|
||||||
/* Allocate a new name and add it to the hash table. */
|
/* Allocate a new name and add it to the hash table. */
|
||||||
adbname = new_adbname(adb, name, start_at_zone);
|
adbname = new_adbname(adb, name, start_at_zone);
|
||||||
|
|
||||||
result = isc_hashmap_add(adb->names, &hashval,
|
result = isc_hashmap_add(adb->names, &hashval,
|
||||||
&adbname->key.key, adbname->key.size,
|
&adbname->key.key, adbname->key.size,
|
||||||
adbname);
|
adbname);
|
||||||
|
if (result == ISC_R_EXISTS) {
|
||||||
|
destroy_adbname(adbname);
|
||||||
|
adbname = NULL;
|
||||||
|
result = isc_hashmap_find(adb->names, &hashval, key.key,
|
||||||
|
key.size, (void **)&adbname);
|
||||||
|
ISC_LIST_UNLINK(adb->names_lru, adbname, link);
|
||||||
|
}
|
||||||
INSIST(result == ISC_R_SUCCESS);
|
INSIST(result == ISC_R_SUCCESS);
|
||||||
|
|
||||||
dns_adbname_ref(adbname);
|
|
||||||
LOCK(&adbname->lock); /* Must be unlocked by the caller */
|
|
||||||
adbname->last_used = now;
|
|
||||||
|
|
||||||
ISC_LIST_PREPEND(adb->names_lru, adbname, link);
|
|
||||||
break;
|
break;
|
||||||
case ISC_R_SUCCESS:
|
case ISC_R_SUCCESS:
|
||||||
dns_adbname_ref(adbname);
|
if (locktype == isc_rwlocktype_write) {
|
||||||
LOCK(&adbname->lock); /* Must be unlocked by the caller */
|
|
||||||
if (adbname->last_used + ADB_CACHE_MINIMUM <= last_update) {
|
|
||||||
adbname->last_used = now;
|
|
||||||
|
|
||||||
ISC_LIST_UNLINK(adb->names_lru, adbname, link);
|
ISC_LIST_UNLINK(adb->names_lru, adbname, link);
|
||||||
ISC_LIST_PREPEND(adb->names_lru, adbname, link);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dns_adbname_ref(adbname);
|
||||||
|
|
||||||
|
LOCK(&adbname->lock); /* Must be unlocked by the caller */
|
||||||
|
if (adbname->last_used + ADB_CACHE_MINIMUM <= last_update) {
|
||||||
|
adbname->last_used = now;
|
||||||
|
}
|
||||||
|
if (locktype == isc_rwlocktype_write) {
|
||||||
|
ISC_LIST_PREPEND(adb->names_lru, adbname, link);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The refcount is now 2 and the final detach will happen in
|
* The refcount is now 2 and the final detach will happen in
|
||||||
* expire_name() - the unused adbname stored in the hashtable and lru
|
* expire_name() - the unused adbname stored in the hashtable and lru
|
||||||
* has always refcount == 1
|
* has always refcount == 1
|
||||||
*/
|
*/
|
||||||
UNLOCK(&adb->names_lock);
|
RWUNLOCK(&adb->names_lock, locktype);
|
||||||
|
|
||||||
return (adbname);
|
return (adbname);
|
||||||
}
|
}
|
||||||
@@ -1415,64 +1430,93 @@ get_attached_and_locked_entry(dns_adb_t *adb, isc_stdtime_t now,
|
|||||||
isc_stdtime_t last_update;
|
isc_stdtime_t last_update;
|
||||||
uint32_t hashval = isc_hashmap_hash(
|
uint32_t hashval = isc_hashmap_hash(
|
||||||
adb->entries, (const unsigned char *)addr, sizeof(*addr));
|
adb->entries, (const unsigned char *)addr, sizeof(*addr));
|
||||||
|
isc_rwlocktype_t locktype = isc_rwlocktype_read;
|
||||||
|
|
||||||
isc_time_set(&timenow, now, 0);
|
isc_time_set(&timenow, now, 0);
|
||||||
|
|
||||||
LOCK(&adb->entries_lock);
|
RWLOCK(&adb->entries_lock, locktype);
|
||||||
last_update = adb->entries_last_update;
|
last_update = adb->entries_last_update;
|
||||||
|
|
||||||
if (now - last_update > ADB_STALE_MARGIN ||
|
if (now - last_update > ADB_STALE_MARGIN ||
|
||||||
atomic_load_relaxed(&adb->is_overmem))
|
atomic_load_relaxed(&adb->is_overmem))
|
||||||
{
|
{
|
||||||
last_update = adb->entries_last_update = now;
|
last_update = now;
|
||||||
|
|
||||||
|
UPGRADELOCK(&adb->entries_lock, locktype);
|
||||||
|
|
||||||
purge_stale_entries(adb, now);
|
purge_stale_entries(adb, now);
|
||||||
|
adb->entries_last_update = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
again:
|
||||||
result = isc_hashmap_find(adb->entries, &hashval,
|
result = isc_hashmap_find(adb->entries, &hashval,
|
||||||
(const unsigned char *)addr, sizeof(*addr),
|
(const unsigned char *)addr, sizeof(*addr),
|
||||||
(void **)&adbentry);
|
(void **)&adbentry);
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case ISC_R_NOTFOUND: {
|
case ISC_R_NOTFOUND: {
|
||||||
create:
|
create:
|
||||||
|
UPGRADELOCK(&adb->entries_lock, locktype);
|
||||||
|
|
||||||
/* Allocate a new entry and add it to the hash table. */
|
/* Allocate a new entry and add it to the hash table. */
|
||||||
adbentry = new_adbentry(adb, addr);
|
adbentry = new_adbentry(adb, addr);
|
||||||
|
|
||||||
result = isc_hashmap_add(adb->entries, &hashval,
|
result = isc_hashmap_add(adb->entries, &hashval,
|
||||||
&adbentry->sockaddr,
|
&adbentry->sockaddr,
|
||||||
sizeof(adbentry->sockaddr), adbentry);
|
sizeof(adbentry->sockaddr), adbentry);
|
||||||
|
if (result == ISC_R_EXISTS) {
|
||||||
|
dns_adbentry_detach(&adbentry);
|
||||||
|
|
||||||
|
result = isc_hashmap_find(adb->entries, &hashval,
|
||||||
|
(const unsigned char *)addr,
|
||||||
|
sizeof(*addr),
|
||||||
|
(void **)&adbentry);
|
||||||
|
ISC_LIST_UNLINK(adb->entries_lru, adbentry, link);
|
||||||
|
}
|
||||||
INSIST(result == ISC_R_SUCCESS);
|
INSIST(result == ISC_R_SUCCESS);
|
||||||
|
|
||||||
dns_adbentry_ref(adbentry);
|
|
||||||
LOCK(&adbentry->lock); /* Must be unlocked by the caller */
|
|
||||||
adbentry->last_used = now;
|
|
||||||
|
|
||||||
ISC_LIST_PREPEND(adb->entries_lru, adbentry, link);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ISC_R_SUCCESS:
|
case ISC_R_SUCCESS:
|
||||||
/*
|
if (locktype == isc_rwlocktype_write) {
|
||||||
* The dns_adbentry_ref() must stay here before trying to expire
|
|
||||||
* the ADB entry, so it is not destroyed under the lock.
|
|
||||||
*/
|
|
||||||
dns_adbentry_ref(adbentry);
|
|
||||||
LOCK(&adbentry->lock); /* Must be unlocked by the caller */
|
|
||||||
if (maybe_expire_entry(adbentry, now)) {
|
|
||||||
UNLOCK(&adbentry->lock);
|
|
||||||
dns_adbentry_detach(&adbentry);
|
|
||||||
goto create;
|
|
||||||
}
|
|
||||||
if (adbentry->last_used + ADB_CACHE_MINIMUM <= last_update) {
|
|
||||||
adbentry->last_used = now;
|
|
||||||
|
|
||||||
ISC_LIST_UNLINK(adb->entries_lru, adbentry, link);
|
ISC_LIST_UNLINK(adb->entries_lru, adbentry, link);
|
||||||
ISC_LIST_PREPEND(adb->entries_lru, adbentry, link);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
UNLOCK(&adb->entries_lock);
|
/*
|
||||||
|
* The dns_adbentry_ref() must stay here before trying to expire
|
||||||
|
* the ADB entry, so it is not destroyed under the lock.
|
||||||
|
*/
|
||||||
|
dns_adbentry_ref(adbentry);
|
||||||
|
LOCK(&adbentry->lock); /* Must be unlocked by the caller */
|
||||||
|
switch (locktype) {
|
||||||
|
case isc_rwlocktype_read:
|
||||||
|
if (entry_expired(adbentry, now)) {
|
||||||
|
UNLOCK(&adbentry->lock);
|
||||||
|
dns_adbentry_detach(&adbentry);
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case isc_rwlocktype_write:
|
||||||
|
if (maybe_expire_entry(adbentry, now)) {
|
||||||
|
UNLOCK(&adbentry->lock);
|
||||||
|
dns_adbentry_detach(&adbentry);
|
||||||
|
goto create;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (adbentry->last_used + ADB_CACHE_MINIMUM <= last_update) {
|
||||||
|
adbentry->last_used = now;
|
||||||
|
}
|
||||||
|
if (locktype == isc_rwlocktype_write) {
|
||||||
|
ISC_LIST_PREPEND(adb->entries_lru, adbentry, link);
|
||||||
|
}
|
||||||
|
|
||||||
|
RWUNLOCK(&adb->entries_lock, locktype);
|
||||||
|
|
||||||
return (adbentry);
|
return (adbentry);
|
||||||
}
|
}
|
||||||
@@ -1657,9 +1701,7 @@ expire_entry(dns_adbentry_t *adbentry) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
maybe_expire_entry(dns_adbentry_t *adbentry, isc_stdtime_t now) {
|
entry_expired(dns_adbentry_t *adbentry, isc_stdtime_t now) {
|
||||||
REQUIRE(DNS_ADBENTRY_VALID(adbentry));
|
|
||||||
|
|
||||||
if (!ISC_LIST_EMPTY(adbentry->nhs)) {
|
if (!ISC_LIST_EMPTY(adbentry->nhs)) {
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
@@ -1668,11 +1710,21 @@ maybe_expire_entry(dns_adbentry_t *adbentry, isc_stdtime_t now) {
|
|||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
expire_entry(adbentry);
|
|
||||||
|
|
||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
maybe_expire_entry(dns_adbentry_t *adbentry, isc_stdtime_t now) {
|
||||||
|
REQUIRE(DNS_ADBENTRY_VALID(adbentry));
|
||||||
|
|
||||||
|
if (entry_expired(adbentry, now)) {
|
||||||
|
expire_entry(adbentry);
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
* Examine the tail entry of the LRU list to see if it expires or is stale
|
* Examine the tail entry of the LRU list to see if it expires or is stale
|
||||||
* (unused for some period); if so, the name entry will be freed. If the ADB
|
* (unused for some period); if so, the name entry will be freed. If the ADB
|
||||||
@@ -1756,7 +1808,7 @@ static void
|
|||||||
cleanup_names(dns_adb_t *adb, isc_stdtime_t now) {
|
cleanup_names(dns_adb_t *adb, isc_stdtime_t now) {
|
||||||
dns_adbname_t *next = NULL;
|
dns_adbname_t *next = NULL;
|
||||||
|
|
||||||
LOCK(&adb->names_lock);
|
RWLOCK(&adb->names_lock, isc_rwlocktype_write);
|
||||||
for (dns_adbname_t *adbname = ISC_LIST_HEAD(adb->names_lru);
|
for (dns_adbname_t *adbname = ISC_LIST_HEAD(adb->names_lru);
|
||||||
adbname != NULL; adbname = next)
|
adbname != NULL; adbname = next)
|
||||||
{
|
{
|
||||||
@@ -1775,7 +1827,7 @@ cleanup_names(dns_adb_t *adb, isc_stdtime_t now) {
|
|||||||
UNLOCK(&adbname->lock);
|
UNLOCK(&adbname->lock);
|
||||||
dns_adbname_detach(&adbname);
|
dns_adbname_detach(&adbname);
|
||||||
}
|
}
|
||||||
UNLOCK(&adb->names_lock);
|
RWUNLOCK(&adb->names_lock, isc_rwlocktype_write);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
@@ -1859,7 +1911,7 @@ static void
|
|||||||
cleanup_entries(dns_adb_t *adb, isc_stdtime_t now) {
|
cleanup_entries(dns_adb_t *adb, isc_stdtime_t now) {
|
||||||
dns_adbentry_t *next = NULL;
|
dns_adbentry_t *next = NULL;
|
||||||
|
|
||||||
LOCK(&adb->entries_lock);
|
RWLOCK(&adb->entries_lock, isc_rwlocktype_write);
|
||||||
for (dns_adbentry_t *adbentry = ISC_LIST_HEAD(adb->entries_lru);
|
for (dns_adbentry_t *adbentry = ISC_LIST_HEAD(adb->entries_lru);
|
||||||
adbentry != NULL; adbentry = next)
|
adbentry != NULL; adbentry = next)
|
||||||
{
|
{
|
||||||
@@ -1871,7 +1923,7 @@ cleanup_entries(dns_adb_t *adb, isc_stdtime_t now) {
|
|||||||
UNLOCK(&adbentry->lock);
|
UNLOCK(&adbentry->lock);
|
||||||
dns_adbentry_detach(&adbentry);
|
dns_adbentry_detach(&adbentry);
|
||||||
}
|
}
|
||||||
UNLOCK(&adb->entries_lock);
|
RWUNLOCK(&adb->entries_lock, isc_rwlocktype_write);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1880,18 +1932,18 @@ destroy(dns_adb_t *adb) {
|
|||||||
|
|
||||||
adb->magic = 0;
|
adb->magic = 0;
|
||||||
|
|
||||||
LOCK(&adb->names_lock);
|
RWLOCK(&adb->names_lock, isc_rwlocktype_write);
|
||||||
INSIST(isc_hashmap_count(adb->names) == 0);
|
INSIST(isc_hashmap_count(adb->names) == 0);
|
||||||
isc_hashmap_destroy(&adb->names);
|
isc_hashmap_destroy(&adb->names);
|
||||||
UNLOCK(&adb->names_lock);
|
RWUNLOCK(&adb->names_lock, isc_rwlocktype_write);
|
||||||
isc_mutex_destroy(&adb->names_lock);
|
isc_rwlock_destroy(&adb->names_lock);
|
||||||
|
|
||||||
LOCK(&adb->entries_lock);
|
RWLOCK(&adb->entries_lock, isc_rwlocktype_write);
|
||||||
/* There are no unassociated entries */
|
/* There are no unassociated entries */
|
||||||
INSIST(isc_hashmap_count(adb->entries) == 0);
|
INSIST(isc_hashmap_count(adb->entries) == 0);
|
||||||
isc_hashmap_destroy(&adb->entries);
|
isc_hashmap_destroy(&adb->entries);
|
||||||
UNLOCK(&adb->entries_lock);
|
RWUNLOCK(&adb->entries_lock, isc_rwlocktype_write);
|
||||||
isc_mutex_destroy(&adb->entries_lock);
|
isc_rwlock_destroy(&adb->entries_lock);
|
||||||
|
|
||||||
isc_mem_destroy(&adb->hmctx);
|
isc_mem_destroy(&adb->hmctx);
|
||||||
|
|
||||||
@@ -1956,11 +2008,11 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_loopmgr_t *loopmgr,
|
|||||||
|
|
||||||
isc_hashmap_create(adb->hmctx, ADB_HASH_BITS,
|
isc_hashmap_create(adb->hmctx, ADB_HASH_BITS,
|
||||||
ISC_HASHMAP_CASE_INSENSITIVE, &adb->names);
|
ISC_HASHMAP_CASE_INSENSITIVE, &adb->names);
|
||||||
isc_mutex_init(&adb->names_lock);
|
isc_rwlock_init(&adb->names_lock);
|
||||||
|
|
||||||
isc_hashmap_create(adb->hmctx, ADB_HASH_BITS,
|
isc_hashmap_create(adb->hmctx, ADB_HASH_BITS,
|
||||||
ISC_HASHMAP_CASE_SENSITIVE, &adb->entries);
|
ISC_HASHMAP_CASE_SENSITIVE, &adb->entries);
|
||||||
isc_mutex_init(&adb->entries_lock);
|
isc_rwlock_init(&adb->entries_lock);
|
||||||
|
|
||||||
isc_mutex_init(&adb->lock);
|
isc_mutex_init(&adb->lock);
|
||||||
|
|
||||||
@@ -2002,11 +2054,11 @@ free_tasks:
|
|||||||
|
|
||||||
isc_mutex_destroy(&adb->lock);
|
isc_mutex_destroy(&adb->lock);
|
||||||
|
|
||||||
isc_mutex_destroy(&adb->entries_lock);
|
isc_rwlock_destroy(&adb->entries_lock);
|
||||||
isc_hashmap_destroy(&adb->entries);
|
isc_hashmap_destroy(&adb->entries);
|
||||||
INSIST(ISC_LIST_EMPTY(adb->entries_lru));
|
INSIST(ISC_LIST_EMPTY(adb->entries_lru));
|
||||||
|
|
||||||
isc_mutex_destroy(&adb->names_lock);
|
isc_rwlock_destroy(&adb->names_lock);
|
||||||
isc_hashmap_destroy(&adb->names);
|
isc_hashmap_destroy(&adb->names);
|
||||||
INSIST(ISC_LIST_EMPTY(adb->names_lru));
|
INSIST(ISC_LIST_EMPTY(adb->names_lru));
|
||||||
|
|
||||||
@@ -2507,7 +2559,7 @@ dump_adb(dns_adb_t *adb, FILE *f, bool debug, isc_stdtime_t now) {
|
|||||||
/*
|
/*
|
||||||
* Ensure this operation is applied to both hash tables at once.
|
* Ensure this operation is applied to both hash tables at once.
|
||||||
*/
|
*/
|
||||||
LOCK(&adb->names_lock);
|
RWLOCK(&adb->names_lock, isc_rwlocktype_write);
|
||||||
|
|
||||||
for (dns_adbname_t *name = ISC_LIST_HEAD(adb->names_lru); name != NULL;
|
for (dns_adbname_t *name = ISC_LIST_HEAD(adb->names_lru); name != NULL;
|
||||||
name = ISC_LIST_NEXT(name, link))
|
name = ISC_LIST_NEXT(name, link))
|
||||||
@@ -2546,7 +2598,7 @@ dump_adb(dns_adb_t *adb, FILE *f, bool debug, isc_stdtime_t now) {
|
|||||||
UNLOCK(&name->lock);
|
UNLOCK(&name->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCK(&adb->entries_lock);
|
RWLOCK(&adb->entries_lock, isc_rwlocktype_write);
|
||||||
fprintf(f, ";\n; Unassociated entries\n;\n");
|
fprintf(f, ";\n; Unassociated entries\n;\n");
|
||||||
for (dns_adbentry_t *adbentry = ISC_LIST_HEAD(adb->entries_lru);
|
for (dns_adbentry_t *adbentry = ISC_LIST_HEAD(adb->entries_lru);
|
||||||
adbentry != NULL; adbentry = ISC_LIST_NEXT(adbentry, link))
|
adbentry != NULL; adbentry = ISC_LIST_NEXT(adbentry, link))
|
||||||
@@ -2558,8 +2610,8 @@ dump_adb(dns_adb_t *adb, FILE *f, bool debug, isc_stdtime_t now) {
|
|||||||
UNLOCK(&adbentry->lock);
|
UNLOCK(&adbentry->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
UNLOCK(&adb->entries_lock);
|
RWUNLOCK(&adb->entries_lock, isc_rwlocktype_write);
|
||||||
UNLOCK(&adb->names_lock);
|
RWUNLOCK(&adb->names_lock, isc_rwlocktype_write);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -2735,7 +2787,7 @@ dns_adb_dumpquota(dns_adb_t *adb, isc_buffer_t **buf) {
|
|||||||
isc_hashmap_iter_t *it = NULL;
|
isc_hashmap_iter_t *it = NULL;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
|
|
||||||
LOCK(&adb->entries_lock);
|
RWLOCK(&adb->entries_lock, isc_rwlocktype_read);
|
||||||
isc_hashmap_iter_create(adb->entries, &it);
|
isc_hashmap_iter_create(adb->entries, &it);
|
||||||
for (result = isc_hashmap_iter_first(it); result == ISC_R_SUCCESS;
|
for (result = isc_hashmap_iter_first(it); result == ISC_R_SUCCESS;
|
||||||
result = isc_hashmap_iter_next(it))
|
result = isc_hashmap_iter_next(it))
|
||||||
@@ -2764,7 +2816,7 @@ dns_adb_dumpquota(dns_adb_t *adb, isc_buffer_t **buf) {
|
|||||||
UNLOCK(&entry->lock);
|
UNLOCK(&entry->lock);
|
||||||
}
|
}
|
||||||
isc_hashmap_iter_destroy(&it);
|
isc_hashmap_iter_destroy(&it);
|
||||||
UNLOCK(&adb->entries_lock);
|
RWUNLOCK(&adb->entries_lock, isc_rwlocktype_read);
|
||||||
|
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
@@ -3612,7 +3664,7 @@ dns_adb_flushname(dns_adb_t *adb, const dns_name_t *name) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCK(&adb->names_lock);
|
RWLOCK(&adb->names_lock, isc_rwlocktype_write);
|
||||||
again:
|
again:
|
||||||
/*
|
/*
|
||||||
* Delete both entries - without and with NAME_STARTATZONE set.
|
* Delete both entries - without and with NAME_STARTATZONE set.
|
||||||
@@ -3636,7 +3688,7 @@ again:
|
|||||||
start_at_zone = true;
|
start_at_zone = true;
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
UNLOCK(&adb->names_lock);
|
RWUNLOCK(&adb->names_lock, isc_rwlocktype_write);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -3650,7 +3702,7 @@ dns_adb_flushnames(dns_adb_t *adb, const dns_name_t *name) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCK(&adb->names_lock);
|
RWLOCK(&adb->names_lock, isc_rwlocktype_write);
|
||||||
for (dns_adbname_t *adbname = ISC_LIST_HEAD(adb->names_lru);
|
for (dns_adbname_t *adbname = ISC_LIST_HEAD(adb->names_lru);
|
||||||
adbname != NULL; adbname = next)
|
adbname != NULL; adbname = next)
|
||||||
{
|
{
|
||||||
@@ -3663,7 +3715,7 @@ dns_adb_flushnames(dns_adb_t *adb, const dns_name_t *name) {
|
|||||||
UNLOCK(&adbname->lock);
|
UNLOCK(&adbname->lock);
|
||||||
dns_adbname_detach(&adbname);
|
dns_adbname_detach(&adbname);
|
||||||
}
|
}
|
||||||
UNLOCK(&adb->names_lock);
|
RWUNLOCK(&adb->names_lock, isc_rwlocktype_write);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Reference in New Issue
Block a user