mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-29 05:28:00 +00:00
3353. [bug] Use a single task for task exclusive operations.
[RT #29872]
This commit is contained in:
parent
77e3e9daf1
commit
c965b18690
3
CHANGES
3
CHANGES
@ -1,3 +1,6 @@
|
||||
3353. [bug] Use a single task for task exclusive operations.
|
||||
[RT #29872]
|
||||
|
||||
3352. [bug] Ensure that learned server attributes timeout of the
|
||||
adb cache. [RT #29856]
|
||||
|
||||
|
@ -5603,11 +5603,13 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
|
||||
|
||||
/*
|
||||
* Setup the server task, which is responsible for coordinating
|
||||
* startup and shutdown of the server.
|
||||
* startup and shutdown of the server, as well as all exclusive
|
||||
* tasks.
|
||||
*/
|
||||
CHECKFATAL(isc_task_create(ns_g_taskmgr, 0, &server->task),
|
||||
"creating server task");
|
||||
isc_task_setname(server->task, "server", server);
|
||||
isc_taskmgr_setexcltask(ns_g_taskmgr, server->task);
|
||||
CHECKFATAL(isc_task_onshutdown(server->task, shutdown_server, server),
|
||||
"isc_task_onshutdown");
|
||||
CHECKFATAL(isc_app_onrun(ns_g_mctx, server->task, run_server, server),
|
||||
|
@ -111,6 +111,7 @@ struct dns_adb {
|
||||
|
||||
isc_taskmgr_t *taskmgr;
|
||||
isc_task_t *task;
|
||||
isc_task_t *excl;
|
||||
|
||||
isc_interval_t tick_interval;
|
||||
int next_cleanbucket;
|
||||
@ -1653,10 +1654,12 @@ new_adbname(dns_adb_t *adb, dns_name_t *dnsname) {
|
||||
LOCK(&adb->namescntlock);
|
||||
adb->namescnt++;
|
||||
inc_adbstats(adb, dns_adbstats_namescnt);
|
||||
if (!adb->grownames_sent && adb->namescnt > (adb->nnames * 8)) {
|
||||
if (!adb->grownames_sent && adb->excl != NULL &&
|
||||
adb->namescnt > (adb->nnames * 8))
|
||||
{
|
||||
isc_event_t *event = &adb->grownames;
|
||||
inc_adb_irefcnt(adb);
|
||||
isc_task_send(adb->task, &event);
|
||||
isc_task_send(adb->excl, &event);
|
||||
adb->grownames_sent = ISC_TRUE;
|
||||
}
|
||||
UNLOCK(&adb->namescntlock);
|
||||
@ -1779,8 +1782,9 @@ new_adbentry(dns_adb_t *adb) {
|
||||
LOCK(&adb->entriescntlock);
|
||||
adb->entriescnt++;
|
||||
inc_adbstats(adb, dns_adbstats_entriescnt);
|
||||
if (!adb->growentries_sent &&
|
||||
adb->entriescnt > (adb->nentries * 8)) {
|
||||
if (!adb->growentries_sent && adb->growentries_sent &&
|
||||
adb->entriescnt > (adb->nentries * 8))
|
||||
{
|
||||
isc_event_t *event = &adb->growentries;
|
||||
inc_adb_irefcnt(adb);
|
||||
isc_task_send(adb->task, &event);
|
||||
@ -2356,6 +2360,7 @@ destroy(dns_adb_t *adb) {
|
||||
adb->magic = 0;
|
||||
|
||||
isc_task_detach(&adb->task);
|
||||
isc_task_detach(&adb->excl);
|
||||
|
||||
isc_mempool_destroy(&adb->nmp);
|
||||
isc_mempool_destroy(&adb->nhmp);
|
||||
@ -2439,6 +2444,7 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
|
||||
adb->aimp = NULL;
|
||||
adb->afmp = NULL;
|
||||
adb->task = NULL;
|
||||
adb->excl = NULL;
|
||||
adb->mctx = NULL;
|
||||
adb->view = view;
|
||||
adb->taskmgr = taskmgr;
|
||||
@ -2474,6 +2480,16 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
|
||||
adb, NULL, NULL);
|
||||
adb->grownames_sent = ISC_FALSE;
|
||||
|
||||
result = isc_taskmgr_excltask(adb->taskmgr, &adb->excl);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
DP(ISC_LOG_INFO, "adb: task-exclusive mode unavailable, "
|
||||
"intializing table sizes to %u\n",
|
||||
nbuckets[11]);
|
||||
adb->nentries = nbuckets[11];
|
||||
adb->nnames= nbuckets[11];
|
||||
|
||||
}
|
||||
|
||||
isc_mem_attach(mem, &adb->mctx);
|
||||
|
||||
result = isc_mutex_init(&adb->lock);
|
||||
@ -2586,11 +2602,13 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
|
||||
result = isc_task_create(adb->taskmgr, 0, &adb->task);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto fail3;
|
||||
|
||||
isc_task_setname(adb->task, "ADB", adb);
|
||||
|
||||
result = isc_stats_create(adb->mctx, &view->adbstats, dns_adbstats_max);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto fail3;
|
||||
|
||||
set_adbstat(adb, adb->nentries, dns_adbstats_nentries);
|
||||
set_adbstat(adb, adb->nnames, dns_adbstats_nnames);
|
||||
|
||||
|
@ -153,6 +153,8 @@
|
||||
#define isc_taskmgr_setmode isc__taskmgr_setmode
|
||||
#define isc_taskmgr_mode isc__taskmgr_mode
|
||||
#define isc_taskmgr_destroy isc__taskmgr_destroy
|
||||
#define isc_taskmgr_setexcltask isc__taskmgr_setexcltask
|
||||
#define isc_taskmgr_excltask isc__taskmgr_excltask
|
||||
#define isc_task_beginexclusive isc__task_beginexclusive
|
||||
#define isc_task_endexclusive isc__task_endexclusive
|
||||
#define isc_task_setprivilege isc__task_setprivilege
|
||||
|
@ -115,6 +115,8 @@ typedef struct isc_taskmgrmethods {
|
||||
isc_result_t (*taskcreate)(isc_taskmgr_t *manager,
|
||||
unsigned int quantum,
|
||||
isc_task_t **taskp);
|
||||
void (*setexcltask)(isc_taskmgr_t *mgr, isc_task_t *task);
|
||||
isc_result_t (*excltask)(isc_taskmgr_t *mgr, isc_task_t **taskp);
|
||||
} isc_taskmgrmethods_t;
|
||||
|
||||
typedef struct isc_taskmethods {
|
||||
@ -759,6 +761,31 @@ isc_taskmgr_destroy(isc_taskmgr_t **managerp);
|
||||
* have been freed.
|
||||
*/
|
||||
|
||||
void
|
||||
isc_taskmgr_setexcltask(isc_taskmgr_t *mgr, isc_task_t *task);
|
||||
/*%<
|
||||
* Set a task which will be used for all task-exclusive operations.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'manager' is a valid task manager.
|
||||
*
|
||||
*\li 'task' is a valid task.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
isc_taskmgr_excltask(isc_taskmgr_t *mgr, isc_task_t **taskp);
|
||||
/*%<
|
||||
* Attach '*taskp' to the task set by isc_taskmgr_getexcltask().
|
||||
* This task should be used whenever running in task-exclusive mode,
|
||||
* so as to prevent deadlock between two exclusive tasks.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'manager' is a valid task manager.
|
||||
|
||||
*\li taskp != NULL && *taskp == NULL
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_LIBXML2
|
||||
|
||||
void
|
||||
|
@ -158,6 +158,7 @@ struct isc__taskmgr {
|
||||
isc_boolean_t pause_requested;
|
||||
isc_boolean_t exclusive_requested;
|
||||
isc_boolean_t exiting;
|
||||
isc__task_t *excl;
|
||||
#ifdef USE_SHARED_MANAGER
|
||||
unsigned int refs;
|
||||
#endif /* ISC_PLATFORM_USETHREADS */
|
||||
@ -227,6 +228,10 @@ isc__taskmgr_create(isc_mem_t *mctx, unsigned int workers,
|
||||
unsigned int default_quantum, isc_taskmgr_t **managerp);
|
||||
ISC_TASKFUNC_SCOPE void
|
||||
isc__taskmgr_destroy(isc_taskmgr_t **managerp);
|
||||
ISC_TASKFUNC_SCOPE void
|
||||
isc__taskmgr_setexcltask(isc_taskmgr_t *mgr0, isc_task_t *task0);
|
||||
ISC_TASKFUNC_SCOPE isc_result_t
|
||||
isc__taskmgr_excltask(isc_taskmgr_t *mgr0, isc_task_t **taskp);
|
||||
ISC_TASKFUNC_SCOPE isc_result_t
|
||||
isc__task_beginexclusive(isc_task_t *task);
|
||||
ISC_TASKFUNC_SCOPE void
|
||||
@ -288,7 +293,9 @@ static isc_taskmgrmethods_t taskmgrmethods = {
|
||||
isc__taskmgr_destroy,
|
||||
isc__taskmgr_setmode,
|
||||
isc__taskmgr_mode,
|
||||
isc__task_create
|
||||
isc__task_create,
|
||||
isc__taskmgr_setexcltask,
|
||||
isc__taskmgr_excltask
|
||||
};
|
||||
|
||||
/***
|
||||
@ -1411,6 +1418,7 @@ isc__taskmgr_create(isc_mem_t *mctx, unsigned int workers,
|
||||
manager->exclusive_requested = ISC_FALSE;
|
||||
manager->pause_requested = ISC_FALSE;
|
||||
manager->exiting = ISC_FALSE;
|
||||
manager->excl = NULL;
|
||||
|
||||
isc_mem_attach(mctx, &manager->mctx);
|
||||
|
||||
@ -1494,6 +1502,12 @@ isc__taskmgr_destroy(isc_taskmgr_t **managerp) {
|
||||
* that the startup thread is sleeping on.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Detach the exclusive task before acquiring the manager lock
|
||||
*/
|
||||
if (manager->excl != NULL)
|
||||
isc__task_detach((isc_task_t **) &manager->excl);
|
||||
|
||||
/*
|
||||
* Unlike elsewhere, we're going to hold this lock a long time.
|
||||
* We need to do so, because otherwise the list of tasks could
|
||||
@ -1644,12 +1658,41 @@ isc__taskmgr_resume(isc_taskmgr_t *manager0) {
|
||||
}
|
||||
#endif /* USE_WORKER_THREADS */
|
||||
|
||||
ISC_TASKFUNC_SCOPE void
|
||||
isc__taskmgr_setexcltask(isc_taskmgr_t *mgr0, isc_task_t *task0) {
|
||||
isc__taskmgr_t *mgr = (isc__taskmgr_t *) mgr0;
|
||||
isc__task_t *task = (isc__task_t *) task0;
|
||||
|
||||
REQUIRE(VALID_MANAGER(mgr));
|
||||
REQUIRE(VALID_TASK(task));
|
||||
if (mgr->excl != NULL)
|
||||
isc__task_detach((isc_task_t **) &mgr->excl);
|
||||
isc__task_attach(task0, (isc_task_t **) &mgr->excl);
|
||||
}
|
||||
|
||||
ISC_TASKFUNC_SCOPE isc_result_t
|
||||
isc__taskmgr_excltask(isc_taskmgr_t *mgr0, isc_task_t **taskp) {
|
||||
isc__taskmgr_t *mgr = (isc__taskmgr_t *) mgr0;
|
||||
|
||||
REQUIRE(VALID_MANAGER(mgr));
|
||||
REQUIRE(taskp != NULL && *taskp == NULL);
|
||||
|
||||
if (mgr->excl == NULL)
|
||||
return (ISC_R_NOTFOUND);
|
||||
|
||||
isc__task_attach((isc_task_t *) mgr->excl, taskp);
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
ISC_TASKFUNC_SCOPE isc_result_t
|
||||
isc__task_beginexclusive(isc_task_t *task0) {
|
||||
#ifdef USE_WORKER_THREADS
|
||||
isc__task_t *task = (isc__task_t *)task0;
|
||||
isc__taskmgr_t *manager = task->manager;
|
||||
|
||||
REQUIRE(task->state == task_state_running);
|
||||
/* XXX: Require task == manager->excl? */
|
||||
|
||||
LOCK(&manager->lock);
|
||||
if (manager->exclusive_requested) {
|
||||
UNLOCK(&manager->lock);
|
||||
|
@ -201,6 +201,17 @@ isc_task_purge(isc_task_t *task, void *sender, isc_eventtype_t type, void *tag)
|
||||
return (task->methods->purgeevents(task, sender, type, tag));
|
||||
}
|
||||
|
||||
void
|
||||
isc_taskmgr_setexcltask(isc_taskmgr_t *mgr, isc_task_t *task) {
|
||||
REQUIRE(ISCAPI_TASK_VALID(task));
|
||||
return (mgr->methods->setexcltask(mgr, task));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_taskmgr_excltask(isc_taskmgr_t *mgr, isc_task_t **taskp) {
|
||||
return (mgr->methods->excltask(mgr, taskp));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_task_beginexclusive(isc_task_t *task) {
|
||||
REQUIRE(ISCAPI_TASK_VALID(task));
|
||||
|
@ -42,6 +42,7 @@ isc_log_t *lctx = NULL;
|
||||
isc_taskmgr_t *taskmgr = NULL;
|
||||
isc_timermgr_t *timermgr = NULL;
|
||||
isc_socketmgr_t *socketmgr = NULL;
|
||||
isc_task_t *maintask = NULL;
|
||||
int ncpus;
|
||||
|
||||
static isc_boolean_t hash_active = ISC_FALSE;
|
||||
@ -63,6 +64,8 @@ static isc_logcategory_t categories[] = {
|
||||
|
||||
static void
|
||||
cleanup_managers() {
|
||||
if (maintask != NULL)
|
||||
isc_task_destroy(&maintask);
|
||||
if (socketmgr != NULL)
|
||||
isc_socketmgr_destroy(&socketmgr);
|
||||
if (taskmgr != NULL)
|
||||
@ -81,6 +84,9 @@ create_managers() {
|
||||
#endif
|
||||
|
||||
CHECK(isc_taskmgr_create(mctx, ncpus, 0, &taskmgr));
|
||||
CHECK(isc_task_create(taskmgr, 0, &maintask));
|
||||
isc_taskmgr_setexcltask(taskmgr, maintask);
|
||||
|
||||
CHECK(isc_timermgr_create(mctx, &timermgr));
|
||||
CHECK(isc_socketmgr_create(mctx, &socketmgr));
|
||||
return (ISC_R_SUCCESS);
|
||||
@ -138,6 +144,8 @@ isc_test_begin(FILE *logfile, isc_boolean_t start_managers) {
|
||||
|
||||
void
|
||||
isc_test_end() {
|
||||
if (maintask != NULL)
|
||||
isc_task_detach(&maintask);
|
||||
if (taskmgr != NULL)
|
||||
isc_taskmgr_destroy(&taskmgr);
|
||||
if (lctx != NULL)
|
||||
|
@ -140,7 +140,9 @@ isc__task_unsend
|
||||
isc__task_unsendrange
|
||||
isc__taskmgr_create
|
||||
isc__taskmgr_destroy
|
||||
isc__taskmgr_excltask
|
||||
isc__taskmgr_mode
|
||||
isc__taskmgr_setexcltask
|
||||
isc__taskmgr_setmode
|
||||
isc__timer_attach
|
||||
isc__timer_create
|
||||
@ -219,9 +221,9 @@ isc_event_free
|
||||
isc_file_absolutepath
|
||||
isc_file_basename
|
||||
isc_file_exists
|
||||
isc_file_getmodtime
|
||||
isc_file_getsize
|
||||
isc_file_getsizefd
|
||||
isc_file_getmodtime
|
||||
isc_file_isabsolute
|
||||
isc_file_ischdiridempotent
|
||||
isc_file_iscurrentdir
|
||||
|
Loading…
x
Reference in New Issue
Block a user