1/*	$NetBSD$	*/
2
3/*
4 * Copyright (C) 2004, 2007  Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 1998-2001  Internet Software Consortium.
6 *
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.
10 *
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.
18 */
19
20/* Id: task_test.c,v 1.51 2007/06/19 23:46:59 tbox Exp  */
21
22#include <config.h>
23
24#include <stdlib.h>
25#include <unistd.h>
26
27#include <isc/mem.h>
28#include <isc/task.h>
29#include <isc/time.h>
30#include <isc/timer.h>
31#include <isc/util.h>
32
33isc_mem_t *mctx = NULL;
34
35static void
36my_callback(isc_task_t *task, isc_event_t *event) {
37	int i, j;
38	char *name = event->ev_arg;
39
40	j = 0;
41	for (i = 0; i < 1000000; i++)
42		j += 100;
43	printf("task %s (%p): %d\n", name, task, j);
44	isc_event_free(&event);
45}
46
47static void
48my_shutdown(isc_task_t *task, isc_event_t *event) {
49	char *name = event->ev_arg;
50
51	printf("shutdown %s (%p)\n", name, task);
52	isc_event_free(&event);
53}
54
55static void
56my_tick(isc_task_t *task, isc_event_t *event) {
57	char *name = event->ev_arg;
58
59	printf("task %p tick %s\n", task, name);
60	isc_event_free(&event);
61}
62
63int
64main(int argc, char *argv[]) {
65	isc_taskmgr_t *manager = NULL;
66	isc_task_t *t1 = NULL, *t2 = NULL;
67	isc_task_t *t3 = NULL, *t4 = NULL;
68	isc_event_t *event;
69	unsigned int workers;
70	isc_timermgr_t *timgr;
71	isc_timer_t *ti1, *ti2;
72	struct isc_interval interval;
73
74	if (argc > 1)
75		workers = atoi(argv[1]);
76	else
77		workers = 2;
78	printf("%d workers\n", workers);
79
80	RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
81
82	RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, 0, &manager) ==
83		      ISC_R_SUCCESS);
84
85	RUNTIME_CHECK(isc_task_create(manager, 0, &t1) == ISC_R_SUCCESS);
86	RUNTIME_CHECK(isc_task_create(manager, 0, &t2) == ISC_R_SUCCESS);
87	RUNTIME_CHECK(isc_task_create(manager, 0, &t3) == ISC_R_SUCCESS);
88	RUNTIME_CHECK(isc_task_create(manager, 0, &t4) == ISC_R_SUCCESS);
89
90	RUNTIME_CHECK(isc_task_onshutdown(t1, my_shutdown, "1") ==
91		      ISC_R_SUCCESS);
92	RUNTIME_CHECK(isc_task_onshutdown(t2, my_shutdown, "2") ==
93		      ISC_R_SUCCESS);
94	RUNTIME_CHECK(isc_task_onshutdown(t3, my_shutdown, "3") ==
95		      ISC_R_SUCCESS);
96	RUNTIME_CHECK(isc_task_onshutdown(t4, my_shutdown, "4") ==
97		      ISC_R_SUCCESS);
98
99	timgr = NULL;
100	RUNTIME_CHECK(isc_timermgr_create(mctx, &timgr) == ISC_R_SUCCESS);
101	ti1 = NULL;
102
103	isc_interval_set(&interval, 1, 0);
104	RUNTIME_CHECK(isc_timer_create(timgr, isc_timertype_ticker, NULL,
105				       &interval, t1, my_tick, "foo", &ti1) ==
106		      ISC_R_SUCCESS);
107
108	ti2 = NULL;
109	isc_interval_set(&interval, 1, 0);
110	RUNTIME_CHECK(isc_timer_create(timgr, isc_timertype_ticker, NULL,
111				       &interval, t2, my_tick, "bar", &ti2) ==
112		      ISC_R_SUCCESS);
113
114	printf("task 1 = %p\n", t1);
115	printf("task 2 = %p\n", t2);
116	sleep(2);
117
118	/*
119	 * Note:  (void *)1 is used as a sender here, since some compilers
120	 * don't like casting a function pointer to a (void *).
121	 *
122	 * In a real use, it is more likely the sender would be a
123	 * structure (socket, timer, task, etc) but this is just a test
124	 * program.
125	 */
126	event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "1",
127				   sizeof(*event));
128	isc_task_send(t1, &event);
129	event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "1",
130				   sizeof(*event));
131	isc_task_send(t1, &event);
132	event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "1",
133				   sizeof(*event));
134	isc_task_send(t1, &event);
135	event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "1",
136				   sizeof(*event));
137	isc_task_send(t1, &event);
138	event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "1",
139				   sizeof(*event));
140	isc_task_send(t1, &event);
141	event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "1",
142				   sizeof(*event));
143	isc_task_send(t1, &event);
144	event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "1",
145				   sizeof(*event));
146	isc_task_send(t1, &event);
147	event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "1",
148				   sizeof(*event));
149	isc_task_send(t1, &event);
150	event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "1",
151				   sizeof(*event));
152	isc_task_send(t1, &event);
153	event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "2",
154				   sizeof(*event));
155	isc_task_send(t2, &event);
156	event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "3",
157				   sizeof(*event));
158	isc_task_send(t3, &event);
159	event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "4",
160				   sizeof(*event));
161	isc_task_send(t4, &event);
162	event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "2",
163				   sizeof(*event));
164	isc_task_send(t2, &event);
165	event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "3",
166				   sizeof(*event));
167	isc_task_send(t3, &event);
168	event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "4",
169				   sizeof(*event));
170	isc_task_send(t4, &event);
171	isc_task_purgerange(t3,
172			    NULL,
173			    ISC_EVENTTYPE_FIRSTEVENT,
174			    ISC_EVENTTYPE_LASTEVENT, NULL);
175
176	isc_task_detach(&t1);
177	isc_task_detach(&t2);
178	isc_task_detach(&t3);
179	isc_task_detach(&t4);
180
181	sleep(10);
182	printf("destroy\n");
183	isc_timer_detach(&ti1);
184	isc_timer_detach(&ti2);
185	isc_timermgr_destroy(&timgr);
186	isc_taskmgr_destroy(&manager);
187	printf("destroyed\n");
188
189	isc_mem_stats(mctx, stdout);
190	isc_mem_destroy(&mctx);
191
192	return (0);
193}
194