1 /*
2 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3 *
4 * SPDX-License-Identifier: MPL-2.0
5 *
6 * This Source Code Form is subject to the terms of the Mozilla Public
7 * License, v. 2.0. If a copy of the MPL was not distributed with this
8 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
9 *
10 * See the COPYRIGHT file distributed with this work for additional
11 * information regarding copyright ownership.
12 */
13
14 #include <stdlib.h>
15 #include <unistd.h>
16
17 #include <isc/managers.h>
18 #include <isc/mem.h>
19 #include <isc/print.h>
20 #include <isc/task.h>
21 #include <isc/time.h>
22 #include <isc/timer.h>
23 #include <isc/util.h>
24
25 isc_mem_t *mctx = NULL;
26
27 static void
my_callback(isc_task_t * task,isc_event_t * event)28 my_callback(isc_task_t *task, isc_event_t *event) {
29 int i, j;
30 char *name = event->ev_arg;
31
32 j = 0;
33 for (i = 0; i < 1000000; i++) {
34 j += 100;
35 }
36 printf("task %s (%p): %d\n", name, task, j);
37 isc_event_free(&event);
38 }
39
40 static void
my_shutdown(isc_task_t * task,isc_event_t * event)41 my_shutdown(isc_task_t *task, isc_event_t *event) {
42 char *name = event->ev_arg;
43
44 printf("shutdown %s (%p)\n", name, task);
45 isc_event_free(&event);
46 }
47
48 static void
my_tick(isc_task_t * task,isc_event_t * event)49 my_tick(isc_task_t *task, isc_event_t *event) {
50 char *name = event->ev_arg;
51
52 printf("task %p tick %s\n", task, name);
53 isc_event_free(&event);
54 }
55
56 static char one[] = "1";
57 static char two[] = "2";
58 static char three[] = "3";
59 static char four[] = "4";
60 static char foo[] = "foo";
61 static char bar[] = "bar";
62
63 int
main(int argc,char * argv[])64 main(int argc, char *argv[]) {
65 isc_nm_t *netmgr = NULL;
66 isc_taskmgr_t *taskmgr = NULL;
67 isc_task_t *t1 = NULL, *t2 = NULL;
68 isc_task_t *t3 = NULL, *t4 = NULL;
69 isc_event_t *event;
70 unsigned int workers;
71 isc_timermgr_t *timgr;
72 isc_timer_t *ti1, *ti2;
73 struct isc_interval interval;
74
75 if (argc > 1) {
76 workers = atoi(argv[1]);
77 if (workers < 1) {
78 workers = 1;
79 }
80 if (workers > 8192) {
81 workers = 8192;
82 }
83 } else {
84 workers = 2;
85 }
86 printf("%u workers\n", workers);
87
88 isc_mem_create(&mctx);
89
90 RUNTIME_CHECK(isc_managers_create(mctx, workers, 0, &netmgr,
91 &taskmgr) == ISC_R_SUCCESS);
92
93 RUNTIME_CHECK(isc_task_create(taskmgr, 0, &t1) == ISC_R_SUCCESS);
94 RUNTIME_CHECK(isc_task_create(taskmgr, 0, &t2) == ISC_R_SUCCESS);
95 RUNTIME_CHECK(isc_task_create(taskmgr, 0, &t3) == ISC_R_SUCCESS);
96 RUNTIME_CHECK(isc_task_create(taskmgr, 0, &t4) == ISC_R_SUCCESS);
97
98 RUNTIME_CHECK(isc_task_onshutdown(t1, my_shutdown, one) ==
99 ISC_R_SUCCESS);
100 RUNTIME_CHECK(isc_task_onshutdown(t2, my_shutdown, two) ==
101 ISC_R_SUCCESS);
102 RUNTIME_CHECK(isc_task_onshutdown(t3, my_shutdown, three) ==
103 ISC_R_SUCCESS);
104 RUNTIME_CHECK(isc_task_onshutdown(t4, my_shutdown, four) ==
105 ISC_R_SUCCESS);
106
107 timgr = NULL;
108 RUNTIME_CHECK(isc_timermgr_create(mctx, &timgr) == ISC_R_SUCCESS);
109 ti1 = NULL;
110
111 isc_interval_set(&interval, 1, 0);
112 RUNTIME_CHECK(isc_timer_create(timgr, isc_timertype_ticker, NULL,
113 &interval, t1, my_tick, foo,
114 &ti1) == ISC_R_SUCCESS);
115
116 ti2 = NULL;
117 isc_interval_set(&interval, 1, 0);
118 RUNTIME_CHECK(isc_timer_create(timgr, isc_timertype_ticker, NULL,
119 &interval, t2, my_tick, bar,
120 &ti2) == ISC_R_SUCCESS);
121
122 printf("task 1 = %p\n", t1);
123 printf("task 2 = %p\n", t2);
124 #ifndef WIN32
125 sleep(2);
126 #else /* ifndef WIN32 */
127 Sleep(2000);
128 #endif /* ifndef WIN32 */
129
130 /*
131 * Note: (void *)1 is used as a sender here, since some compilers
132 * don't like casting a function pointer to a (void *).
133 *
134 * In a real use, it is more likely the sender would be a
135 * structure (socket, timer, task, etc) but this is just a test
136 * program.
137 */
138 event = isc_event_allocate(mctx, (void *)1, 1, my_callback, one,
139 sizeof(*event));
140 isc_task_send(t1, &event);
141 event = isc_event_allocate(mctx, (void *)1, 1, my_callback, one,
142 sizeof(*event));
143 isc_task_send(t1, &event);
144 event = isc_event_allocate(mctx, (void *)1, 1, my_callback, one,
145 sizeof(*event));
146 isc_task_send(t1, &event);
147 event = isc_event_allocate(mctx, (void *)1, 1, my_callback, one,
148 sizeof(*event));
149 isc_task_send(t1, &event);
150 event = isc_event_allocate(mctx, (void *)1, 1, my_callback, one,
151 sizeof(*event));
152 isc_task_send(t1, &event);
153 event = isc_event_allocate(mctx, (void *)1, 1, my_callback, one,
154 sizeof(*event));
155 isc_task_send(t1, &event);
156 event = isc_event_allocate(mctx, (void *)1, 1, my_callback, one,
157 sizeof(*event));
158 isc_task_send(t1, &event);
159 event = isc_event_allocate(mctx, (void *)1, 1, my_callback, one,
160 sizeof(*event));
161 isc_task_send(t1, &event);
162 event = isc_event_allocate(mctx, (void *)1, 1, my_callback, one,
163 sizeof(*event));
164 isc_task_send(t1, &event);
165 event = isc_event_allocate(mctx, (void *)1, 1, my_callback, two,
166 sizeof(*event));
167 isc_task_send(t2, &event);
168 event = isc_event_allocate(mctx, (void *)1, 1, my_callback, three,
169 sizeof(*event));
170 isc_task_send(t3, &event);
171 event = isc_event_allocate(mctx, (void *)1, 1, my_callback, four,
172 sizeof(*event));
173 isc_task_send(t4, &event);
174 event = isc_event_allocate(mctx, (void *)1, 1, my_callback, two,
175 sizeof(*event));
176 isc_task_send(t2, &event);
177 event = isc_event_allocate(mctx, (void *)1, 1, my_callback, three,
178 sizeof(*event));
179 isc_task_send(t3, &event);
180 event = isc_event_allocate(mctx, (void *)1, 1, my_callback, four,
181 sizeof(*event));
182 isc_task_send(t4, &event);
183 isc_task_purgerange(t3, NULL, ISC_EVENTTYPE_FIRSTEVENT,
184 ISC_EVENTTYPE_LASTEVENT, NULL);
185
186 isc_task_detach(&t1);
187 isc_task_detach(&t2);
188 isc_task_detach(&t3);
189 isc_task_detach(&t4);
190
191 #ifndef WIN32
192 sleep(10);
193 #else /* ifndef WIN32 */
194 Sleep(10000);
195 #endif /* ifndef WIN32 */
196 printf("destroy\n");
197 isc_timer_detach(&ti1);
198 isc_timer_detach(&ti2);
199 isc_timermgr_destroy(&timgr);
200 isc_managers_destroy(&netmgr, &taskmgr);
201 printf("destroyed\n");
202
203 isc_mem_stats(mctx, stdout);
204 isc_mem_destroy(&mctx);
205
206 return (0);
207 }
208