2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-29 21:47:59 +00:00

Remove isc_task_onshutdown()

The isc_task_onshutdown() was used to post event that should be run when
the task is being shutdown.  This could happen explicitly in the
isc_test_shutdown() call or implicitly when we detach the last reference
to the task and there are no more events posted on the task.

This whole task onshutdown mechanism just makes things more complicated,
and it's easier to post the "shutdown" events when we are shutting down
explicitly and the existing code already always knows when it should
shutdown the task that's being used to execute the onshutdown events.

Replace the isc_task_onshutdown() calls with explicit calls to execute
the shutdown tasks.
This commit is contained in:
Ondřej Surý 2022-05-09 11:33:09 +02:00
parent 8fbb75e457
commit 2235edabcf
12 changed files with 80 additions and 446 deletions

View File

@ -37,11 +37,12 @@
#include <named/types.h>
#define NAMED_EVENTCLASS ISC_EVENTCLASS(0x4E43)
#define NAMED_EVENT_RELOAD (NAMED_EVENTCLASS + 0)
#define NAMED_EVENT_DELZONE (NAMED_EVENTCLASS + 1)
#define NAMED_EVENT_COMMAND (NAMED_EVENTCLASS + 2)
#define NAMED_EVENT_TATSEND (NAMED_EVENTCLASS + 3)
#define NAMED_EVENTCLASS ISC_EVENTCLASS(0x4E43)
#define NAMED_EVENT_RELOAD (NAMED_EVENTCLASS + 0)
#define NAMED_EVENT_DELZONE (NAMED_EVENTCLASS + 1)
#define NAMED_EVENT_COMMAND (NAMED_EVENTCLASS + 2)
#define NAMED_EVENT_TATSEND (NAMED_EVENTCLASS + 3)
#define NAMED_EVENT_SHUTDOWN (NAMED_EVENTCLASS + 4)
/*%
* Name server state. Better here than in lots of separate global variables.
@ -134,6 +135,12 @@ named_server_destroy(named_server_t **serverp);
* Destroy a server object, freeing its memory.
*/
void
named_server_shutdown(named_server_t *server);
/*%<
* Initiate the server shutdown.
*/
void
named_server_reloadwanted(named_server_t *server);
/*%<

View File

@ -1258,6 +1258,8 @@ setup(void) {
static void
cleanup(void) {
named_server_shutdown(named_g_server);
destroy_managers();
if (named_g_mapped != NULL) {

View File

@ -9963,6 +9963,14 @@ shutdown_server(isc_task_t *task, isc_event_t *event) {
isc_event_free(&event);
}
void
named_server_shutdown(named_server_t *server) {
isc_event_t *event =
isc_event_allocate(named_g_mctx, server, NAMED_EVENT_SHUTDOWN,
shutdown_server, server, sizeof(*event));
isc_task_send(server->task, &event);
}
/*%
* Find a view that matches the source and destination addresses of a query.
*/
@ -10069,8 +10077,6 @@ named_server_create(isc_mem_t *mctx, named_server_t **serverp) {
server->sctx->fuzznotify = named_fuzz_notify;
#endif /* ifdef ENABLE_AFL */
CHECKFATAL(isc_task_onshutdown(server->task, shutdown_server, server),
"isc_task_onshutdown");
CHECKFATAL(
isc_app_onrun(named_g_mctx, server->task, run_server, server),
"isc_app_onrun");

View File

@ -752,12 +752,8 @@ maybeshutdown(void) {
}
static void
shutdown_program(isc_task_t *task, isc_event_t *event) {
REQUIRE(task == global_task);
UNUSED(task);
shutdown_program(void) {
ddebug("shutdown_program()");
isc_event_free(&event);
shuttingdown = true;
maybeshutdown();
@ -918,9 +914,6 @@ setup_system(void) {
result = isc_task_create(taskmgr, 0, &global_task);
check_result(result, "isc_task_create");
result = isc_task_onshutdown(global_task, shutdown_program, NULL);
check_result(result, "isc_task_onshutdown");
result = dst_lib_init(gmctx, NULL);
check_result(result, "dst_lib_init");
is_dst_up = true;
@ -3412,6 +3405,8 @@ main(int argc, char **argv) {
(void)isc_app_run();
shutdown_program();
cleanup();
isc_app_finish();

View File

@ -16,13 +16,8 @@ and termination model. Here's how things now work:
When a task is shutdown:
Any "on shutdown" events for the task are posted
The "shutting down" attribute of the task is set
Any attempts to add shutdown events with isc_task_onshutdown()
will fail, since the task is already shutting down
Task shutdown can be initiated explicitly, via a call to isc_task_shutdown(),
or implicitly, when the following conditions occur:
@ -32,7 +27,6 @@ or implicitly, when the following conditions occur:
The task has an empty event queue
Task termination occurs when:
The "shutting down" attribute of the task is set

View File

@ -410,6 +410,12 @@ dns_cache_detach(dns_cache_t **cachep) {
* If the cleaner task exists, let it free the cache.
*/
if (isc_refcount_decrement(&cache->live_tasks) > 1) {
isc_event_t *event = isc_event_allocate(
cache->mctx, &cache->cleaner,
DNS_EVENT_CACHESHUTDOWN,
cleaner_shutdown_action, &cache->cleaner,
sizeof(*event));
isc_task_send(cache->cleaner.task, &event);
isc_task_shutdown(cache->cleaner.task);
} else {
cache_free(cache);
@ -476,17 +482,6 @@ cache_cleaner_init(dns_cache_t *cache, isc_taskmgr_t *taskmgr,
isc_refcount_increment(&cleaner->cache->live_tasks);
isc_task_setname(cleaner->task, "cachecleaner", cleaner);
result = isc_task_onshutdown(cleaner->task,
cleaner_shutdown_action, cache);
if (result != ISC_R_SUCCESS) {
isc_refcount_decrement0(&cleaner->cache->live_tasks);
UNEXPECTED_ERROR(__FILE__, __LINE__,
"cache cleaner: "
"isc_task_onshutdown() failed: %s",
isc_result_totext(result));
goto cleanup;
}
cleaner->resched_event = isc_event_allocate(
cache->mctx, cleaner, DNS_EVENT_CACHECLEAN,
incremental_cleaning_action, cleaner,

View File

@ -82,3 +82,4 @@
#define DNS_EVENT_TRYSTALE (ISC_EVENTCLASS_DNS + 59)
#define DNS_EVENT_ZONEFLUSH (ISC_EVENTCLASS_DNS + 60)
#define DNS_EVENT_CHECKDSSENDTOADDR (ISC_EVENTCLASS_DNS + 61)
#define DNS_EVENT_CACHESHUTDOWN (ISC_EVENTCLASS_DNS + 62)

View File

@ -266,35 +266,6 @@ isc_task_purgeevent(isc_task_t *task, isc_event_t *event);
* or was marked unpurgeable.
*/
isc_result_t
isc_task_onshutdown(isc_task_t *task, isc_taskaction_t action, void *arg);
/*%<
* Send a shutdown event with action 'action' and argument 'arg' when
* 'task' is shutdown.
*
* Notes:
*
*\li Shutdown events are posted in LIFO order.
*
* Requires:
*
*\li 'task' is a valid task.
*
*\li 'action' is a valid task action.
*
* Ensures:
*
*\li When the task is shutdown, shutdown events requested with
* isc_task_onshutdown() will be appended to the task's event queue.
*
*
* Returns:
*
*\li #ISC_R_SUCCESS
*\li #ISC_R_NOMEMORY
*\li #ISC_R_SHUTTINGDOWN Task is shutting down.
*/
void
isc_task_shutdown(isc_task_t *task);
/*%<
@ -302,10 +273,7 @@ isc_task_shutdown(isc_task_t *task);
*
* Notes:
*
*\li Shutting down a task causes any shutdown events requested with
* isc_task_onshutdown() to be posted (in LIFO order). The task
* moves into a "shutting down" mode which prevents further calls
* to isc_task_onshutdown().
*\li The task moves into a "shutting down" mode.
*
*\li Trying to shutdown a task that has already been shutdown has no
* effect.
@ -314,10 +282,6 @@ isc_task_shutdown(isc_task_t *task);
*
*\li 'task' is a valid task.
*
* Ensures:
*
*\li Any shutdown events requested with isc_task_onshutdown() have been
* posted (in LIFO order).
*/
void

View File

@ -113,7 +113,6 @@ struct isc_task {
isc_refcount_t references;
isc_refcount_t running;
isc_eventlist_t events;
isc_eventlist_t on_shutdown;
unsigned int nevents;
unsigned int quantum;
isc_stdtime_t now;
@ -183,7 +182,6 @@ task_finished(isc_task_t *task) {
isc_mem_t *mctx = manager->mctx;
REQUIRE(EMPTY(task->events));
REQUIRE(task->nevents == 0);
REQUIRE(EMPTY(task->on_shutdown));
REQUIRE(task->state == task_state_done);
XTRACE("task_finished");
@ -249,7 +247,6 @@ isc__task_create_bound(isc_taskmgr_t *manager, unsigned int quantum,
isc_refcount_init(&task->references, 1);
isc_refcount_init(&task->running, 0);
INIT_LIST(task->events);
INIT_LIST(task->on_shutdown);
task->nevents = 0;
task->quantum = (quantum > 0) ? quantum : manager->default_quantum;
atomic_init(&task->shuttingdown, false);
@ -302,7 +299,6 @@ isc_task_attach(isc_task_t *source, isc_task_t **targetp) {
static bool
task_shutdown(isc_task_t *task) {
bool was_idle = false;
isc_event_t *event, *prev;
/*
* Caller must be holding the task's lock.
@ -320,17 +316,6 @@ task_shutdown(isc_task_t *task) {
}
INSIST(task->state == task_state_ready ||
task->state == task_state_running);
/*
* Note that we post shutdown events LIFO.
*/
for (event = TAIL(task->on_shutdown); event != NULL;
event = prev) {
prev = PREV(event, ev_link);
DEQUEUE(task->on_shutdown, event, ev_link);
ENQUEUE(task->events, event, ev_link);
task->nevents++;
}
}
return (was_idle);
@ -562,40 +547,6 @@ isc_task_purgeevent(isc_task_t *task, isc_event_t *event) {
return (true);
}
isc_result_t
isc_task_onshutdown(isc_task_t *task, isc_taskaction_t action, void *arg) {
bool disallowed = false;
isc_result_t result = ISC_R_SUCCESS;
isc_event_t *event;
/*
* Send a shutdown event with action 'action' and argument 'arg' when
* 'task' is shutdown.
*/
REQUIRE(VALID_TASK(task));
REQUIRE(action != NULL);
event = isc_event_allocate(task->manager->mctx, NULL,
ISC_TASKEVENT_SHUTDOWN, action, arg,
sizeof(*event));
if (TASK_SHUTTINGDOWN(task)) {
disallowed = true;
result = ISC_R_SHUTTINGDOWN;
} else {
LOCK(&task->lock);
ENQUEUE(task->on_shutdown, event, ev_link);
UNLOCK(&task->lock);
}
if (disallowed) {
isc_mem_put(task->manager->mctx, event, sizeof(*event));
}
return (result);
}
void
isc_task_shutdown(isc_task_t *task) {
bool was_idle;

View File

@ -205,17 +205,6 @@ basic_cb(isc_task_t *task, isc_event_t *event) {
isc_event_free(&event);
}
static void
basic_shutdown(isc_task_t *task, isc_event_t *event) {
UNUSED(task);
if (verbose) {
print_message("# shutdown %s\n", (char *)event->ev_arg);
}
isc_event_free(&event);
}
static void
basic_tick(isc_task_t *task, isc_event_t *event) {
UNUSED(task);
@ -260,15 +249,6 @@ basic(void **state) {
result = isc_task_create(taskmgr, 0, &task4);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_task_onshutdown(task1, basic_shutdown, one);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_task_onshutdown(task2, basic_shutdown, two);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_task_onshutdown(task3, basic_shutdown, three);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_task_onshutdown(task4, basic_shutdown, four);
assert_int_equal(result, ISC_R_SUCCESS);
isc_interval_set(&interval, 1, 0);
isc_timer_create(timermgr, task1, basic_tick, tick, &ti1);
result = isc_timer_reset(ti1, isc_timertype_ticker, &interval, false);
@ -421,53 +401,39 @@ task_exclusive(void **state) {
* Max tasks test:
* The task system can create and execute many tasks. Tests with 10000.
*/
static void
maxtask_shutdown(isc_task_t *task, isc_event_t *event) {
UNUSED(task);
if (event->ev_arg != NULL) {
isc_task_destroy((isc_task_t **)&event->ev_arg);
static void
maxtask_cb(isc_task_t *task, isc_event_t *event) {
isc_result_t result;
uintptr_t ntasks = (uintptr_t)event->ev_arg;
if (ntasks-- > 0) {
task = NULL;
event->ev_arg = (void *)ntasks;
/*
* Create a new task and forward the message.
*/
result = isc_task_create(taskmgr, 0, &task);
assert_int_equal(result, ISC_R_SUCCESS);
isc_task_send(task, &event);
isc_task_detach(&task);
} else {
isc_event_free(&event);
LOCK(&lock);
atomic_store(&done, true);
SIGNAL(&cv);
UNLOCK(&lock);
}
isc_event_free(&event);
}
static void
maxtask_cb(isc_task_t *task, isc_event_t *event) {
isc_result_t result;
if (event->ev_arg != NULL) {
isc_task_t *newtask = NULL;
event->ev_arg = (void *)(((uintptr_t)event->ev_arg) - 1);
/*
* Create a new task and forward the message.
*/
result = isc_task_create(taskmgr, 0, &newtask);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_task_onshutdown(newtask, maxtask_shutdown,
(void *)task);
assert_int_equal(result, ISC_R_SUCCESS);
isc_task_send(newtask, &event);
} else if (task != NULL) {
isc_task_destroy(&task);
isc_event_free(&event);
}
}
static void
manytasks(void **state) {
isc_mem_t *mctx = NULL;
isc_event_t *event = NULL;
uintptr_t ntasks = 10000;
uintptr_t ntasks = 2; /* 0000; */
UNUSED(state);
@ -479,14 +445,9 @@ manytasks(void **state) {
isc_mutex_init(&lock);
isc_condition_init(&cv);
isc_mem_debugging = ISC_MEM_DEBUGRECORD;
isc_mem_create(&mctx);
isc_managers_create(mctx, 4, 0, &netmgr, &taskmgr, NULL);
atomic_init(&done, false);
event = isc_event_allocate(mctx, (void *)1, 1, maxtask_cb,
event = isc_event_allocate(test_mctx, NULL, 1, maxtask_cb,
(void *)ntasks, sizeof(*event));
assert_non_null(event);
@ -497,221 +458,10 @@ manytasks(void **state) {
}
UNLOCK(&lock);
isc_managers_destroy(&netmgr, &taskmgr, NULL);
isc_mem_destroy(&mctx);
isc_condition_destroy(&cv);
isc_mutex_destroy(&lock);
}
/*
* Shutdown test:
* When isc_task_shutdown() is called, shutdown events are posted
* in LIFO order.
*/
static int nevents = 0;
static int nsdevents = 0;
static int senders[4];
atomic_bool ready, all_done;
static void
sd_sde1(isc_task_t *task, isc_event_t *event) {
UNUSED(task);
assert_int_equal(nevents, 256);
assert_int_equal(nsdevents, 1);
++nsdevents;
if (verbose) {
print_message("# shutdown 1\n");
}
isc_event_free(&event);
atomic_store(&all_done, true);
}
static void
sd_sde2(isc_task_t *task, isc_event_t *event) {
UNUSED(task);
assert_int_equal(nevents, 256);
assert_int_equal(nsdevents, 0);
++nsdevents;
if (verbose) {
print_message("# shutdown 2\n");
}
isc_event_free(&event);
}
static void
sd_event1(isc_task_t *task, isc_event_t *event) {
UNUSED(task);
LOCK(&lock);
while (!atomic_load(&ready)) {
WAIT(&cv, &lock);
}
UNLOCK(&lock);
if (verbose) {
print_message("# event 1\n");
}
isc_event_free(&event);
}
static void
sd_event2(isc_task_t *task, isc_event_t *event) {
UNUSED(task);
++nevents;
if (verbose) {
print_message("# event 2\n");
}
isc_event_free(&event);
}
static void
task_shutdown(void **state) {
isc_result_t result;
isc_eventtype_t event_type;
isc_event_t *event = NULL;
isc_task_t *task = NULL;
int i;
UNUSED(state);
nevents = nsdevents = 0;
event_type = 3;
atomic_init(&ready, false);
atomic_init(&all_done, false);
LOCK(&lock);
result = isc_task_create(taskmgr, 0, &task);
assert_int_equal(result, ISC_R_SUCCESS);
/*
* This event causes the task to wait on cv.
*/
event = isc_event_allocate(test_mctx, &senders[1], event_type,
sd_event1, NULL, sizeof(*event));
assert_non_null(event);
isc_task_send(task, &event);
/*
* Now we fill up the task's event queue with some events.
*/
for (i = 0; i < 256; ++i) {
event = isc_event_allocate(test_mctx, &senders[1], event_type,
sd_event2, NULL, sizeof(*event));
assert_non_null(event);
isc_task_send(task, &event);
}
/*
* Now we register two shutdown events.
*/
result = isc_task_onshutdown(task, sd_sde1, NULL);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_task_onshutdown(task, sd_sde2, NULL);
assert_int_equal(result, ISC_R_SUCCESS);
isc_task_shutdown(task);
isc_task_detach(&task);
/*
* Now we free the task by signaling cv.
*/
atomic_store(&ready, true);
SIGNAL(&cv);
UNLOCK(&lock);
while (!atomic_load(&all_done)) {
isc_test_nap(1000);
}
assert_int_equal(nsdevents, 2);
}
/*
* Post-shutdown test:
* After isc_task_shutdown() has been called, any call to
* isc_task_onshutdown() will return ISC_R_SHUTTINGDOWN.
*/
static void
psd_event1(isc_task_t *task, isc_event_t *event) {
UNUSED(task);
LOCK(&lock);
while (!atomic_load(&done)) {
WAIT(&cv, &lock);
}
UNLOCK(&lock);
isc_event_free(&event);
}
static void
psd_sde(isc_task_t *task, isc_event_t *event) {
UNUSED(task);
isc_event_free(&event);
}
static void
post_shutdown(void **state) {
isc_result_t result;
isc_eventtype_t event_type;
isc_event_t *event;
isc_task_t *task;
UNUSED(state);
atomic_init(&done, false);
event_type = 4;
isc_condition_init(&cv);
LOCK(&lock);
task = NULL;
result = isc_task_create(taskmgr, 0, &task);
assert_int_equal(result, ISC_R_SUCCESS);
/*
* This event causes the task to wait on cv.
*/
event = isc_event_allocate(test_mctx, &senders[1], event_type,
psd_event1, NULL, sizeof(*event));
assert_non_null(event);
isc_task_send(task, &event);
isc_task_shutdown(task);
result = isc_task_onshutdown(task, psd_sde, NULL);
assert_int_equal(result, ISC_R_SHUTTINGDOWN);
/*
* Release the task.
*/
atomic_store(&done, true);
SIGNAL(&cv);
UNLOCK(&lock);
isc_task_detach(&task);
}
/*
* Helper for the purge tests below:
*/
@ -738,6 +488,11 @@ pge_event1(isc_task_t *task, isc_event_t *event) {
}
UNLOCK(&lock);
LOCK(&lock);
atomic_store(&done, true);
SIGNAL(&cv);
UNLOCK(&lock);
isc_event_free(&event);
}
@ -749,18 +504,6 @@ pge_event2(isc_task_t *task, isc_event_t *event) {
isc_event_free(&event);
}
static void
pge_sde(isc_task_t *task, isc_event_t *event) {
UNUSED(task);
LOCK(&lock);
atomic_store(&done, true);
SIGNAL(&cv);
UNLOCK(&lock);
isc_event_free(&event);
}
static void
try_purgeevent(void) {
isc_result_t result;
@ -781,9 +524,6 @@ try_purgeevent(void) {
result = isc_task_create(taskmgr, 0, &task);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_task_onshutdown(task, pge_sde, NULL);
assert_int_equal(result, ISC_R_SUCCESS);
/*
* Block the task on cv.
*/
@ -847,15 +587,11 @@ purgeevent(void **state) {
int
main(int argc, char **argv) {
const struct CMUnitTest tests[] = {
cmocka_unit_test(manytasks),
cmocka_unit_test_setup_teardown(manytasks, _setup, _teardown),
cmocka_unit_test_setup_teardown(all_events, _setup, _teardown),
cmocka_unit_test_setup_teardown(basic, _setup2, _teardown),
cmocka_unit_test_setup_teardown(create_task, _setup, _teardown),
cmocka_unit_test_setup_teardown(post_shutdown, _setup2,
_teardown),
cmocka_unit_test_setup_teardown(purgeevent, _setup2, _teardown),
cmocka_unit_test_setup_teardown(task_shutdown, _setup4,
_teardown),
cmocka_unit_test_setup_teardown(task_exclusive, _setup4,
_teardown),
};

View File

@ -81,11 +81,9 @@ _teardown(void **state) {
}
static void
test_shutdown(isc_task_t *task, isc_event_t *event) {
test_shutdown(void) {
isc_result_t result;
UNUSED(task);
/*
* Signal shutdown processing complete.
*/
@ -97,8 +95,6 @@ test_shutdown(isc_task_t *task, isc_event_t *event) {
result = isc_mutex_unlock(&mx);
assert_int_equal(result, ISC_R_SUCCESS);
isc_event_free(&event);
}
static void
@ -121,9 +117,6 @@ setup_test(isc_timertype_t timertype, isc_interval_t *interval,
result = isc_task_create(taskmgr, 0, &task);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_task_onshutdown(task, test_shutdown, NULL);
assert_int_equal(result, ISC_R_SUCCESS);
isc_mutex_lock(&lasttime_mx);
result = isc_time_now(&lasttime);
isc_mutex_unlock(&lasttime_mx);
@ -200,6 +193,8 @@ ticktock(isc_task_t *task, isc_event_t *event) {
isc_interval_t interval;
isc_eventtype_t expected_event_type;
UNUSED(task);
int tick = atomic_fetch_add(&eventcnt, 1);
if (verbose) {
@ -247,7 +242,7 @@ ticktock(isc_task_t *task, isc_event_t *event) {
result = isc_time_now(&endtime);
subthread_assert_result_equal(result, ISC_R_SUCCESS);
isc_timer_destroy(&timer);
isc_task_shutdown(task);
test_shutdown();
}
}
@ -280,6 +275,8 @@ test_idle(isc_task_t *task, isc_event_t *event) {
isc_time_t llim;
isc_interval_t interval;
UNUSED(task);
int tick = atomic_fetch_add(&eventcnt, 1);
if (verbose) {
@ -315,7 +312,7 @@ test_idle(isc_task_t *task, isc_event_t *event) {
isc_event_free(&event);
isc_timer_destroy(&timer);
isc_task_shutdown(task);
test_shutdown();
}
/* timer type once idles out */
@ -344,6 +341,8 @@ test_reset(isc_task_t *task, isc_event_t *event) {
isc_time_t llim;
isc_interval_t interval;
UNUSED(task);
int tick = atomic_fetch_add(&eventcnt, 1);
if (verbose) {
@ -395,7 +394,7 @@ test_reset(isc_task_t *task, isc_event_t *event) {
isc_event_free(&event);
isc_timer_destroy(&timer);
isc_task_shutdown(task);
test_shutdown();
}
}
@ -458,7 +457,7 @@ tick_event(isc_task_t *task, isc_event_t *event) {
&interval, true);
subthread_assert_result_equal(result, ISC_R_SUCCESS);
isc_task_shutdown(task);
atomic_store(&shutdownflag, 1);
}
isc_event_free(&event);
@ -466,6 +465,8 @@ tick_event(isc_task_t *task, isc_event_t *event) {
static void
once_event(isc_task_t *task, isc_event_t *event) {
UNUSED(task);
if (verbose) {
print_message("# once_event\n");
}
@ -475,24 +476,6 @@ once_event(isc_task_t *task, isc_event_t *event) {
*/
atomic_store(&startflag, true);
isc_event_free(&event);
isc_task_shutdown(task);
}
static void
shutdown_purge(isc_task_t *task, isc_event_t *event) {
UNUSED(task);
UNUSED(event);
if (verbose) {
print_message("# shutdown_event\n");
}
/*
* Signal shutdown processing complete.
*/
atomic_store(&shutdownflag, 1);
isc_event_free(&event);
}
@ -513,9 +496,6 @@ purge(void **state) {
result = isc_task_create(taskmgr, 0, &task1);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_task_onshutdown(task1, shutdown_purge, NULL);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_task_create(taskmgr, 0, &task2);
assert_int_equal(result, ISC_R_SUCCESS);

View File

@ -159,6 +159,8 @@ static void
shutdown_managers(isc_task_t *task, isc_event_t *event) {
UNUSED(task);
isc_event_free(&event);
if (interfacemgr != NULL) {
ns_interfacemgr_shutdown(interfacemgr);
ns_interfacemgr_detach(&interfacemgr);
@ -170,8 +172,6 @@ shutdown_managers(isc_task_t *task, isc_event_t *event) {
atomic_store(&shutdown_done, true);
atomic_store(&run_managers, false);
isc_event_free(&event);
}
static void
@ -179,6 +179,10 @@ cleanup_managers(void) {
atomic_store(&shutdown_done, false);
if (maintask != NULL) {
isc_event_t *event = isc_event_allocate(
mctx, NULL, ISC_TASKEVENT_TEST, shutdown_managers, NULL,
sizeof(*event));
isc_task_send(maintask, &event);
isc_task_shutdown(maintask);
isc_task_destroy(&maintask);
}
@ -227,7 +231,6 @@ create_managers(void) {
isc_managers_create(mctx, ncpus, 0, &netmgr, &taskmgr, &timermgr);
CHECK(isc_task_create_bound(taskmgr, 0, &maintask, 0));
isc_taskmgr_setexcltask(taskmgr, maintask);
CHECK(isc_task_onshutdown(maintask, shutdown_managers, NULL));
CHECK(ns_server_create(mctx, matchview, &sctx));