ATF_TC_BODY(get_tasks, tc) {
	isc_result_t result;
	isc_taskpool_t *pool = NULL;
	isc_task_t *task1 = NULL, *task2 = NULL, *task3 = NULL;

	UNUSED(tc);

	result = isc_test_begin(NULL, ISC_TRUE);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	result = isc_taskpool_create(taskmgr, mctx, 2, 2, &pool);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
	ATF_REQUIRE_EQ(isc_taskpool_size(pool), 2);

	/* two tasks in pool; make sure we can access them more than twice */
	isc_taskpool_gettask(pool, &task1);
	ATF_REQUIRE(ISCAPI_TASK_VALID(task1));

	isc_taskpool_gettask(pool, &task2);
	ATF_REQUIRE(ISCAPI_TASK_VALID(task2));

	isc_taskpool_gettask(pool, &task3);
	ATF_REQUIRE(ISCAPI_TASK_VALID(task3));

	isc_task_destroy(&task1);
	isc_task_destroy(&task2);
	isc_task_destroy(&task3);

	isc_taskpool_destroy(&pool);
	ATF_REQUIRE_EQ(pool, NULL);

	isc_test_end();
}
Exemple #2
0
int
main(int argc, char *argv[]) {
	isc_interval_t linterval;
	int i;

	UNUSED(argc);
	UNUSED(argv);

	isc__mem_register();
	isc__task_register();
	isc__timer_register();
	isc__socket_register();
	isc_app_start();
	isc_interval_set(&linterval, 1, 0);

	RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
	RUNTIME_CHECK(isc_taskmgr_create(mctx, 3, 0, &taskmgr) ==
		      ISC_R_SUCCESS);
	RUNTIME_CHECK(isc_timermgr_create(mctx, &timermgr) ==
		      ISC_R_SUCCESS);
	RUNTIME_CHECK(isc_task_create(taskmgr, 0, &g_task) ==
		      ISC_R_SUCCESS);

	RUNTIME_CHECK(isc_ratelimiter_create(mctx, timermgr, g_task,
					     &rlim) == ISC_R_SUCCESS);

	RUNTIME_CHECK(isc_ratelimiter_setinterval(rlim, &linterval) ==
		      ISC_R_SUCCESS);

	for (i = 0; i < NEVENTS; i++) {
		isc_interval_t uinterval;
		int ms = schedule[i].milliseconds;
		isc_interval_set(&uinterval,  ms / 1000,
				 (ms % 1000) * 1000000);
		timers[i] = NULL;
		RUNTIME_CHECK(isc_timer_create(timermgr,
					       isc_timertype_once, NULL,
					       &uinterval,
					       g_task, schedule[i].fun, NULL,
					       &timers[i]) == ISC_R_SUCCESS);
	}

	isc_app_run();

	isc_task_destroy(&g_task);

	isc_ratelimiter_detach(&rlim);

	isc_timermgr_destroy(&timermgr);
	isc_taskmgr_destroy(&taskmgr);

	isc_mem_stats(mctx, stdout);

	isc_app_finish();
	return (0);
}
ATF_TC_BODY(set_privilege, tc) {
	isc_result_t result;
	isc_taskpool_t *pool = NULL;
	isc_task_t *task1 = NULL, *task2 = NULL, *task3 = NULL;

	UNUSED(tc);

	result = isc_test_begin(NULL, ISC_TRUE);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	result = isc_taskpool_create(taskmgr, mctx, 2, 2, &pool);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
	ATF_REQUIRE_EQ(isc_taskpool_size(pool), 2);

	isc_taskpool_setprivilege(pool, ISC_TRUE);

	isc_taskpool_gettask(pool, &task1);
	isc_taskpool_gettask(pool, &task2);
	isc_taskpool_gettask(pool, &task3);

	ATF_CHECK(ISCAPI_TASK_VALID(task1));
	ATF_CHECK(ISCAPI_TASK_VALID(task2));
	ATF_CHECK(ISCAPI_TASK_VALID(task3));

	ATF_CHECK(isc_task_privilege(task1));
	ATF_CHECK(isc_task_privilege(task2));
	ATF_CHECK(isc_task_privilege(task3));

	isc_taskpool_setprivilege(pool, ISC_FALSE);

	ATF_CHECK(!isc_task_privilege(task1));
	ATF_CHECK(!isc_task_privilege(task2));
	ATF_CHECK(!isc_task_privilege(task3));

	isc_task_destroy(&task1);
	isc_task_destroy(&task2);
	isc_task_destroy(&task3);

	isc_taskpool_destroy(&pool);
	ATF_REQUIRE_EQ(pool, NULL);

	isc_test_end();
}
Exemple #4
0
static void
cleanup_managers() {
	if (maintask != NULL)
		isc_task_destroy(&maintask);
	if (socketmgr != NULL)
		isc_socketmgr_destroy(&socketmgr);
	if (taskmgr != NULL)
		isc_taskmgr_destroy(&taskmgr);
	if (timermgr != NULL)
		isc_timermgr_destroy(&timermgr);
}
Exemple #5
0
static void
cleanup_managers(void) {
	if (app_running)
		isc_app_finish();
	if (socketmgr != NULL)
		isc_socketmgr_destroy(&socketmgr);
	if (maintask != NULL)
		isc_task_destroy(&maintask);
	if (taskmgr != NULL)
		isc_taskmgr_destroy(&taskmgr);
	if (timermgr != NULL)
		isc_timermgr_destroy(&timermgr);
}
ATF_TC_BODY(all_events, tc) {
	isc_result_t result;
	isc_task_t *task = NULL;
	isc_event_t *event;
	int a = 0, b = 0;
	int i = 0;

	UNUSED(tc);

	counter = 1;

	result = isc_mutex_init(&set_lock);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	result = isc_test_begin(NULL, ISC_TRUE);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	result = isc_task_create(taskmgr, 0, &task);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	/* First event */
	event = isc_event_allocate(mctx, task, ISC_TASKEVENT_TEST,
				   set, &a, sizeof (isc_event_t));
	ATF_REQUIRE(event != NULL);

	ATF_CHECK_EQ(a, 0);
	isc_task_send(task, &event);

	event = isc_event_allocate(mctx, task, ISC_TASKEVENT_TEST,
				   set, &b, sizeof (isc_event_t));
	ATF_REQUIRE(event != NULL);

	ATF_CHECK_EQ(b, 0);
	isc_task_send(task, &event);

	while ((a == 0 || b == 0) && i++ < 5000) {
#ifndef ISC_PLATFORM_USETHREADS
		while (isc__taskmgr_ready(taskmgr))
			isc__taskmgr_dispatch(taskmgr);
#endif
		isc_test_nap(1000);
	}

	ATF_CHECK(a != 0);
	ATF_CHECK(b != 0);

	isc_task_destroy(&task);
	ATF_REQUIRE_EQ(task, NULL);

	isc_test_end();
}
ATF_TC_BODY(create_task, tc) {
	isc_result_t result;
	isc_task_t *task = NULL;

	UNUSED(tc);

	result = isc_test_begin(NULL, ISC_TRUE);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	result = isc_task_create(taskmgr, 0, &task);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	isc_task_destroy(&task);
	ATF_REQUIRE_EQ(task, NULL);

	isc_test_end();
}
Exemple #8
0
static int
t_timers5(void) {
	char		*p;
	int		result;
	isc_mem_t	*mctx;
	isc_taskmgr_t	*tmgr;
	unsigned int	workers;
	isc_result_t	isc_result;
	isc_timermgr_t	*timermgr;
	isc_event_t	*event;
	isc_time_t	expires;
	isc_interval_t	interval;

	T5_startflag = 0;
	T5_shutdownflag = 0;
	T5_eventcnt = 0;

	workers = 2;
	p = t_getenv("ISC_TASK_WORKERS");
	if (p != NULL)
		workers = atoi(p);

	mctx = NULL;
	isc_result = isc_mem_create(0, 0, &mctx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mem_create failed %s\n",
		       isc_result_totext(isc_result));
		return(T_UNRESOLVED);
	}

	isc_result = isc_mutex_init(&T5_mx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mutex_init failed %s\n",
		       isc_result_totext(isc_result));
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	isc_result = isc_condition_init(&T5_cv);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_condition_init failed %s\n",
		       isc_result_totext(isc_result));
		DESTROYLOCK(&T5_mx);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	tmgr = NULL;
	isc_result = isc_taskmgr_create(mctx, workers, 0, &tmgr);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_taskmgr_create failed %s\n",
		       isc_result_totext(isc_result));
		DESTROYLOCK(&T5_mx);
		(void) isc_condition_destroy(&T5_cv);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	timermgr = NULL;
	isc_result = isc_timermgr_create(mctx, &timermgr);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_timermgr_create failed %s\n",
		       isc_result_totext(isc_result));
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&T5_mx);
		(void) isc_condition_destroy(&T5_cv);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	T5_task1 = NULL;
	isc_result = isc_task_create(tmgr, 0, &T5_task1);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_task_create failed %s\n",
		       isc_result_totext(isc_result));
		isc_timermgr_destroy(&timermgr);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&T5_mx);
		(void) isc_condition_destroy(&T5_cv);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	isc_result = isc_task_onshutdown(T5_task1, t5_shutdown_event, NULL);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_task_onshutdown failed %s\n",
		       isc_result_totext(isc_result));
		isc_timermgr_destroy(&timermgr);
		isc_task_destroy(&T5_task1);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&T5_mx);
		(void) isc_condition_destroy(&T5_cv);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	T5_task2 = NULL;
	isc_result = isc_task_create(tmgr, 0, &T5_task2);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_task_create failed %s\n",
		       isc_result_totext(isc_result));
		isc_timermgr_destroy(&timermgr);
		isc_task_destroy(&T5_task1);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&T5_mx);
		(void) isc_condition_destroy(&T5_cv);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	isc_result = isc_mutex_lock(&T5_mx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mutex_lock failed %s\n",
		       isc_result_totext(isc_result));
		isc_timermgr_destroy(&timermgr);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&T5_mx);
		(void) isc_condition_destroy(&T5_cv);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	event = isc_event_allocate(mctx, (void *)1 , (isc_eventtype_t)1,
				   t5_start_event, NULL, sizeof(*event));
	isc_task_send(T5_task1, &event);

	isc_time_settoepoch(&expires);
	isc_interval_set(&interval, T5_SECONDS, 0);

	T5_tickertimer = NULL;
	isc_result = isc_timer_create(timermgr, isc_timertype_ticker,
				      &expires, &interval, T5_task1,
				      t5_tick_event, NULL, &T5_tickertimer);

	if (isc_result != ISC_R_SUCCESS) {
		isc_timermgr_destroy(&timermgr);
		(void) isc_condition_signal(&T5_cv);
		(void) isc_mutex_unlock(&T5_mx);
		isc_task_destroy(&T5_task1);
		isc_task_destroy(&T5_task2);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&T5_mx);
		(void) isc_condition_destroy(&T5_cv);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	T5_oncetimer = NULL;
	isc_interval_set(&interval, (T5_SECONDS * T5_NTICKS) + 2, 0);
	isc_result = isc_time_nowplusinterval(&expires, &interval);
	if (isc_result != ISC_R_SUCCESS) {
		isc_timer_detach(&T5_tickertimer);
		isc_timermgr_destroy(&timermgr);
		(void)isc_condition_signal(&T5_cv);
		(void)isc_mutex_unlock(&T5_mx);
		isc_task_destroy(&T5_task1);
		isc_task_destroy(&T5_task2);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&T5_mx);
		(void) isc_condition_destroy(&T5_cv);
		isc_mem_destroy(&mctx);
		return(T_UNRESOLVED);
	}

	isc_interval_set(&interval, 0, 0);
	isc_result = isc_timer_create(timermgr, isc_timertype_once,
				      &expires, &interval, T5_task2,
				      t5_once_event, NULL, &T5_oncetimer);

	if (isc_result != ISC_R_SUCCESS) {
		isc_timer_detach(&T5_tickertimer);
		isc_timermgr_destroy(&timermgr);
		(void) isc_condition_signal(&T5_cv);
		(void) isc_mutex_unlock(&T5_mx);
		isc_task_destroy(&T5_task1);
		isc_task_destroy(&T5_task2);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&T5_mx);
		(void) isc_condition_destroy(&T5_cv);
		isc_mem_destroy(&mctx);
		++T5_nprobs;
		return(T_UNRESOLVED);
	}

	/*
	 * Wait for shutdown processing to complete.
	 */
	while (! T5_shutdownflag) {
		isc_result = isc_condition_wait(&T5_cv, &T5_mx);
		if (isc_result != ISC_R_SUCCESS) {
			t_info("isc_condition_waituntil failed %s\n",
			       isc_result_totext(isc_result));
			++T5_nprobs;
		}
	}

	isc_result = isc_mutex_unlock(&T5_mx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mutex_unlock failed %s\n",
		       isc_result_totext(isc_result));
		++T5_nprobs;
	}

	if (T5_eventcnt != 1) {
		t_info("processed %d events\n", T5_eventcnt);
		++T5_nfails;
	}

	isc_timer_detach(&T5_tickertimer);
	isc_timer_detach(&T5_oncetimer);
	isc_timermgr_destroy(&timermgr);
	isc_task_destroy(&T5_task1);
	isc_task_destroy(&T5_task2);
	isc_taskmgr_destroy(&tmgr);
	DESTROYLOCK(&T5_mx);
	(void) isc_condition_destroy(&T5_cv);
	isc_mem_destroy(&mctx);

	result = T_UNRESOLVED;

	if ((T5_nfails == 0) && (T5_nprobs == 0))
		result = T_PASS;
	else if (T5_nfails)
		result = T_FAIL;

	return (result);
}
Exemple #9
0
static void
t_timers_x(isc_timertype_t timertype, isc_time_t *expires,
	   isc_interval_t *interval,
	   void (*action)(isc_task_t *, isc_event_t *))
{
	char		*p;
	isc_mem_t	*mctx;
	isc_taskmgr_t	*tmgr;
	isc_task_t	*task;
	unsigned int	workers;
	isc_result_t	isc_result;
	isc_timermgr_t	*timermgr;

	Tx_eventcnt = 0;
	isc_time_settoepoch(&Tx_endtime);

	workers = 2;
	p = t_getenv("ISC_TASK_WORKERS");
	if (p != NULL)
		workers = atoi(p);

	mctx = NULL;
	isc_result = isc_mem_create(0, 0, &mctx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mem_create failed %s\n",
		       isc_result_totext(isc_result));
		++Tx_nprobs;
		return;
	}

	isc_result = isc_mutex_init(&Tx_mx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mutex_init failed %s\n",
		       isc_result_totext(isc_result));
		isc_mem_destroy(&mctx);
		++Tx_nprobs;
		return;
	}

	isc_result = isc_condition_init(&Tx_cv);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_condition_init failed %s\n",
		       isc_result_totext(isc_result));
		DESTROYLOCK(&Tx_mx);
		isc_mem_destroy(&mctx);
		++Tx_nprobs;
		return;
	}

	tmgr = NULL;
	isc_result = isc_taskmgr_create(mctx, workers, 0, &tmgr);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_taskmgr_create failed %s\n",
		       isc_result_totext(isc_result));
		DESTROYLOCK(&Tx_mx);
		(void) isc_condition_destroy(&Tx_cv);
		isc_mem_destroy(&mctx);
		++Tx_nprobs;
		return;
	}

	timermgr = NULL;
	isc_result = isc_timermgr_create(mctx, &timermgr);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_timermgr_create failed %s\n",
		       isc_result_totext(isc_result));
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&Tx_mx);
		(void) isc_condition_destroy(&Tx_cv);
		isc_mem_destroy(&mctx);
		++Tx_nprobs;
		return;
	}

	isc_result = isc_mutex_lock(&Tx_mx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mutex_lock failed %s\n",
		       isc_result_totext(isc_result));
		isc_timermgr_destroy(&timermgr);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&Tx_mx);
		(void) isc_condition_destroy(&Tx_cv);
		isc_mem_destroy(&mctx);
		++Tx_nprobs;
		return;
	}

	task = NULL;
	isc_result = isc_task_create(tmgr, 0, &task);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_task_create failed %s\n",
		       isc_result_totext(isc_result));
		isc_timermgr_destroy(&timermgr);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&Tx_mx);
		(void) isc_condition_destroy(&Tx_cv);
		isc_mem_destroy(&mctx);
		++Tx_nprobs;
		return;
	}

	isc_result = isc_task_onshutdown(task, tx_sde, NULL);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_task_onshutdown failed %s\n",
		       isc_result_totext(isc_result));
		isc_timermgr_destroy(&timermgr);
		isc_task_destroy(&task);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&Tx_mx);
		(void) isc_condition_destroy(&Tx_cv);
		isc_mem_destroy(&mctx);
		++Tx_nprobs;
		return;
	}

	isc_result = isc_time_now(&Tx_lasttime);
	if (isc_result != ISC_R_SUCCESS) {
		isc_timermgr_destroy(&timermgr);
		isc_task_destroy(&task);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&Tx_mx);
		(void) isc_condition_destroy(&Tx_cv);
		isc_mem_destroy(&mctx);
		++Tx_nprobs;
		return;
	}

	Tx_timer = NULL;
	isc_result = isc_timer_create(timermgr, timertype, expires, interval,
				      task, action, (void *)timertype,
				      &Tx_timer);

	if (isc_result != ISC_R_SUCCESS) {
		isc_timermgr_destroy(&timermgr);
		isc_task_destroy(&task);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&Tx_mx);
		(void) isc_condition_destroy(&Tx_cv);
		isc_mem_destroy(&mctx);
		++Tx_nprobs;
		return;
	}

	/*
	 * Wait for shutdown processing to complete.
	 */
	while (Tx_eventcnt != Tx_nevents) {
		isc_result = isc_condition_wait(&Tx_cv, &Tx_mx);
		if (isc_result != ISC_R_SUCCESS) {
			t_info("isc_condition_waituntil failed %s\n",
			       isc_result_totext(isc_result));
			++Tx_nprobs;
		}
	}

	isc_result = isc_mutex_unlock(&Tx_mx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mutex_unlock failed %s\n",
		       isc_result_totext(isc_result));
		++Tx_nprobs;
	}

	isc_task_detach(&task);
	isc_taskmgr_destroy(&tmgr);
	isc_timermgr_destroy(&timermgr);
	DESTROYLOCK(&Tx_mx);
	(void) isc_condition_destroy(&Tx_cv);
	isc_mem_destroy(&mctx);

}
Exemple #10
0
static void
poolfree(void **target) {
	isc_task_t *task = *(isc_task_t **) target;
	isc_task_destroy(&task);
	*target = NULL;
}
ATF_TC_BODY(privilege_drop, tc) {
	isc_result_t result;
	isc_task_t *task1 = NULL, *task2 = NULL;
	isc_event_t *event;
	int a = -1, b = -1, c = -1, d = -1, e = -1;	/* non valid states */
	int i = 0;

	UNUSED(tc);

	counter = 1;
	result = isc_mutex_init(&set_lock);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	result = isc_test_begin(NULL, ISC_TRUE);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

#ifdef ISC_PLATFORM_USETHREADS
	/*
	 * Pause the task manager so we can fill up the work queue
	 * without things happening while we do it.
	 */
	isc__taskmgr_pause(taskmgr);
#endif

	result = isc_task_create(taskmgr, 0, &task1);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
	isc_task_setname(task1, "privileged", NULL);
	ATF_CHECK(!isc_task_privilege(task1));
	isc_task_setprivilege(task1, ISC_TRUE);
	ATF_CHECK(isc_task_privilege(task1));

	result = isc_task_create(taskmgr, 0, &task2);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
	isc_task_setname(task2, "normal", NULL);
	ATF_CHECK(!isc_task_privilege(task2));

	/* First event: privileged */
	event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST,
				   set_and_drop, &a, sizeof (isc_event_t));
	ATF_REQUIRE(event != NULL);

	ATF_CHECK_EQ(a, -1);
	isc_task_send(task1, &event);

	/* Second event: not privileged */
	event = isc_event_allocate(mctx, task2, ISC_TASKEVENT_TEST,
				   set_and_drop, &b, sizeof (isc_event_t));
	ATF_REQUIRE(event != NULL);

	ATF_CHECK_EQ(b, -1);
	isc_task_send(task2, &event);

	/* Third event: privileged */
	event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST,
				   set_and_drop, &c, sizeof (isc_event_t));
	ATF_REQUIRE(event != NULL);

	ATF_CHECK_EQ(c, -1);
	isc_task_send(task1, &event);

	/* Fourth event: privileged */
	event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST,
				   set_and_drop, &d, sizeof (isc_event_t));
	ATF_REQUIRE(event != NULL);

	ATF_CHECK_EQ(d, -1);
	isc_task_send(task1, &event);

	/* Fifth event: not privileged */
	event = isc_event_allocate(mctx, task2, ISC_TASKEVENT_TEST,
				   set_and_drop, &e, sizeof (isc_event_t));
	ATF_REQUIRE(event != NULL);

	ATF_CHECK_EQ(e, -1);
	isc_task_send(task2, &event);

	ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_normal);
	isc_taskmgr_setmode(taskmgr, isc_taskmgrmode_privileged);
	ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_privileged);

#ifdef ISC_PLATFORM_USETHREADS
	isc__taskmgr_resume(taskmgr);
#endif

	/* We're waiting for all variables to be set. */
	while ((a == -1 || b == -1 || c == -1 || d == -1 || e == -1) &&
	       i++ < 5000) {
#ifndef ISC_PLATFORM_USETHREADS
		while (isc__taskmgr_ready(taskmgr))
			isc__taskmgr_dispatch(taskmgr);
#endif
		isc_test_nap(1000);
	}

	/*
	 * We can't guarantee what order the events fire, but
	 * we do know *exactly one* of the privileged tasks will
	 * have run in privileged mode...
	 */
	ATF_CHECK(a == isc_taskmgrmode_privileged ||
		  c == isc_taskmgrmode_privileged ||
		  d == isc_taskmgrmode_privileged);
	ATF_CHECK(a + c + d == isc_taskmgrmode_privileged);

	/* ...and neither of the non-privileged tasks did... */
	ATF_CHECK(b == isc_taskmgrmode_normal || e == isc_taskmgrmode_normal);

	/* ...but all five of them did run. */
	ATF_CHECK_EQ(counter, 6);

	ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_normal);

	isc_task_destroy(&task1);
	ATF_REQUIRE_EQ(task1, NULL);
	isc_task_destroy(&task2);
	ATF_REQUIRE_EQ(task2, NULL);

	isc_test_end();
}
ATF_TC_BODY(privileged_events, tc) {
	isc_result_t result;
	isc_task_t *task1 = NULL, *task2 = NULL;
	isc_event_t *event;
	int a = 0, b = 0, c = 0, d = 0, e = 0;
	int i = 0;

	UNUSED(tc);

	counter = 1;
	result = isc_mutex_init(&set_lock);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	result = isc_test_begin(NULL, ISC_TRUE);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

#ifdef ISC_PLATFORM_USETHREADS
	/*
	 * Pause the task manager so we can fill up the work queue
	 * without things happening while we do it.
	 */
	isc__taskmgr_pause(taskmgr);
#endif

	result = isc_task_create(taskmgr, 0, &task1);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
	isc_task_setname(task1, "privileged", NULL);
	ATF_CHECK(!isc_task_privilege(task1));
	isc_task_setprivilege(task1, ISC_TRUE);
	ATF_CHECK(isc_task_privilege(task1));

	result = isc_task_create(taskmgr, 0, &task2);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
	isc_task_setname(task2, "normal", NULL);
	ATF_CHECK(!isc_task_privilege(task2));

	/* First event: privileged */
	event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST,
				   set, &a, sizeof (isc_event_t));
	ATF_REQUIRE(event != NULL);

	ATF_CHECK_EQ(a, 0);
	isc_task_send(task1, &event);

	/* Second event: not privileged */
	event = isc_event_allocate(mctx, task2, ISC_TASKEVENT_TEST,
				   set, &b, sizeof (isc_event_t));
	ATF_REQUIRE(event != NULL);

	ATF_CHECK_EQ(b, 0);
	isc_task_send(task2, &event);

	/* Third event: privileged */
	event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST,
				   set, &c, sizeof (isc_event_t));
	ATF_REQUIRE(event != NULL);

	ATF_CHECK_EQ(c, 0);
	isc_task_send(task1, &event);

	/* Fourth event: privileged */
	event = isc_event_allocate(mctx, task1, ISC_TASKEVENT_TEST,
				   set, &d, sizeof (isc_event_t));
	ATF_REQUIRE(event != NULL);

	ATF_CHECK_EQ(d, 0);
	isc_task_send(task1, &event);

	/* Fifth event: not privileged */
	event = isc_event_allocate(mctx, task2, ISC_TASKEVENT_TEST,
				   set, &e, sizeof (isc_event_t));
	ATF_REQUIRE(event != NULL);

	ATF_CHECK_EQ(e, 0);
	isc_task_send(task2, &event);

	ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_normal);
	isc_taskmgr_setmode(taskmgr, isc_taskmgrmode_privileged);
	ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_privileged);

#ifdef ISC_PLATFORM_USETHREADS
	isc__taskmgr_resume(taskmgr);
#endif

	/* We're waiting for *all* variables to be set */
	while ((a == 0 || b == 0 || c == 0 || d == 0 || e == 0) && i++ < 5000) {
#ifndef ISC_PLATFORM_USETHREADS
		while (isc__taskmgr_ready(taskmgr))
			isc__taskmgr_dispatch(taskmgr);
#endif
		isc_test_nap(1000);
	}

	/*
	 * We can't guarantee what order the events fire, but
	 * we do know the privileged tasks that set a, c, and d
	 * would have fired first.
	 */
	ATF_CHECK(a <= 3);
	ATF_CHECK(c <= 3);
	ATF_CHECK(d <= 3);

	/* ...and the non-privileged tasks that set b and e, last */
	ATF_CHECK(b >= 4);
	ATF_CHECK(e >= 4);

	ATF_CHECK_EQ(counter, 6);

	isc_task_setprivilege(task1, ISC_FALSE);
	ATF_CHECK(!isc_task_privilege(task1));

	ATF_CHECK_EQ(isc_taskmgr_mode(taskmgr), isc_taskmgrmode_normal);

	isc_task_destroy(&task1);
	ATF_REQUIRE_EQ(task1, NULL);
	isc_task_destroy(&task2);
	ATF_REQUIRE_EQ(task2, NULL);

	isc_test_end();
}