xref: /minix3/external/bsd/bind/dist/lib/isc/tests/task_test.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: task_test.c,v 1.1.1.3 2014/12/10 03:34:44 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek  * Copyright (C) 2011, 2012  Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek  *
6*00b67f09SDavid van Moolenbroek  * Permission to use, copy, modify, and/or distribute this software for any
7*00b67f09SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
8*00b67f09SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
9*00b67f09SDavid van Moolenbroek  *
10*00b67f09SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11*00b67f09SDavid van Moolenbroek  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12*00b67f09SDavid van Moolenbroek  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13*00b67f09SDavid van Moolenbroek  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14*00b67f09SDavid van Moolenbroek  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15*00b67f09SDavid van Moolenbroek  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16*00b67f09SDavid van Moolenbroek  * PERFORMANCE OF THIS SOFTWARE.
17*00b67f09SDavid van Moolenbroek  */
18*00b67f09SDavid van Moolenbroek 
19*00b67f09SDavid van Moolenbroek /* Id */
20*00b67f09SDavid van Moolenbroek 
21*00b67f09SDavid van Moolenbroek /*! \file */
22*00b67f09SDavid van Moolenbroek 
23*00b67f09SDavid van Moolenbroek #include <config.h>
24*00b67f09SDavid van Moolenbroek 
25*00b67f09SDavid van Moolenbroek #include <atf-c.h>
26*00b67f09SDavid van Moolenbroek 
27*00b67f09SDavid van Moolenbroek #include <unistd.h>
28*00b67f09SDavid van Moolenbroek 
29*00b67f09SDavid van Moolenbroek #include <isc/task.h>
30*00b67f09SDavid van Moolenbroek #include <isc/util.h>
31*00b67f09SDavid van Moolenbroek 
32*00b67f09SDavid van Moolenbroek #include "../task_p.h"
33*00b67f09SDavid van Moolenbroek #include "isctest.h"
34*00b67f09SDavid van Moolenbroek 
35*00b67f09SDavid van Moolenbroek /*
36*00b67f09SDavid van Moolenbroek  * Helper functions
37*00b67f09SDavid van Moolenbroek  */
38*00b67f09SDavid van Moolenbroek 
39*00b67f09SDavid van Moolenbroek /* task event handler, sets a boolean to true */
40*00b67f09SDavid van Moolenbroek int counter = 0;
41*00b67f09SDavid van Moolenbroek isc_mutex_t set_lock;
42*00b67f09SDavid van Moolenbroek 
43*00b67f09SDavid van Moolenbroek static void
set(isc_task_t * task,isc_event_t * event)44*00b67f09SDavid van Moolenbroek set(isc_task_t *task, isc_event_t *event) {
45*00b67f09SDavid van Moolenbroek 	int *value = (int *) event->ev_arg;
46*00b67f09SDavid van Moolenbroek 
47*00b67f09SDavid van Moolenbroek 	UNUSED(task);
48*00b67f09SDavid van Moolenbroek 
49*00b67f09SDavid van Moolenbroek 	isc_event_free(&event);
50*00b67f09SDavid van Moolenbroek 	LOCK(&set_lock);
51*00b67f09SDavid van Moolenbroek 	*value = counter++;
52*00b67f09SDavid van Moolenbroek 	UNLOCK(&set_lock);
53*00b67f09SDavid van Moolenbroek }
54*00b67f09SDavid van Moolenbroek 
55*00b67f09SDavid van Moolenbroek static void
set_and_drop(isc_task_t * task,isc_event_t * event)56*00b67f09SDavid van Moolenbroek set_and_drop(isc_task_t *task, isc_event_t *event) {
57*00b67f09SDavid van Moolenbroek 	int *value = (int *) event->ev_arg;
58*00b67f09SDavid van Moolenbroek 
59*00b67f09SDavid van Moolenbroek 	UNUSED(task);
60*00b67f09SDavid van Moolenbroek 
61*00b67f09SDavid van Moolenbroek 	isc_event_free(&event);
62*00b67f09SDavid van Moolenbroek 	LOCK(&set_lock);
63*00b67f09SDavid van Moolenbroek 	*value = (int) isc_taskmgr_mode(taskmgr);
64*00b67f09SDavid van Moolenbroek 	counter++;
65*00b67f09SDavid van Moolenbroek 	UNLOCK(&set_lock);
66*00b67f09SDavid van Moolenbroek 	isc_taskmgr_setmode(taskmgr, isc_taskmgrmode_normal);
67*00b67f09SDavid van Moolenbroek }
68*00b67f09SDavid van Moolenbroek 
69*00b67f09SDavid van Moolenbroek /*
70*00b67f09SDavid van Moolenbroek  * Individual unit tests
71*00b67f09SDavid van Moolenbroek  */
72*00b67f09SDavid van Moolenbroek 
73*00b67f09SDavid van Moolenbroek /* Create a task */
74*00b67f09SDavid van Moolenbroek ATF_TC(create_task);
ATF_TC_HEAD(create_task,tc)75*00b67f09SDavid van Moolenbroek ATF_TC_HEAD(create_task, tc) {
76*00b67f09SDavid van Moolenbroek 	atf_tc_set_md_var(tc, "descr", "create and destroy a task");
77*00b67f09SDavid van Moolenbroek }
ATF_TC_BODY(create_task,tc)78*00b67f09SDavid van Moolenbroek ATF_TC_BODY(create_task, tc) {
79*00b67f09SDavid van Moolenbroek 	isc_result_t result;
80*00b67f09SDavid van Moolenbroek 	isc_task_t *task = NULL;
81*00b67f09SDavid van Moolenbroek 
82*00b67f09SDavid van Moolenbroek 	UNUSED(tc);
83*00b67f09SDavid van Moolenbroek 
84*00b67f09SDavid van Moolenbroek 	result = isc_test_begin(NULL, ISC_TRUE);
85*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
86*00b67f09SDavid van Moolenbroek 
87*00b67f09SDavid van Moolenbroek 	result = isc_task_create(taskmgr, 0, &task);
88*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
89*00b67f09SDavid van Moolenbroek 
90*00b67f09SDavid van Moolenbroek 	isc_task_destroy(&task);
91*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE_EQ(task, NULL);
92*00b67f09SDavid van Moolenbroek 
93*00b67f09SDavid van Moolenbroek 	isc_test_end();
94*00b67f09SDavid van Moolenbroek }
95*00b67f09SDavid van Moolenbroek 
96*00b67f09SDavid van Moolenbroek /* Process events */
97*00b67f09SDavid van Moolenbroek ATF_TC(all_events);
ATF_TC_HEAD(all_events,tc)98*00b67f09SDavid van Moolenbroek ATF_TC_HEAD(all_events, tc) {
99*00b67f09SDavid van Moolenbroek 	atf_tc_set_md_var(tc, "descr", "process task events");
100*00b67f09SDavid van Moolenbroek }
ATF_TC_BODY(all_events,tc)101*00b67f09SDavid van Moolenbroek ATF_TC_BODY(all_events, tc) {
102*00b67f09SDavid van Moolenbroek 	isc_result_t result;
103*00b67f09SDavid van Moolenbroek 	isc_task_t *task = NULL;
104*00b67f09SDavid van Moolenbroek 	isc_event_t *event;
105*00b67f09SDavid van Moolenbroek 	int a = 0, b = 0;
106*00b67f09SDavid van Moolenbroek 	int i = 0;
107*00b67f09SDavid van Moolenbroek 
108*00b67f09SDavid van Moolenbroek 	UNUSED(tc);
109*00b67f09SDavid van Moolenbroek 
110*00b67f09SDavid van Moolenbroek 	counter = 1;
111*00b67f09SDavid van Moolenbroek 
112*00b67f09SDavid van Moolenbroek 	result = isc_mutex_init(&set_lock);
113*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
114*00b67f09SDavid van Moolenbroek 
115*00b67f09SDavid van Moolenbroek 	result = isc_test_begin(NULL, ISC_TRUE);
116*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
117*00b67f09SDavid van Moolenbroek 
118*00b67f09SDavid van Moolenbroek 	result = isc_task_create(taskmgr, 0, &task);
119*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
120*00b67f09SDavid van Moolenbroek 
121*00b67f09SDavid van Moolenbroek 	/* First event */
122*00b67f09SDavid van Moolenbroek 	event = isc_event_allocate(mctx, task, ISC_TASKEVENT_TEST,
123*00b67f09SDavid van Moolenbroek 				   set, &a, sizeof (isc_event_t));
124*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE(event != NULL);
125*00b67f09SDavid van Moolenbroek 
126*00b67f09SDavid van Moolenbroek 	ATF_CHECK_EQ(a, 0);
127*00b67f09SDavid van Moolenbroek 	isc_task_send(task, &event);
128*00b67f09SDavid van Moolenbroek 
129*00b67f09SDavid van Moolenbroek 	event = isc_event_allocate(mctx, task, ISC_TASKEVENT_TEST,
130*00b67f09SDavid van Moolenbroek 				   set, &b, sizeof (isc_event_t));
131*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE(event != NULL);
132*00b67f09SDavid van Moolenbroek 
133*00b67f09SDavid van Moolenbroek 	ATF_CHECK_EQ(b, 0);
134*00b67f09SDavid van Moolenbroek 	isc_task_send(task, &event);
135*00b67f09SDavid van Moolenbroek 
136*00b67f09SDavid van Moolenbroek 	while ((a == 0 || b == 0) && i++ < 5000) {
137*00b67f09SDavid van Moolenbroek #ifndef ISC_PLATFORM_USETHREADS
138*00b67f09SDavid van Moolenbroek 		while (isc__taskmgr_ready(taskmgr))
139*00b67f09SDavid van Moolenbroek 			isc__taskmgr_dispatch(taskmgr);
140*00b67f09SDavid van Moolenbroek #endif
141*00b67f09SDavid van Moolenbroek 		isc_test_nap(1000);
142*00b67f09SDavid van Moolenbroek 	}
143*00b67f09SDavid van Moolenbroek 
144*00b67f09SDavid van Moolenbroek 	ATF_CHECK(a != 0);
145*00b67f09SDavid van Moolenbroek 	ATF_CHECK(b != 0);
146*00b67f09SDavid van Moolenbroek 
147*00b67f09SDavid van Moolenbroek 	isc_task_destroy(&task);
148*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE_EQ(task, NULL);
149*00b67f09SDavid van Moolenbroek 
150*00b67f09SDavid van Moolenbroek 	isc_test_end();
151*00b67f09SDavid van Moolenbroek }
152*00b67f09SDavid van Moolenbroek 
153*00b67f09SDavid van Moolenbroek /* Privileged events */
154*00b67f09SDavid van Moolenbroek ATF_TC(privileged_events);
ATF_TC_HEAD(privileged_events,tc)155*00b67f09SDavid van Moolenbroek ATF_TC_HEAD(privileged_events, tc) {
156*00b67f09SDavid van Moolenbroek 	atf_tc_set_md_var(tc, "descr", "process privileged events");
157*00b67f09SDavid van Moolenbroek }
ATF_TC_BODY(privileged_events,tc)158*00b67f09SDavid van Moolenbroek ATF_TC_BODY(privileged_events, tc) {
159*00b67f09SDavid van Moolenbroek 	isc_result_t result;
160*00b67f09SDavid van Moolenbroek 	isc_task_t *task1 = NULL, *task2 = NULL;
161*00b67f09SDavid van Moolenbroek 	isc_event_t *event;
162*00b67f09SDavid van Moolenbroek 	int a = 0, b = 0, c = 0, d = 0, e = 0;
163*00b67f09SDavid van Moolenbroek 	int i = 0;
164*00b67f09SDavid van Moolenbroek 
165*00b67f09SDavid van Moolenbroek 	UNUSED(tc);
166*00b67f09SDavid van Moolenbroek 
167*00b67f09SDavid van Moolenbroek 	counter = 1;
168*00b67f09SDavid van Moolenbroek 	result = isc_mutex_init(&set_lock);
169*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
170*00b67f09SDavid van Moolenbroek 
171*00b67f09SDavid van Moolenbroek 	result = isc_test_begin(NULL, ISC_TRUE);
172*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
173*00b67f09SDavid van Moolenbroek 
174*00b67f09SDavid van Moolenbroek #ifdef ISC_PLATFORM_USETHREADS
175*00b67f09SDavid van Moolenbroek 	/*
176*00b67f09SDavid van Moolenbroek 	 * Pause the task manager so we can fill up the work queue
177*00b67f09SDavid van Moolenbroek 	 * without things happening while we do it.
178*00b67f09SDavid van Moolenbroek 	 */
179*00b67f09SDavid van Moolenbroek 	isc__taskmgr_pause(taskmgr);
180*00b67f09SDavid van Moolenbroek #endif
181*00b67f09SDavid van Moolenbroek 
182*00b67f09SDavid van Moolenbroek 	result = isc_task_create(taskmgr, 0, &task1);
183*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
184*00b67f09SDavid van Moolenbroek 	isc_task_setname(task1, "privileged", NULL);
185*00b67f09SDavid van Moolenbroek 	ATF_CHECK(!isc_task_privilege(task1));
186*00b67f09SDavid van Moolenbroek 	isc_task_setprivilege(task1, ISC_TRUE);
187*00b67f09SDavid van Moolenbroek 	ATF_CHECK(isc_task_privilege(task1));
188*00b67f09SDavid van Moolenbroek 
189*00b67f09SDavid van Moolenbroek 	result = isc_task_create(taskmgr, 0, &task2);
190*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
191*00b67f09SDavid van Moolenbroek 	isc_task_setname(task2, "normal", NULL);
192*00b67f09SDavid van Moolenbroek 	ATF_CHECK(!isc_task_privilege(task2));
193*00b67f09SDavid van Moolenbroek 
194*00b67f09SDavid van Moolenbroek 	/* First event: privileged */
195*00b67f09SDavid van Moolenbroek 	event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST,
196*00b67f09SDavid van Moolenbroek 				   set, &a, sizeof (isc_event_t));
197*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE(event != NULL);
198*00b67f09SDavid van Moolenbroek 
199*00b67f09SDavid van Moolenbroek 	ATF_CHECK_EQ(a, 0);
200*00b67f09SDavid van Moolenbroek 	isc_task_send(task1, &event);
201*00b67f09SDavid van Moolenbroek 
202*00b67f09SDavid van Moolenbroek 	/* Second event: not privileged */
203*00b67f09SDavid van Moolenbroek 	event = isc_event_allocate(mctx, task2, ISC_TASKEVENT_TEST,
204*00b67f09SDavid van Moolenbroek 				   set, &b, sizeof (isc_event_t));
205*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE(event != NULL);
206*00b67f09SDavid van Moolenbroek 
207*00b67f09SDavid van Moolenbroek 	ATF_CHECK_EQ(b, 0);
208*00b67f09SDavid van Moolenbroek 	isc_task_send(task2, &event);
209*00b67f09SDavid van Moolenbroek 
210*00b67f09SDavid van Moolenbroek 	/* Third event: privileged */
211*00b67f09SDavid van Moolenbroek 	event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST,
212*00b67f09SDavid van Moolenbroek 				   set, &c, sizeof (isc_event_t));
213*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE(event != NULL);
214*00b67f09SDavid van Moolenbroek 
215*00b67f09SDavid van Moolenbroek 	ATF_CHECK_EQ(c, 0);
216*00b67f09SDavid van Moolenbroek 	isc_task_send(task1, &event);
217*00b67f09SDavid van Moolenbroek 
218*00b67f09SDavid van Moolenbroek 	/* Fourth event: privileged */
219*00b67f09SDavid van Moolenbroek 	event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST,
220*00b67f09SDavid van Moolenbroek 				   set, &d, sizeof (isc_event_t));
221*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE(event != NULL);
222*00b67f09SDavid van Moolenbroek 
223*00b67f09SDavid van Moolenbroek 	ATF_CHECK_EQ(d, 0);
224*00b67f09SDavid van Moolenbroek 	isc_task_send(task1, &event);
225*00b67f09SDavid van Moolenbroek 
226*00b67f09SDavid van Moolenbroek 	/* Fifth event: not privileged */
227*00b67f09SDavid van Moolenbroek 	event = isc_event_allocate(mctx, task2, ISC_TASKEVENT_TEST,
228*00b67f09SDavid van Moolenbroek 				   set, &e, sizeof (isc_event_t));
229*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE(event != NULL);
230*00b67f09SDavid van Moolenbroek 
231*00b67f09SDavid van Moolenbroek 	ATF_CHECK_EQ(e, 0);
232*00b67f09SDavid van Moolenbroek 	isc_task_send(task2, &event);
233*00b67f09SDavid van Moolenbroek 
234*00b67f09SDavid van Moolenbroek 	ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_normal);
235*00b67f09SDavid van Moolenbroek 	isc_taskmgr_setmode(taskmgr, isc_taskmgrmode_privileged);
236*00b67f09SDavid van Moolenbroek 	ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_privileged);
237*00b67f09SDavid van Moolenbroek 
238*00b67f09SDavid van Moolenbroek #ifdef ISC_PLATFORM_USETHREADS
239*00b67f09SDavid van Moolenbroek 	isc__taskmgr_resume(taskmgr);
240*00b67f09SDavid van Moolenbroek #endif
241*00b67f09SDavid van Moolenbroek 
242*00b67f09SDavid van Moolenbroek 	/* We're waiting for *all* variables to be set */
243*00b67f09SDavid van Moolenbroek 	while ((a == 0 || b == 0 || c == 0 || d == 0 || e == 0) && i++ < 5000) {
244*00b67f09SDavid van Moolenbroek #ifndef ISC_PLATFORM_USETHREADS
245*00b67f09SDavid van Moolenbroek 		while (isc__taskmgr_ready(taskmgr))
246*00b67f09SDavid van Moolenbroek 			isc__taskmgr_dispatch(taskmgr);
247*00b67f09SDavid van Moolenbroek #endif
248*00b67f09SDavid van Moolenbroek 		isc_test_nap(1000);
249*00b67f09SDavid van Moolenbroek 	}
250*00b67f09SDavid van Moolenbroek 
251*00b67f09SDavid van Moolenbroek 	/*
252*00b67f09SDavid van Moolenbroek 	 * We can't guarantee what order the events fire, but
253*00b67f09SDavid van Moolenbroek 	 * we do know the privileged tasks that set a, c, and d
254*00b67f09SDavid van Moolenbroek 	 * would have fired first.
255*00b67f09SDavid van Moolenbroek 	 */
256*00b67f09SDavid van Moolenbroek 	ATF_CHECK(a <= 3);
257*00b67f09SDavid van Moolenbroek 	ATF_CHECK(c <= 3);
258*00b67f09SDavid van Moolenbroek 	ATF_CHECK(d <= 3);
259*00b67f09SDavid van Moolenbroek 
260*00b67f09SDavid van Moolenbroek 	/* ...and the non-privileged tasks that set b and e, last */
261*00b67f09SDavid van Moolenbroek 	ATF_CHECK(b >= 4);
262*00b67f09SDavid van Moolenbroek 	ATF_CHECK(e >= 4);
263*00b67f09SDavid van Moolenbroek 
264*00b67f09SDavid van Moolenbroek 	ATF_CHECK_EQ(counter, 6);
265*00b67f09SDavid van Moolenbroek 
266*00b67f09SDavid van Moolenbroek 	isc_task_setprivilege(task1, ISC_FALSE);
267*00b67f09SDavid van Moolenbroek 	ATF_CHECK(!isc_task_privilege(task1));
268*00b67f09SDavid van Moolenbroek 
269*00b67f09SDavid van Moolenbroek 	ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_normal);
270*00b67f09SDavid van Moolenbroek 
271*00b67f09SDavid van Moolenbroek 	isc_task_destroy(&task1);
272*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE_EQ(task1, NULL);
273*00b67f09SDavid van Moolenbroek 	isc_task_destroy(&task2);
274*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE_EQ(task2, NULL);
275*00b67f09SDavid van Moolenbroek 
276*00b67f09SDavid van Moolenbroek 	isc_test_end();
277*00b67f09SDavid van Moolenbroek }
278*00b67f09SDavid van Moolenbroek 
279*00b67f09SDavid van Moolenbroek /*
280*00b67f09SDavid van Moolenbroek  * Edge case: this tests that the task manager behaves as expected when
281*00b67f09SDavid van Moolenbroek  * we explicitly set it into normal mode *while* running privileged.
282*00b67f09SDavid van Moolenbroek  */
283*00b67f09SDavid van Moolenbroek ATF_TC(privilege_drop);
ATF_TC_HEAD(privilege_drop,tc)284*00b67f09SDavid van Moolenbroek ATF_TC_HEAD(privilege_drop, tc) {
285*00b67f09SDavid van Moolenbroek 	atf_tc_set_md_var(tc, "descr", "process privileged events");
286*00b67f09SDavid van Moolenbroek }
ATF_TC_BODY(privilege_drop,tc)287*00b67f09SDavid van Moolenbroek ATF_TC_BODY(privilege_drop, tc) {
288*00b67f09SDavid van Moolenbroek 	isc_result_t result;
289*00b67f09SDavid van Moolenbroek 	isc_task_t *task1 = NULL, *task2 = NULL;
290*00b67f09SDavid van Moolenbroek 	isc_event_t *event;
291*00b67f09SDavid van Moolenbroek 	int a = -1, b = -1, c = -1, d = -1, e = -1;	/* non valid states */
292*00b67f09SDavid van Moolenbroek 	int i = 0;
293*00b67f09SDavid van Moolenbroek 
294*00b67f09SDavid van Moolenbroek 	UNUSED(tc);
295*00b67f09SDavid van Moolenbroek 
296*00b67f09SDavid van Moolenbroek 	counter = 1;
297*00b67f09SDavid van Moolenbroek 	result = isc_mutex_init(&set_lock);
298*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
299*00b67f09SDavid van Moolenbroek 
300*00b67f09SDavid van Moolenbroek 	result = isc_test_begin(NULL, ISC_TRUE);
301*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
302*00b67f09SDavid van Moolenbroek 
303*00b67f09SDavid van Moolenbroek #ifdef ISC_PLATFORM_USETHREADS
304*00b67f09SDavid van Moolenbroek 	/*
305*00b67f09SDavid van Moolenbroek 	 * Pause the task manager so we can fill up the work queue
306*00b67f09SDavid van Moolenbroek 	 * without things happening while we do it.
307*00b67f09SDavid van Moolenbroek 	 */
308*00b67f09SDavid van Moolenbroek 	isc__taskmgr_pause(taskmgr);
309*00b67f09SDavid van Moolenbroek #endif
310*00b67f09SDavid van Moolenbroek 
311*00b67f09SDavid van Moolenbroek 	result = isc_task_create(taskmgr, 0, &task1);
312*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
313*00b67f09SDavid van Moolenbroek 	isc_task_setname(task1, "privileged", NULL);
314*00b67f09SDavid van Moolenbroek 	ATF_CHECK(!isc_task_privilege(task1));
315*00b67f09SDavid van Moolenbroek 	isc_task_setprivilege(task1, ISC_TRUE);
316*00b67f09SDavid van Moolenbroek 	ATF_CHECK(isc_task_privilege(task1));
317*00b67f09SDavid van Moolenbroek 
318*00b67f09SDavid van Moolenbroek 	result = isc_task_create(taskmgr, 0, &task2);
319*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
320*00b67f09SDavid van Moolenbroek 	isc_task_setname(task2, "normal", NULL);
321*00b67f09SDavid van Moolenbroek 	ATF_CHECK(!isc_task_privilege(task2));
322*00b67f09SDavid van Moolenbroek 
323*00b67f09SDavid van Moolenbroek 	/* First event: privileged */
324*00b67f09SDavid van Moolenbroek 	event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST,
325*00b67f09SDavid van Moolenbroek 				   set_and_drop, &a, sizeof (isc_event_t));
326*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE(event != NULL);
327*00b67f09SDavid van Moolenbroek 
328*00b67f09SDavid van Moolenbroek 	ATF_CHECK_EQ(a, -1);
329*00b67f09SDavid van Moolenbroek 	isc_task_send(task1, &event);
330*00b67f09SDavid van Moolenbroek 
331*00b67f09SDavid van Moolenbroek 	/* Second event: not privileged */
332*00b67f09SDavid van Moolenbroek 	event = isc_event_allocate(mctx, task2, ISC_TASKEVENT_TEST,
333*00b67f09SDavid van Moolenbroek 				   set_and_drop, &b, sizeof (isc_event_t));
334*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE(event != NULL);
335*00b67f09SDavid van Moolenbroek 
336*00b67f09SDavid van Moolenbroek 	ATF_CHECK_EQ(b, -1);
337*00b67f09SDavid van Moolenbroek 	isc_task_send(task2, &event);
338*00b67f09SDavid van Moolenbroek 
339*00b67f09SDavid van Moolenbroek 	/* Third event: privileged */
340*00b67f09SDavid van Moolenbroek 	event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST,
341*00b67f09SDavid van Moolenbroek 				   set_and_drop, &c, sizeof (isc_event_t));
342*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE(event != NULL);
343*00b67f09SDavid van Moolenbroek 
344*00b67f09SDavid van Moolenbroek 	ATF_CHECK_EQ(c, -1);
345*00b67f09SDavid van Moolenbroek 	isc_task_send(task1, &event);
346*00b67f09SDavid van Moolenbroek 
347*00b67f09SDavid van Moolenbroek 	/* Fourth event: privileged */
348*00b67f09SDavid van Moolenbroek 	event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST,
349*00b67f09SDavid van Moolenbroek 				   set_and_drop, &d, sizeof (isc_event_t));
350*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE(event != NULL);
351*00b67f09SDavid van Moolenbroek 
352*00b67f09SDavid van Moolenbroek 	ATF_CHECK_EQ(d, -1);
353*00b67f09SDavid van Moolenbroek 	isc_task_send(task1, &event);
354*00b67f09SDavid van Moolenbroek 
355*00b67f09SDavid van Moolenbroek 	/* Fifth event: not privileged */
356*00b67f09SDavid van Moolenbroek 	event = isc_event_allocate(mctx, task2, ISC_TASKEVENT_TEST,
357*00b67f09SDavid van Moolenbroek 				   set_and_drop, &e, sizeof (isc_event_t));
358*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE(event != NULL);
359*00b67f09SDavid van Moolenbroek 
360*00b67f09SDavid van Moolenbroek 	ATF_CHECK_EQ(e, -1);
361*00b67f09SDavid van Moolenbroek 	isc_task_send(task2, &event);
362*00b67f09SDavid van Moolenbroek 
363*00b67f09SDavid van Moolenbroek 	ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_normal);
364*00b67f09SDavid van Moolenbroek 	isc_taskmgr_setmode(taskmgr, isc_taskmgrmode_privileged);
365*00b67f09SDavid van Moolenbroek 	ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_privileged);
366*00b67f09SDavid van Moolenbroek 
367*00b67f09SDavid van Moolenbroek #ifdef ISC_PLATFORM_USETHREADS
368*00b67f09SDavid van Moolenbroek 	isc__taskmgr_resume(taskmgr);
369*00b67f09SDavid van Moolenbroek #endif
370*00b67f09SDavid van Moolenbroek 
371*00b67f09SDavid van Moolenbroek 	/* We're waiting for all variables to be set. */
372*00b67f09SDavid van Moolenbroek 	while ((a == -1 || b == -1 || c == -1 || d == -1 || e == -1) &&
373*00b67f09SDavid van Moolenbroek 	       i++ < 5000) {
374*00b67f09SDavid van Moolenbroek #ifndef ISC_PLATFORM_USETHREADS
375*00b67f09SDavid van Moolenbroek 		while (isc__taskmgr_ready(taskmgr))
376*00b67f09SDavid van Moolenbroek 			isc__taskmgr_dispatch(taskmgr);
377*00b67f09SDavid van Moolenbroek #endif
378*00b67f09SDavid van Moolenbroek 		isc_test_nap(1000);
379*00b67f09SDavid van Moolenbroek 	}
380*00b67f09SDavid van Moolenbroek 
381*00b67f09SDavid van Moolenbroek 	/*
382*00b67f09SDavid van Moolenbroek 	 * We can't guarantee what order the events fire, but
383*00b67f09SDavid van Moolenbroek 	 * we do know *exactly one* of the privileged tasks will
384*00b67f09SDavid van Moolenbroek 	 * have run in privileged mode...
385*00b67f09SDavid van Moolenbroek 	 */
386*00b67f09SDavid van Moolenbroek 	ATF_CHECK(a == isc_taskmgrmode_privileged ||
387*00b67f09SDavid van Moolenbroek 		  c == isc_taskmgrmode_privileged ||
388*00b67f09SDavid van Moolenbroek 		  d == isc_taskmgrmode_privileged);
389*00b67f09SDavid van Moolenbroek 	ATF_CHECK(a + c + d == isc_taskmgrmode_privileged);
390*00b67f09SDavid van Moolenbroek 
391*00b67f09SDavid van Moolenbroek 	/* ...and neither of the non-privileged tasks did... */
392*00b67f09SDavid van Moolenbroek 	ATF_CHECK(b == isc_taskmgrmode_normal || e == isc_taskmgrmode_normal);
393*00b67f09SDavid van Moolenbroek 
394*00b67f09SDavid van Moolenbroek 	/* ...but all five of them did run. */
395*00b67f09SDavid van Moolenbroek 	ATF_CHECK_EQ(counter, 6);
396*00b67f09SDavid van Moolenbroek 
397*00b67f09SDavid van Moolenbroek 	ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_normal);
398*00b67f09SDavid van Moolenbroek 
399*00b67f09SDavid van Moolenbroek 	isc_task_destroy(&task1);
400*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE_EQ(task1, NULL);
401*00b67f09SDavid van Moolenbroek 	isc_task_destroy(&task2);
402*00b67f09SDavid van Moolenbroek 	ATF_REQUIRE_EQ(task2, NULL);
403*00b67f09SDavid van Moolenbroek 
404*00b67f09SDavid van Moolenbroek 	isc_test_end();
405*00b67f09SDavid van Moolenbroek }
406*00b67f09SDavid van Moolenbroek 
407*00b67f09SDavid van Moolenbroek /*
408*00b67f09SDavid van Moolenbroek  * Main
409*00b67f09SDavid van Moolenbroek  */
ATF_TP_ADD_TCS(tp)410*00b67f09SDavid van Moolenbroek ATF_TP_ADD_TCS(tp) {
411*00b67f09SDavid van Moolenbroek 	ATF_TP_ADD_TC(tp, create_task);
412*00b67f09SDavid van Moolenbroek 	ATF_TP_ADD_TC(tp, all_events);
413*00b67f09SDavid van Moolenbroek 	ATF_TP_ADD_TC(tp, privileged_events);
414*00b67f09SDavid van Moolenbroek 	ATF_TP_ADD_TC(tp, privilege_drop);
415*00b67f09SDavid van Moolenbroek 
416*00b67f09SDavid van Moolenbroek 	return (atf_no_error());
417*00b67f09SDavid van Moolenbroek }
418*00b67f09SDavid van Moolenbroek 
419