void isc_ratelimiter_shutdown (isc_ratelimiter_t * rl) { isc_event_t *ev; isc_task_t *task; LOCK (&rl->lock); rl->state = isc_ratelimiter_shuttingdown; (void) isc_timer_reset (rl->timer, isc_timertype_inactive, NULL, NULL, ISC_FALSE); while ((ev = ISC_LIST_HEAD (rl->pending)) != NULL) { ISC_LIST_UNLINK (rl->pending, ev, ev_link); ev->ev_attributes |= ISC_EVENTATTR_CANCELED; task = ev->ev_sender; isc_task_send (task, &ev); } isc_timer_detach (&rl->timer); /* * Send an event to our task. The delivery of this event * indicates that no more timer events will be delivered. */ ev = &rl->shutdownevent; isc_task_send (rl->task, &ev); UNLOCK (&rl->lock); }
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(); }
static void recv_message(isc_task_t *task, isc_event_t *ev_in) { isc_socketevent_t *ev = (isc_socketevent_t *)ev_in; isc_event_t *dev; dns_tcpmsg_t *tcpmsg = ev_in->ev_arg; (void)task; INSIST(VALID_TCPMSG(tcpmsg)); dev = &tcpmsg->event; tcpmsg->address = ev->address; if (ev->result != ISC_R_SUCCESS) { tcpmsg->result = ev->result; goto send_and_free; } tcpmsg->result = ISC_R_SUCCESS; isc_buffer_add(&tcpmsg->buffer, ev->n); XDEBUG(("Received %d bytes (of %d)\n", ev->n, tcpmsg->size)); send_and_free: isc_task_send(tcpmsg->task, &dev); tcpmsg->task = NULL; isc_event_free(&ev_in); }
isc_result_t isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_task_t *task, isc_event_t **eventp) { isc_result_t result = ISC_R_SUCCESS; isc_event_t *ev; REQUIRE(eventp != NULL && *eventp != NULL); REQUIRE(task != NULL); ev = *eventp; REQUIRE(ev->ev_sender == NULL); LOCK(&rl->lock); if (rl->state == isc_ratelimiter_ratelimited || rl->state == isc_ratelimiter_stalled) { isc_event_t *ev = *eventp; ev->ev_sender = task; ISC_LIST_APPEND(rl->pending, ev, ev_link); *eventp = NULL; } else if (rl->state == isc_ratelimiter_idle) { result = isc_timer_reset(rl->timer, isc_timertype_ticker, NULL, &rl->interval, ISC_FALSE); if (result == ISC_R_SUCCESS) { ev->ev_sender = task; rl->state = isc_ratelimiter_ratelimited; } } else { INSIST(rl->state == isc_ratelimiter_shuttingdown); result = ISC_R_SHUTTINGDOWN; } UNLOCK(&rl->lock); if (*eventp != NULL && result == ISC_R_SUCCESS) isc_task_send(task, eventp); return (result); }
static void recv_message(isc_task_t *task, isc_event_t *ev_in) { isc_socketevent_t *ev = (isc_socketevent_t *)ev_in; isc_event_t *dev; isccc_ccmsg_t *ccmsg = ev_in->ev_arg; (void)task; INSIST(VALID_CCMSG(ccmsg)); dev = &ccmsg->event; if (ev->result != ISC_R_SUCCESS) { ccmsg->result = ev->result; goto send_and_free; } ccmsg->result = ISC_R_SUCCESS; isc_buffer_add(&ccmsg->buffer, ev->n); ccmsg->address = ev->address; send_and_free: isc_task_send(ccmsg->task, &dev); ccmsg->task = NULL; isc_event_free(&ev_in); }
static void recvresponse(isc_task_t *task, isc_event_t *event) { dns_requestevent_t *reqev = (dns_requestevent_t *)event; isc_result_t result, result2; dns_message_t *query = NULL, *response = NULL; isc_buffer_t outtoken; isc_buffer_t outbuf; char output[10 * 1024]; unsigned char array[DNS_NAME_MAXTEXT + 1]; isc_buffer_init(&outtoken, array, sizeof(array)); UNUSED(task); REQUIRE(reqev != NULL); query = reqev->ev_arg; if (reqev->result != ISC_R_SUCCESS) { fprintf(stderr, "I:request event result: %s\n", isc_result_totext(reqev->result)); goto end; } response = NULL; result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response); CHECK("dns_message_create", result); printf("\nReceived Response:\n"); result2 = dns_request_getresponse(reqev->request, response, DNS_MESSAGEPARSE_PRESERVEORDER); isc_buffer_init(&outbuf, output, sizeof(output)); result = dns_message_totext(response, &dns_master_style_debug, 0, &outbuf); CHECK("dns_message_totext", result); printf("%.*s\n", (int)isc_buffer_usedlength(&outbuf), (char *)isc_buffer_base(&outbuf)); CHECK("dns_request_getresponse", result2); if (response != NULL) dns_message_destroy(&response); end: if (query != NULL) dns_message_destroy(&query); if (reqev->request != NULL) dns_request_destroy(&reqev->request); isc_event_free(&event); event = isc_event_allocate(mctx, (void *)1, 1, console, NULL, sizeof(*event)); isc_task_send(task, &event); return; }
static void recv_length(isc_task_t *task, isc_event_t *ev_in) { isc_socketevent_t *ev = (isc_socketevent_t *)ev_in; isc_event_t *dev; dns_tcpmsg_t *tcpmsg = ev_in->ev_arg; isc_region_t region; isc_result_t result; INSIST(VALID_TCPMSG(tcpmsg)); dev = &tcpmsg->event; tcpmsg->address = ev->address; if (ev->result != ISC_R_SUCCESS) { tcpmsg->result = ev->result; goto send_and_free; } /* * Success. */ tcpmsg->size = ntohs(tcpmsg->size); if (tcpmsg->size == 0) { tcpmsg->result = ISC_R_UNEXPECTEDEND; goto send_and_free; } if (tcpmsg->size > tcpmsg->maxsize) { tcpmsg->result = ISC_R_RANGE; goto send_and_free; } region.base = isc_mem_get(tcpmsg->mctx, tcpmsg->size); region.length = tcpmsg->size; if (region.base == NULL) { tcpmsg->result = ISC_R_NOMEMORY; goto send_and_free; } XDEBUG(("Allocated %d bytes\n", tcpmsg->size)); isc_buffer_init(&tcpmsg->buffer, region.base, region.length); result = isc_socket_recv(tcpmsg->sock, ®ion, 0, task, recv_message, tcpmsg); if (result != ISC_R_SUCCESS) { tcpmsg->result = result; goto send_and_free; } isc_event_free(&ev_in); return; send_and_free: isc_task_send(tcpmsg->task, &dev); tcpmsg->task = NULL; isc_event_free(&ev_in); return; }
static void recv_length(isc_task_t *task, isc_event_t *ev_in) { isc_socketevent_t *ev = (isc_socketevent_t *)ev_in; isc_event_t *dev; isccc_ccmsg_t *ccmsg = ev_in->ev_arg; isc_region_t region; isc_result_t result; INSIST(VALID_CCMSG(ccmsg)); dev = &ccmsg->event; if (ev->result != ISC_R_SUCCESS) { ccmsg->result = ev->result; goto send_and_free; } /* * Success. */ ccmsg->size = ntohl(ccmsg->size); if (ccmsg->size == 0) { ccmsg->result = ISC_R_UNEXPECTEDEND; goto send_and_free; } if (ccmsg->size > ccmsg->maxsize) { ccmsg->result = ISC_R_RANGE; goto send_and_free; } region.base = isc_mem_get(ccmsg->mctx, ccmsg->size); region.length = ccmsg->size; if (region.base == NULL) { ccmsg->result = ISC_R_NOMEMORY; goto send_and_free; } isc_buffer_init(&ccmsg->buffer, region.base, region.length); result = isc_socket_recv(ccmsg->sock, ®ion, 0, task, recv_message, ccmsg); if (result != ISC_R_SUCCESS) { ccmsg->result = result; goto send_and_free; } isc_event_free(&ev_in); return; send_and_free: isc_task_send(ccmsg->task, &dev); ccmsg->task = NULL; isc_event_free(&ev_in); return; }
void dighost_shutdown(void) { isc_event_t *event = global_event; flush_lookup_list(); debug("dighost_shutdown()"); if (!in_use) { isc_app_shutdown(); return; } isc_task_send(global_task, &event); }
static void console(isc_task_t *task, isc_event_t *event) { char buf[32]; int c; isc_event_t *ev = NULL; isc_event_free(&event); for (;;) { printf("\nCommand => "); c = scanf("%31s", buf); if (c == EOF || strcmp(buf, "quit") == 0) { isc_app_shutdown(); return; } if (strcmp(buf, "initctx") == 0) { ev = isc_event_allocate(mctx, (void *)1, 1, initctx1, NULL, sizeof(*event)); isc_task_send(task, &ev); return; } if (strcmp(buf, "query") == 0) { ev = isc_event_allocate(mctx, (void *)1, 1, sendquery, NULL, sizeof(*event)); isc_task_send(task, &ev); return; } printf("Unknown command\n"); } }
static void ratelimiter_tick (isc_task_t * task, isc_event_t * event) { isc_result_t result = ISC_R_SUCCESS; isc_ratelimiter_t *rl = (isc_ratelimiter_t *) event->ev_arg; isc_event_t *p; isc_uint32_t pertic; UNUSED (task); isc_event_free (&event); pertic = rl->pertic; while (pertic != 0) { pertic--; LOCK (&rl->lock); p = ISC_LIST_HEAD (rl->pending); if (p != NULL) { /* * There is work to do. Let's do it after unlocking. */ ISC_LIST_UNLINK (rl->pending, p, ev_link); } else { /* * No work left to do. Stop the timer so that we don't * waste resources by having it fire periodically. */ result = isc_timer_reset (rl->timer, isc_timertype_inactive, NULL, NULL, ISC_FALSE); RUNTIME_CHECK (result == ISC_R_SUCCESS); rl->state = isc_ratelimiter_idle; pertic = 0; /* Force the loop to exit. */ } UNLOCK (&rl->lock); if (p != NULL) { isc_task_t *evtask = p->ev_sender; isc_task_send (evtask, &p); } INSIST (p == NULL); } }
void do_xadd(isc_task_t *task, isc_event_t *ev) { counter_t *state = (counter_t *)ev->ev_arg; int i; for (i = 0 ; i < COUNTS_PER_ITERATION ; i++) { isc_atomic_xadd(&counter_32, 1); } state->iteration++; if (state->iteration < ITERATIONS) { isc_task_send(task, &ev); } else { isc_event_free(&ev); } }
static void tick(isc_task_t *task, isc_event_t *event) { t_info *info = event->ev_arg; isc_event_t *nevent; INSIST(event->ev_type == ISC_TIMEREVENT_TICK); printf("task %s (%p) tick\n", info->name, task); info->ticks++; if (strcmp(info->name, "1") == 0) { if (info->ticks == 10) { RUNTIME_CHECK(isc_app_shutdown() == ISC_R_SUCCESS); } else if (info->ticks >= 15 && info->exiting) { isc_timer_detach(&info->timer); isc_task_detach(&info->task); nevent = isc_event_allocate(info->mctx, info, T2_SHUTDOWNDONE, t1_shutdown, &tasks[0], sizeof(*event)); RUNTIME_CHECK(nevent != NULL); isc_task_send(info->peer, &nevent); isc_task_detach(&info->peer); } } else if (strcmp(info->name, "foo") == 0) { isc_timer_detach(&info->timer); nevent = isc_event_allocate(info->mctx, info, FOO_EVENT, foo_event, task, sizeof(*event)); RUNTIME_CHECK(nevent != NULL); isc_task_sendanddetach(&task, &nevent); } isc_event_free(&event); }
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(); }
int main(int argc, char *argv[]) { isc_taskmgr_t *manager = NULL; isc_task_t *t1 = NULL, *t2 = NULL; isc_task_t *t3 = NULL, *t4 = NULL; isc_event_t *event; unsigned int workers; isc_timermgr_t *timgr; isc_timer_t *ti1, *ti2; struct isc_interval interval; if (argc > 1) { workers = atoi(argv[1]); if (workers < 1) workers = 1; if (workers > 8192) workers = 8192; } else workers = 2; printf("%d workers\n", workers); RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, 0, &manager) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_task_create(manager, 0, &t1) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_task_create(manager, 0, &t2) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_task_create(manager, 0, &t3) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_task_create(manager, 0, &t4) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_task_onshutdown(t1, my_shutdown, "1") == ISC_R_SUCCESS); RUNTIME_CHECK(isc_task_onshutdown(t2, my_shutdown, "2") == ISC_R_SUCCESS); RUNTIME_CHECK(isc_task_onshutdown(t3, my_shutdown, "3") == ISC_R_SUCCESS); RUNTIME_CHECK(isc_task_onshutdown(t4, my_shutdown, "4") == ISC_R_SUCCESS); timgr = NULL; RUNTIME_CHECK(isc_timermgr_create(mctx, &timgr) == ISC_R_SUCCESS); ti1 = NULL; isc_interval_set(&interval, 1, 0); RUNTIME_CHECK(isc_timer_create(timgr, isc_timertype_ticker, NULL, &interval, t1, my_tick, "foo", &ti1) == ISC_R_SUCCESS); ti2 = NULL; isc_interval_set(&interval, 1, 0); RUNTIME_CHECK(isc_timer_create(timgr, isc_timertype_ticker, NULL, &interval, t2, my_tick, "bar", &ti2) == ISC_R_SUCCESS); printf("task 1 = %p\n", t1); printf("task 2 = %p\n", t2); sleep(2); /* * Note: (void *)1 is used as a sender here, since some compilers * don't like casting a function pointer to a (void *). * * In a real use, it is more likely the sender would be a * structure (socket, timer, task, etc) but this is just a test * program. */ event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "1", sizeof(*event)); isc_task_send(t1, &event); event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "1", sizeof(*event)); isc_task_send(t1, &event); event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "1", sizeof(*event)); isc_task_send(t1, &event); event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "1", sizeof(*event)); isc_task_send(t1, &event); event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "1", sizeof(*event)); isc_task_send(t1, &event); event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "1", sizeof(*event)); isc_task_send(t1, &event); event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "1", sizeof(*event)); isc_task_send(t1, &event); event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "1", sizeof(*event)); isc_task_send(t1, &event); event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "1", sizeof(*event)); isc_task_send(t1, &event); event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "2", sizeof(*event)); isc_task_send(t2, &event); event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "3", sizeof(*event)); isc_task_send(t3, &event); event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "4", sizeof(*event)); isc_task_send(t4, &event); event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "2", sizeof(*event)); isc_task_send(t2, &event); event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "3", sizeof(*event)); isc_task_send(t3, &event); event = isc_event_allocate(mctx, (void *)1, 1, my_callback, "4", sizeof(*event)); isc_task_send(t4, &event); isc_task_purgerange(t3, NULL, ISC_EVENTTYPE_FIRSTEVENT, ISC_EVENTTYPE_LASTEVENT, NULL); isc_task_detach(&t1); isc_task_detach(&t2); isc_task_detach(&t3); isc_task_detach(&t4); sleep(10); printf("destroy\n"); isc_timer_detach(&ti1); isc_timer_detach(&ti2); isc_timermgr_destroy(&timgr); isc_taskmgr_destroy(&manager); printf("destroyed\n"); isc_mem_stats(mctx, stdout); isc_mem_destroy(&mctx); return (0); }
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(); }
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); }
static void initctx2(isc_task_t *task, isc_event_t *event) { dns_requestevent_t *reqev = (dns_requestevent_t *)event; isc_result_t result; dns_message_t *query = NULL, *response = NULL; isc_buffer_t outtoken; unsigned char array[DNS_NAME_MAXTEXT + 1]; dns_rdataset_t *rdataset; dns_rdatatype_t qtype; dns_name_t *question_name; UNUSED(task); REQUIRE(reqev != NULL); query = reqev->ev_arg; if (reqev->result != ISC_R_SUCCESS) { fprintf(stderr, "I:request event result: %s\n", isc_result_totext(reqev->result)); goto end; } response = NULL; result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response); CHECK("dns_message_create", result); result = dns_request_getresponse(reqev->request, response, DNS_MESSAGEPARSE_PRESERVEORDER); CHECK("dns_request_getresponse", result); if (response->rcode != dns_rcode_noerror) { result = ISC_RESULTCLASS_DNSRCODE + response->rcode; fprintf(stderr, "I:response rcode: %s\n", isc_result_totext(result)); goto end; } printf("Received token from server, calling gss_init_sec_context()\n"); isc_buffer_init(&outtoken, array, DNS_NAME_MAXTEXT + 1); result = dns_tkey_processgssresponse(query, response, dns_fixedname_name(&gssname), &gssctx, &outtoken, &tsigkey, ring, NULL); gssctx = *gssctxp; CHECK("dns_tkey_processgssresponse", result); printf("Context accepted\n"); question_name = NULL; dns_message_currentname(response, DNS_SECTION_ANSWER, &question_name); rdataset = ISC_LIST_HEAD(question_name->list); INSIST(rdataset != NULL); qtype = rdataset->type; if (qtype == dns_rdatatype_tkey) { printf("Received TKEY response from server\n"); printf("Context completed\n"); } else { printf("Did not receive TKEY response from server\n"); printf("Context not completed\n"); dns_tsigkey_detach(&tsigkey); tsigkey = NULL; } dns_message_destroy(&response); end: if (query != NULL) dns_message_destroy(&query); if (reqev->request != NULL) dns_request_destroy(&reqev->request); isc_event_free(&event); event = isc_event_allocate(mctx, (void *)1, 1, console, NULL, sizeof(*event)); isc_task_send(task, &event); return; }
static void dispatch(isc__timermgr_t *manager, isc_time_t *now) { isc_boolean_t done = ISC_FALSE, post_event, need_schedule; isc_timerevent_t *event; isc_eventtype_t type = 0; isc__timer_t *timer; isc_result_t result; isc_boolean_t idle; /*! * The caller must be holding the manager lock. */ while (manager->nscheduled > 0 && !done) { timer = isc_heap_element(manager->heap, 1); INSIST(timer->type != isc_timertype_inactive); if (isc_time_compare(now, &timer->due) >= 0) { if (timer->type == isc_timertype_ticker) { type = ISC_TIMEREVENT_TICK; post_event = ISC_TRUE; need_schedule = ISC_TRUE; } else if (timer->type == isc_timertype_limited) { int cmp; cmp = isc_time_compare(now, &timer->expires); if (cmp >= 0) { type = ISC_TIMEREVENT_LIFE; post_event = ISC_TRUE; need_schedule = ISC_FALSE; } else { type = ISC_TIMEREVENT_TICK; post_event = ISC_TRUE; need_schedule = ISC_TRUE; } } else if (!isc_time_isepoch(&timer->expires) && isc_time_compare(now, &timer->expires) >= 0) { type = ISC_TIMEREVENT_LIFE; post_event = ISC_TRUE; need_schedule = ISC_FALSE; } else { idle = ISC_FALSE; LOCK(&timer->lock); if (!isc_time_isepoch(&timer->idle) && isc_time_compare(now, &timer->idle) >= 0) { idle = ISC_TRUE; } UNLOCK(&timer->lock); if (idle) { type = ISC_TIMEREVENT_IDLE; post_event = ISC_TRUE; need_schedule = ISC_FALSE; } else { /* * Idle timer has been touched; * reschedule. */ XTRACEID(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TIMER, ISC_MSG_IDLERESCHED, "idle reschedule"), timer); post_event = ISC_FALSE; need_schedule = ISC_TRUE; } } if (post_event) { XTRACEID(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TIMER, ISC_MSG_POSTING, "posting"), timer); /* * XXX We could preallocate this event. */ event = (isc_timerevent_t *)isc_event_allocate(manager->mctx, timer, type, timer->action, timer->arg, sizeof(*event)); if (event != NULL) { event->due = timer->due; isc_task_send(timer->task, ISC_EVENT_PTR(&event)); } else UNEXPECTED_ERROR(__FILE__, __LINE__, "%s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_TIMER, ISC_MSG_EVENTNOTALLOC, "couldn't " "allocate event")); } timer->index = 0; isc_heap_delete(manager->heap, 1); manager->nscheduled--; if (need_schedule) { result = schedule(timer, now, ISC_FALSE); if (result != ISC_R_SUCCESS) UNEXPECTED_ERROR(__FILE__, __LINE__, "%s: %u", isc_msgcat_get(isc_msgcat, ISC_MSGSET_TIMER, ISC_MSG_SCHEDFAIL, "couldn't schedule " "timer"), result); } } else { manager->due = timer->due; done = ISC_TRUE; } } }
static void initctx1(isc_task_t *task, isc_event_t *event) { char gssid[512]; char contextname[512]; isc_result_t result; isc_buffer_t buf; dns_message_t *query; dns_request_t *request; int c; isc_event_free(&event); printf("Initctx - GSS name => "); c = scanf("%511s", gssid); if (c == EOF) return; snprintf(contextname, sizeof(contextname), "gsstest.context.%d.", (int)time(NULL)); printf("Initctx - context name we're using: %s\n", contextname); printf("Negotiating GSSAPI context: "); printf("%s", gssid); printf("\n"); /* * Setup a GSSAPI context with the server */ dns_fixedname_init(&servername); isc_buffer_init(&buf, contextname, strlen(contextname)); isc_buffer_add(&buf, strlen(contextname)); result = dns_name_fromtext(dns_fixedname_name(&servername), &buf, dns_rootname, 0, NULL); CHECK("dns_name_fromtext", result); /* Make name happen */ dns_fixedname_init(&gssname); isc_buffer_init(&buf, gssid, strlen(gssid)); isc_buffer_add(&buf, strlen(gssid)); result = dns_name_fromtext(dns_fixedname_name(&gssname), &buf, dns_rootname, 0, NULL); CHECK("dns_name_fromtext", result); query = NULL; result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &query); CHECK("dns_message_create", result); printf("Calling gss_init_sec_context()\n"); gssctx = GSS_C_NO_CONTEXT; result = dns_tkey_buildgssquery(query, dns_fixedname_name(&servername), dns_fixedname_name(&gssname), NULL, 36000, &gssctx, ISC_TRUE, mctx, NULL); CHECK("dns_tkey_buildgssquery", result); printf("Sending context token to server\n"); request = NULL; result = dns_request_create(requestmgr, query, &address, 0, NULL, TIMEOUT, task, initctx2, query, &request); CHECK("dns_request_create", result); return; end: event = isc_event_allocate(mctx, (void *)1, 1, console, NULL, sizeof(*event)); isc_task_send(task, &event);return; }