mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 05:57:52 +00:00
Convert cache->live_tasks to reference counter.
This commit is contained in:
parent
ed494fe29d
commit
9edcaa0832
@ -132,9 +132,9 @@ struct dns_cache {
|
|||||||
isc_mem_t *hmctx; /* Heap memory */
|
isc_mem_t *hmctx; /* Heap memory */
|
||||||
char *name;
|
char *name;
|
||||||
isc_refcount_t references;
|
isc_refcount_t references;
|
||||||
|
isc_refcount_t live_tasks;
|
||||||
|
|
||||||
/* Locked by 'lock'. */
|
/* Locked by 'lock'. */
|
||||||
int live_tasks;
|
|
||||||
dns_rdataclass_t rdclass;
|
dns_rdataclass_t rdclass;
|
||||||
dns_db_t *db;
|
dns_db_t *db;
|
||||||
cache_cleaner_t cleaner;
|
cache_cleaner_t cleaner;
|
||||||
@ -210,7 +210,7 @@ dns_cache_create(isc_mem_t *cmctx, isc_mem_t *hmctx, isc_taskmgr_t *taskmgr,
|
|||||||
isc_mutex_init(&cache->filelock);
|
isc_mutex_init(&cache->filelock);
|
||||||
|
|
||||||
isc_refcount_init(&cache->references, 1);
|
isc_refcount_init(&cache->references, 1);
|
||||||
cache->live_tasks = 0;
|
isc_refcount_init(&cache->live_tasks, 1);
|
||||||
cache->rdclass = rdclass;
|
cache->rdclass = rdclass;
|
||||||
cache->serve_stale_ttl = 0;
|
cache->serve_stale_ttl = 0;
|
||||||
|
|
||||||
@ -317,21 +317,27 @@ cache_free(dns_cache_t *cache) {
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
REQUIRE(VALID_CACHE(cache));
|
REQUIRE(VALID_CACHE(cache));
|
||||||
REQUIRE(isc_refcount_current(&cache->references) == 0);
|
|
||||||
|
isc_refcount_destroy(&cache->references);
|
||||||
|
isc_refcount_destroy(&cache->live_tasks);
|
||||||
|
|
||||||
isc_mem_setwater(cache->mctx, NULL, NULL, 0, 0);
|
isc_mem_setwater(cache->mctx, NULL, NULL, 0, 0);
|
||||||
|
|
||||||
if (cache->cleaner.task != NULL)
|
if (cache->cleaner.task != NULL) {
|
||||||
isc_task_detach(&cache->cleaner.task);
|
isc_task_detach(&cache->cleaner.task);
|
||||||
|
}
|
||||||
|
|
||||||
if (cache->cleaner.overmem_event != NULL)
|
if (cache->cleaner.overmem_event != NULL) {
|
||||||
isc_event_free(&cache->cleaner.overmem_event);
|
isc_event_free(&cache->cleaner.overmem_event);
|
||||||
|
}
|
||||||
|
|
||||||
if (cache->cleaner.resched_event != NULL)
|
if (cache->cleaner.resched_event != NULL) {
|
||||||
isc_event_free(&cache->cleaner.resched_event);
|
isc_event_free(&cache->cleaner.resched_event);
|
||||||
|
}
|
||||||
|
|
||||||
if (cache->cleaner.iterator != NULL)
|
if (cache->cleaner.iterator != NULL) {
|
||||||
dns_dbiterator_destroy(&cache->cleaner.iterator);
|
dns_dbiterator_destroy(&cache->cleaner.iterator);
|
||||||
|
}
|
||||||
|
|
||||||
isc_mutex_destroy(&cache->cleaner.lock);
|
isc_mutex_destroy(&cache->cleaner.lock);
|
||||||
|
|
||||||
@ -340,8 +346,9 @@ cache_free(dns_cache_t *cache) {
|
|||||||
cache->filename = NULL;
|
cache->filename = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cache->db != NULL)
|
if (cache->db != NULL) {
|
||||||
dns_db_detach(&cache->db);
|
dns_db_detach(&cache->db);
|
||||||
|
}
|
||||||
|
|
||||||
if (cache->db_argv != NULL) {
|
if (cache->db_argv != NULL) {
|
||||||
/*
|
/*
|
||||||
@ -349,23 +356,30 @@ cache_free(dns_cache_t *cache) {
|
|||||||
* as it's a pointer to hmctx
|
* as it's a pointer to hmctx
|
||||||
*/
|
*/
|
||||||
int extra = 0;
|
int extra = 0;
|
||||||
if (strcmp(cache->db_type, "rbt") == 0)
|
if (strcmp(cache->db_type, "rbt") == 0) {
|
||||||
extra = 1;
|
extra = 1;
|
||||||
for (i = extra; i < cache->db_argc; i++)
|
}
|
||||||
if (cache->db_argv[i] != NULL)
|
for (i = extra; i < cache->db_argc; i++) {
|
||||||
isc_mem_free(cache->mctx, cache->db_argv[i]);
|
if (cache->db_argv[i] != NULL) {
|
||||||
|
isc_mem_free(cache->mctx,
|
||||||
|
cache->db_argv[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
isc_mem_put(cache->mctx, cache->db_argv,
|
isc_mem_put(cache->mctx, cache->db_argv,
|
||||||
cache->db_argc * sizeof(char *));
|
cache->db_argc * sizeof(char *));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cache->db_type != NULL)
|
if (cache->db_type != NULL) {
|
||||||
isc_mem_free(cache->mctx, cache->db_type);
|
isc_mem_free(cache->mctx, cache->db_type);
|
||||||
|
}
|
||||||
|
|
||||||
if (cache->name != NULL)
|
if (cache->name != NULL) {
|
||||||
isc_mem_free(cache->mctx, cache->name);
|
isc_mem_free(cache->mctx, cache->name);
|
||||||
|
}
|
||||||
|
|
||||||
if (cache->stats != NULL)
|
if (cache->stats != NULL) {
|
||||||
isc_stats_detach(&cache->stats);
|
isc_stats_detach(&cache->stats);
|
||||||
|
}
|
||||||
|
|
||||||
isc_mutex_destroy(&cache->lock);
|
isc_mutex_destroy(&cache->lock);
|
||||||
isc_mutex_destroy(&cache->filelock);
|
isc_mutex_destroy(&cache->filelock);
|
||||||
@ -390,7 +404,6 @@ dns_cache_attach(dns_cache_t *cache, dns_cache_t **targetp) {
|
|||||||
void
|
void
|
||||||
dns_cache_detach(dns_cache_t **cachep) {
|
dns_cache_detach(dns_cache_t **cachep) {
|
||||||
dns_cache_t *cache;
|
dns_cache_t *cache;
|
||||||
bool free_cache = false;
|
|
||||||
|
|
||||||
REQUIRE(cachep != NULL);
|
REQUIRE(cachep != NULL);
|
||||||
cache = *cachep;
|
cache = *cachep;
|
||||||
@ -398,33 +411,27 @@ dns_cache_detach(dns_cache_t **cachep) {
|
|||||||
*cachep = NULL;
|
*cachep = NULL;
|
||||||
|
|
||||||
if (isc_refcount_decrement(&cache->references) == 1) {
|
if (isc_refcount_decrement(&cache->references) == 1) {
|
||||||
LOCK(&cache->lock);
|
|
||||||
free_cache = true;
|
|
||||||
cache->cleaner.overmem = false;
|
cache->cleaner.overmem = false;
|
||||||
/*
|
/*
|
||||||
* When the cache is shut down, dump it to a file if one is
|
* When the cache is shut down, dump it to a file if one is
|
||||||
* specified.
|
* specified.
|
||||||
*/
|
*/
|
||||||
isc_result_t result = dns_cache_dump(cache);
|
isc_result_t result = dns_cache_dump(cache);
|
||||||
if (result != ISC_R_SUCCESS)
|
if (result != ISC_R_SUCCESS) {
|
||||||
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
|
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
|
||||||
DNS_LOGMODULE_CACHE, ISC_LOG_WARNING,
|
DNS_LOGMODULE_CACHE, ISC_LOG_WARNING,
|
||||||
"error dumping cache: %s ",
|
"error dumping cache: %s ",
|
||||||
isc_result_totext(result));
|
isc_result_totext(result));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the cleaner task exists, let it free the cache.
|
* If the cleaner task exists, let it free the cache.
|
||||||
*/
|
*/
|
||||||
if (cache->live_tasks > 0) {
|
if (isc_refcount_decrement(&cache->live_tasks) > 1) {
|
||||||
isc_task_shutdown(cache->cleaner.task);
|
isc_task_shutdown(cache->cleaner.task);
|
||||||
free_cache = false;
|
} else {
|
||||||
|
cache_free(cache);
|
||||||
}
|
}
|
||||||
UNLOCK(&cache->lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (free_cache) {
|
|
||||||
cache_free(cache);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -538,12 +545,13 @@ cache_cleaner_init(dns_cache_t *cache, isc_taskmgr_t *taskmgr,
|
|||||||
result = ISC_R_UNEXPECTED;
|
result = ISC_R_UNEXPECTED;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
cleaner->cache->live_tasks++;
|
isc_refcount_increment(&cleaner->cache->live_tasks);
|
||||||
isc_task_setname(cleaner->task, "cachecleaner", cleaner);
|
isc_task_setname(cleaner->task, "cachecleaner", cleaner);
|
||||||
|
|
||||||
result = isc_task_onshutdown(cleaner->task,
|
result = isc_task_onshutdown(cleaner->task,
|
||||||
cleaner_shutdown_action, cache);
|
cleaner_shutdown_action, cache);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
isc_refcount_decrement(&cleaner->cache->live_tasks);
|
||||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||||
"cache cleaner: "
|
"cache cleaner: "
|
||||||
"isc_task_onshutdown() failed: %s",
|
"isc_task_onshutdown() failed: %s",
|
||||||
@ -976,34 +984,24 @@ dns_cache_getservestalettl(dns_cache_t *cache) {
|
|||||||
static void
|
static void
|
||||||
cleaner_shutdown_action(isc_task_t *task, isc_event_t *event) {
|
cleaner_shutdown_action(isc_task_t *task, isc_event_t *event) {
|
||||||
dns_cache_t *cache = event->ev_arg;
|
dns_cache_t *cache = event->ev_arg;
|
||||||
bool should_free = false;
|
|
||||||
|
|
||||||
UNUSED(task);
|
UNUSED(task);
|
||||||
|
|
||||||
INSIST(task == cache->cleaner.task);
|
INSIST(task == cache->cleaner.task);
|
||||||
INSIST(event->ev_type == ISC_TASKEVENT_SHUTDOWN);
|
INSIST(event->ev_type == ISC_TASKEVENT_SHUTDOWN);
|
||||||
|
|
||||||
if (CLEANER_BUSY(&cache->cleaner))
|
if (CLEANER_BUSY(&cache->cleaner)) {
|
||||||
end_cleaning(&cache->cleaner, event);
|
end_cleaning(&cache->cleaner, event);
|
||||||
else
|
} else {
|
||||||
isc_event_free(&event);
|
isc_event_free(&event);
|
||||||
|
|
||||||
LOCK(&cache->lock);
|
|
||||||
|
|
||||||
cache->live_tasks--;
|
|
||||||
INSIST(cache->live_tasks == 0);
|
|
||||||
|
|
||||||
if (isc_refcount_current(&cache->references) == 0) {
|
|
||||||
should_free = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure we don't reschedule anymore. */
|
/* Make sure we don't reschedule anymore. */
|
||||||
(void)isc_task_purge(task, NULL, DNS_EVENT_CACHECLEAN, NULL);
|
(void)isc_task_purge(task, NULL, DNS_EVENT_CACHECLEAN, NULL);
|
||||||
|
|
||||||
UNLOCK(&cache->lock);
|
INSIST(isc_refcount_decrement(&cache->live_tasks) == 1);
|
||||||
|
|
||||||
if (should_free)
|
cache_free(cache);
|
||||||
cache_free(cache);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
|
Loading…
x
Reference in New Issue
Block a user