1 /* $NetBSD: shutdown_test.c,v 1.7 2014/12/10 04:37:53 christos Exp $ */
4 * Copyright (C) 2004, 2007, 2011, 2013 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 1998-2001 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 /* Id: shutdown_test.c,v 1.25 2011/08/28 23:46:41 tbox Exp */
29 #include <isc/print.h>
32 #include <isc/timer.h>
41 isc_boolean_t exiting
;
46 #define T2_SHUTDOWNOK (ISC_EVENTCLASS(1024) + 0)
47 #define T2_SHUTDOWNDONE (ISC_EVENTCLASS(1024) + 1)
48 #define FOO_EVENT (ISC_EVENTCLASS(1024) + 2)
50 static t_info tasks
[MAX_TASKS
];
51 static unsigned int task_count
;
52 static isc_taskmgr_t
* task_manager
;
53 static isc_timermgr_t
* timer_manager
;
56 t1_shutdown(isc_task_t
*task
, isc_event_t
*event
) {
57 t_info
*info
= event
->ev_arg
;
59 printf("task %s (%p) t1_shutdown\n", info
->name
, task
);
60 isc_task_detach(&info
->task
);
61 isc_event_free(&event
);
65 t2_shutdown(isc_task_t
*task
, isc_event_t
*event
) {
66 t_info
*info
= event
->ev_arg
;
68 printf("task %s (%p) t2_shutdown\n", info
->name
, task
);
69 info
->exiting
= ISC_TRUE
;
70 isc_event_free(&event
);
74 shutdown_action(isc_task_t
*task
, isc_event_t
*event
) {
75 t_info
*info
= event
->ev_arg
;
78 INSIST(event
->ev_type
== ISC_TASKEVENT_SHUTDOWN
);
80 printf("task %s (%p) shutdown\n", info
->name
, task
);
81 if (strcmp(info
->name
, "0") == 0) {
82 isc_timer_detach(&info
->timer
);
83 nevent
= isc_event_allocate(info
->mctx
, info
, T2_SHUTDOWNOK
,
84 t2_shutdown
, &tasks
[1],
86 RUNTIME_CHECK(nevent
!= NULL
);
87 info
->exiting
= ISC_TRUE
;
88 isc_task_sendanddetach(&info
->peer
, &nevent
);
90 isc_event_free(&event
);
94 foo_event(isc_task_t
*task
, isc_event_t
*event
) {
95 printf("task(%p) foo\n", task
);
96 isc_event_free(&event
);
100 tick(isc_task_t
*task
, isc_event_t
*event
) {
101 t_info
*info
= event
->ev_arg
;
104 INSIST(event
->ev_type
== ISC_TIMEREVENT_TICK
);
106 printf("task %s (%p) tick\n", info
->name
, task
);
109 if (strcmp(info
->name
, "1") == 0) {
110 if (info
->ticks
== 10) {
111 RUNTIME_CHECK(isc_app_shutdown() == ISC_R_SUCCESS
);
112 } else if (info
->ticks
>= 15 && info
->exiting
) {
113 isc_timer_detach(&info
->timer
);
114 isc_task_detach(&info
->task
);
115 nevent
= isc_event_allocate(info
->mctx
, info
,
117 t1_shutdown
, &tasks
[0],
119 RUNTIME_CHECK(nevent
!= NULL
);
120 isc_task_send(info
->peer
, &nevent
);
121 isc_task_detach(&info
->peer
);
123 } else if (strcmp(info
->name
, "foo") == 0) {
124 isc_timer_detach(&info
->timer
);
125 nevent
= isc_event_allocate(info
->mctx
, info
,
129 RUNTIME_CHECK(nevent
!= NULL
);
130 isc_task_sendanddetach(&task
, &nevent
);
133 isc_event_free(&event
);
137 new_task(isc_mem_t
*mctx
, const char *name
) {
140 isc_interval_t interval
;
142 RUNTIME_CHECK(task_count
< MAX_TASKS
);
143 ti
= &tasks
[task_count
];
149 INSIST(strlen(name
) < sizeof(ti
->name
));
150 strcpy(ti
->name
, name
);
152 sprintf(ti
->name
, "%d", task_count
);
153 RUNTIME_CHECK(isc_task_create(task_manager
, 0, &ti
->task
) ==
155 RUNTIME_CHECK(isc_task_onshutdown(ti
->task
, shutdown_action
, ti
) ==
158 isc_time_settoepoch(&expires
);
159 isc_interval_set(&interval
, 1, 0);
160 RUNTIME_CHECK(isc_timer_create(timer_manager
, isc_timertype_ticker
,
161 &expires
, &interval
, ti
->task
,
162 tick
, ti
, &ti
->timer
) ==
171 main(int argc
, char *argv
[]) {
172 unsigned int workers
;
175 isc_mem_t
*mctx
, *mctx2
;
177 RUNTIME_CHECK(isc_app_start() == ISC_R_SUCCESS
);
180 workers
= atoi(argv
[1]);
187 printf("%d workers\n", workers
);
190 RUNTIME_CHECK(isc_mem_create(0, 0, &mctx
) == ISC_R_SUCCESS
);
192 RUNTIME_CHECK(isc_mem_create(0, 0, &mctx2
) == ISC_R_SUCCESS
);
193 RUNTIME_CHECK(isc_taskmgr_create(mctx
, workers
, 0, &task_manager
) ==
195 RUNTIME_CHECK(isc_timermgr_create(mctx
, &timer_manager
) ==
198 t1
= new_task(mctx
, NULL
);
199 t2
= new_task(mctx2
, NULL
);
200 isc_task_attach(t2
->task
, &t1
->peer
);
201 isc_task_attach(t1
->task
, &t2
->peer
);
204 * Test run-triggered shutdown.
206 (void)new_task(mctx2
, "foo");
209 * Test implicit shutdown.
212 RUNTIME_CHECK(isc_task_create(task_manager
, 0, &task
) ==
214 isc_task_detach(&task
);
217 * Test anti-zombie code.
219 RUNTIME_CHECK(isc_task_create(task_manager
, 0, &task
) ==
221 isc_task_detach(&task
);
223 RUNTIME_CHECK(isc_app_run() == ISC_R_SUCCESS
);
225 isc_taskmgr_destroy(&task_manager
);
226 isc_timermgr_destroy(&timer_manager
);
228 printf("Statistics for mctx:\n");
229 isc_mem_stats(mctx
, stdout
);
230 isc_mem_destroy(&mctx
);
231 printf("Statistics for mctx2:\n");
232 isc_mem_stats(mctx2
, stdout
);
233 isc_mem_destroy(&mctx2
);