static void
inc_entry_refcnt(dns_adb_t *, dns_adbentry_t *, bool);
static bool
-dec_entry_refcnt(dns_adb_t *, bool, dns_adbentry_t *, bool);
+dec_entry_refcnt(dns_adb_t *, bool, dns_adbentry_t *, bool, isc_stdtime_t);
static void
violate_locking_hierarchy(isc_mutex_t *, isc_mutex_t *);
static bool
}
entry->nh--;
- result = dec_entry_refcnt(adb, overmem, entry, false);
+ result = dec_entry_refcnt(adb, overmem, entry, false,
+ INT_MAX);
}
/*
}
static bool
-dec_entry_refcnt(dns_adb_t *adb, bool overmem, dns_adbentry_t *entry,
- bool lock) {
+dec_entry_refcnt(dns_adb_t *adb, bool overmem, dns_adbentry_t *entry, bool lock,
+ isc_stdtime_t now) {
int bucket;
- bool destroy_entry;
+ bool destroy_entry = false;
bool result = false;
bucket = entry->lock_bucket;
INSIST(entry->refcnt > 0);
entry->refcnt--;
- destroy_entry = false;
if (entry->refcnt == 0 &&
- (adb->entry_sd[bucket] || entry->expires == 0 || overmem ||
+ (adb->entry_sd[bucket] || entry->expires == 0 ||
+ (overmem && entry->expires + ADB_CACHE_MINIMUM < now) ||
(entry->flags & ENTRY_IS_DEAD) != 0))
{
destroy_entry = true;
goto next;
}
+ /*
+ * Make sure that we are not purging ADB names that has been
+ * just created.
+ */
+ if (victim->last_used + ADB_CACHE_MINIMUM >= now) {
+ break;
+ }
+
if (!NAME_FETCH(victim) &&
(overmem || victim->last_used + ADB_STALE_MARGIN <= now))
{
int bucket;
dns_adb_t *adb;
bool overmem;
+ isc_stdtime_t now;
REQUIRE(findp != NULL && DNS_ADBFIND_VALID(*findp));
find = *findp;
* Return the find to the memory pool, and decrement the adb's
* reference count.
*/
+ isc_stdtime_get(&now);
overmem = isc_mem_isovermem(adb->mctx);
ai = ISC_LIST_HEAD(find->list);
while (ai != NULL) {
entry = ai->entry;
ai->entry = NULL;
INSIST(DNS_ADBENTRY_VALID(entry));
- RUNTIME_CHECK(!dec_entry_refcnt(adb, overmem, entry, true));
+ RUNTIME_CHECK(
+ !dec_entry_refcnt(adb, overmem, entry, true, now));
free_adbaddrinfo(adb, &ai);
ai = ISC_LIST_HEAD(find->list);
}
bucket = addr->entry->lock_bucket;
LOCK(&adb->entrylocks[bucket]);
+ isc_stdtime_get(&now);
if (entry->expires == 0) {
- isc_stdtime_get(&now);
entry->expires = now + ADB_ENTRY_WINDOW;
}
- want_check_exit = dec_entry_refcnt(adb, overmem, entry, false);
+ want_check_exit = dec_entry_refcnt(adb, overmem, entry, false, now);
UNLOCK(&adb->entrylocks[bucket]);