📄 t_tasks.c
字号:
/* * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. *//* $Id: t_tasks.c,v 1.29.12.6 2004/09/21 02:39:03 marka Exp $ */#include <config.h>#include <stdlib.h>#include <unistd.h>#include <isc/condition.h>#include <isc/mem.h>#include <isc/platform.h>#include <isc/task.h>#include <isc/time.h>#include <isc/timer.h>#include <isc/util.h>#include <tests/t_api.h>#ifdef ISC_PLATFORM_USETHREADSisc_boolean_t threaded = ISC_TRUE;#elseisc_boolean_t threaded = ISC_FALSE;#endifstatic int senders[4];static voidrequire_threads(void) { t_info("This test requires threads\n"); t_result(T_THREADONLY); return;}static voidt1_callback(isc_task_t *task, isc_event_t *event) { int i; int j; UNUSED(task); j = 0; for (i = 0; i < 1000000; i++) j += 100; t_info("task %s\n", (char *)event->ev_arg); isc_event_free(&event);}static voidt1_shutdown(isc_task_t *task, isc_event_t *event) { UNUSED(task); t_info("shutdown %s\n", (char *)event->ev_arg); isc_event_free(&event);}static voidmy_tick(isc_task_t *task, isc_event_t *event) { UNUSED(task); t_info("%s\n", (char *)event->ev_arg); isc_event_free(&event);}/* * Adapted from RTH's original task_test program */static intt_tasks1(void) { char *p; isc_mem_t *mctx; isc_taskmgr_t *manager; isc_task_t *task1; isc_task_t *task2; isc_task_t *task3; isc_task_t *task4; isc_event_t *event; unsigned int workers; isc_timermgr_t *timgr; isc_timer_t *ti1; isc_timer_t *ti2; isc_result_t isc_result; struct isc_time absolute; struct isc_interval interval; manager = NULL; task1 = NULL; task2 = NULL; task3 = NULL; task4 = NULL; mctx = NULL; workers = 2; p = t_getenv("ISC_TASK_WORKERS"); if (p != NULL) workers = atoi(p); if (workers < 1) { t_info("Bad config value for ISC_TASK_WORKERS, %d\n", workers); return(T_UNRESOLVED); } isc_result = isc_mem_create(0, 0, &mctx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mem_create failed %d\n", isc_result); return(T_UNRESOLVED); } isc_result = isc_taskmgr_create(mctx, workers, 0, &manager); if (isc_result != ISC_R_SUCCESS) { t_info("isc_taskmgr_create failed %d\n", isc_result); return(T_FAIL); } isc_result = isc_task_create(manager, 0, &task1); if (isc_result != ISC_R_SUCCESS) { t_info("isc_task_create failed %d\n", isc_result); return(T_FAIL); } isc_result = isc_task_create(manager, 0, &task2); if (isc_result != ISC_R_SUCCESS) { t_info("isc_task_create failed %d\n", isc_result); return(T_FAIL); } isc_result = isc_task_create(manager, 0, &task3); if (isc_result != ISC_R_SUCCESS) { t_info("isc_task_create failed %d\n", isc_result); return(T_FAIL); } isc_result = isc_task_create(manager, 0, &task4); if (isc_result != ISC_R_SUCCESS) { t_info("isc_task_create failed %d\n", isc_result); return(T_FAIL); } isc_result = isc_task_onshutdown(task1, t1_shutdown, "1"); if (isc_result != ISC_R_SUCCESS) { t_info("isc_task_onshutdown failed %d\n", isc_result); return(T_FAIL); } isc_result = isc_task_onshutdown(task2, t1_shutdown, "2"); if (isc_result != ISC_R_SUCCESS) { t_info("isc_task_onshutdown failed %d\n", isc_result); return(T_FAIL); } isc_result = isc_task_onshutdown(task3, t1_shutdown, "3"); if (isc_result != ISC_R_SUCCESS) { t_info("isc_task_onshutdown failed %d\n", isc_result); return(T_FAIL); } isc_result = isc_task_onshutdown(task4, t1_shutdown, "4"); if (isc_result != ISC_R_SUCCESS) { t_info("isc_task_onshutdown failed %d\n", isc_result); return(T_FAIL); } timgr = NULL; isc_result = isc_timermgr_create(mctx, &timgr); if (isc_result != ISC_R_SUCCESS) { t_info("isc_timermgr_create %d\n", isc_result); return(T_UNRESOLVED); } ti1 = NULL; isc_time_settoepoch(&absolute); isc_interval_set(&interval, 1, 0); isc_result = isc_timer_create(timgr, isc_timertype_ticker, &absolute, &interval, task1, my_tick, "tick", &ti1); if (isc_result != ISC_R_SUCCESS) { t_info("isc_timer_create %d\n", isc_result); return(T_UNRESOLVED); } ti2 = NULL; isc_time_settoepoch(&absolute); isc_interval_set(&interval, 1, 0); isc_result = isc_timer_create(timgr, isc_timertype_ticker, &absolute, &interval, task2, my_tick, "tock", &ti2); if (isc_result != ISC_R_SUCCESS) { t_info("isc_timer_create %d\n", isc_result); return(T_UNRESOLVED); } 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, t1_callback, "1", sizeof(*event)); if (event == NULL) { t_info("isc_event_allocate failed\n"); return(T_UNRESOLVED); } isc_task_send(task1, &event); event = isc_event_allocate(mctx, (void *)1, 1, t1_callback, "1", sizeof(*event)); if (event == NULL) { t_info("isc_event_allocate failed\n"); return(T_UNRESOLVED); } isc_task_send(task1, &event); event = isc_event_allocate(mctx, (void *)1, 1, t1_callback, "1", sizeof(*event)); if (event == NULL) { t_info("isc_event_allocate failed\n"); return(T_UNRESOLVED); } isc_task_send(task1, &event); event = isc_event_allocate(mctx, (void *)1, 1, t1_callback, "1", sizeof(*event)); if (event == NULL) { t_info("isc_event_allocate failed\n"); return(T_UNRESOLVED); } isc_task_send(task1, &event); event = isc_event_allocate(mctx, (void *)1, 1, t1_callback, "1", sizeof(*event)); if (event == NULL) { t_info("isc_event_allocate failed\n"); return(T_UNRESOLVED); } isc_task_send(task1, &event); event = isc_event_allocate(mctx, (void *)1, 1, t1_callback, "1", sizeof(*event)); if (event == NULL) { t_info("isc_event_allocate failed\n"); return(T_UNRESOLVED); } isc_task_send(task1, &event); event = isc_event_allocate(mctx, (void *)1, 1, t1_callback, "1", sizeof(*event)); if (event == NULL) { t_info("isc_event_allocate failed\n"); return(T_UNRESOLVED); } isc_task_send(task1, &event); event = isc_event_allocate(mctx, (void *)1, 1, t1_callback, "1", sizeof(*event)); if (event == NULL) { t_info("isc_event_allocate failed\n"); return(T_UNRESOLVED); } isc_task_send(task1, &event); event = isc_event_allocate(mctx, (void *)1, 1, t1_callback, "1", sizeof(*event)); if (event == NULL) { t_info("isc_event_allocate failed\n"); return(T_UNRESOLVED); } isc_task_send(task1, &event); event = isc_event_allocate(mctx, (void *)1, 1, t1_callback, "2", sizeof(*event)); if (event == NULL) { t_info("isc_event_allocate failed\n"); return(T_UNRESOLVED); } isc_task_send(task2, &event); event = isc_event_allocate(mctx, (void *)1, 1, t1_callback, "3", sizeof(*event)); if (event == NULL) { t_info("isc_event_allocate failed\n"); return(T_UNRESOLVED); } isc_task_send(task3, &event); event = isc_event_allocate(mctx, (void *)1, 1, t1_callback, "4", sizeof(*event)); if (event == NULL) { t_info("isc_event_allocate failed\n"); return(T_UNRESOLVED); } isc_task_send(task4, &event); event = isc_event_allocate(mctx, (void *)1, 1, t1_callback, "2", sizeof(*event)); if (event == NULL) { t_info("isc_event_allocate failed\n"); return(T_UNRESOLVED); } isc_task_send(task2, &event); event = isc_event_allocate(mctx, (void *)1, 1, t1_callback, "3", sizeof(*event)); if (event == NULL) { t_info("isc_event_allocate failed\n"); return(T_UNRESOLVED); } isc_task_send(task3, &event); event = isc_event_allocate(mctx, (void *)1, 1, t1_callback, "4", sizeof(*event)); if (event == NULL) { t_info("isc_event_allocate failed\n"); return(T_UNRESOLVED); } isc_task_send(task4, &event); (void)isc_task_purge(task3, NULL, 0, 0); isc_task_detach(&task1); isc_task_detach(&task2); isc_task_detach(&task3); isc_task_detach(&task4); sleep(10); isc_timer_detach(&ti1); isc_timer_detach(&ti2); isc_timermgr_destroy(&timgr); isc_taskmgr_destroy(&manager); isc_mem_destroy(&mctx); return(T_PASS);}static const char *a1 = "The task subsystem can create and manage tasks";static voidt1(void) { int result; t_assert("tasks", 1, T_REQUIRED, a1); result = t_tasks1(); t_result(result);}#define T2_NTASKS 10000static isc_event_t *T2_event;static isc_taskmgr_t *T2_manager;static isc_mem_t *T2_mctx;static isc_condition_t T2_cv;static isc_mutex_t T2_mx;static int T2_done;static int T2_nprobs;static int T2_nfails;static int T2_ntasks;static voidt2_shutdown(isc_task_t *task, isc_event_t *event) { isc_result_t isc_result; task = task; /* notused */ if (event->ev_arg != NULL) { isc_task_destroy((isc_task_t**) &event->ev_arg); } else { isc_result = isc_mutex_lock(&T2_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mutex_lock failed %d\n", isc_result); ++T2_nprobs; } T2_done = 1; isc_result = isc_condition_signal(&T2_cv); if (isc_result != ISC_R_SUCCESS) { t_info("isc_condition_signal failed %d\n", isc_result); ++T2_nprobs; } isc_result = isc_mutex_unlock(&T2_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mutex_unlock failed %d\n", isc_result); ++T2_nprobs; } isc_event_free(&T2_event); isc_taskmgr_destroy(&T2_manager); isc_mem_destroy(&T2_mctx); }}static voidt2_callback(isc_task_t *task, isc_event_t *event) { isc_result_t isc_result; isc_task_t *newtask; ++T2_ntasks; if (T_debug && ((T2_ntasks % 100) == 0)) { t_info("T2_ntasks %d\n", T2_ntasks); } if (event->ev_arg) { event->ev_arg = (void *)(((int) event->ev_arg) - 1); /* * Create a new task and forward the message. */ newtask = NULL; isc_result = isc_task_create(T2_manager, 0, &newtask); if (isc_result != ISC_R_SUCCESS) { t_info("isc_task_create failed %d\n", isc_result); ++T2_nfails; return; } isc_result = isc_task_onshutdown(newtask, t2_shutdown, (void *)task); if (isc_result != ISC_R_SUCCESS) { t_info("isc_task_onshutdown failed %d\n", isc_result); ++T2_nfails; return; } isc_task_send(newtask, &event); } else { /* * Time to unwind, shutdown should perc back up. */ isc_task_destroy(&task); }}static intt_tasks2(void) { int ntasks; int result; char *p; isc_event_t *event; unsigned int workers; isc_result_t isc_result; T2_manager = NULL; T2_done = 0; T2_nprobs = 0; T2_nfails = 0; T2_ntasks = 0; workers = 2; p = t_getenv("ISC_TASK_WORKERS"); if (p != NULL) workers = atoi(p); if (workers < 1) { t_info("Bad config value for ISC_TASK_WORKERS, %d\n", workers); return(T_UNRESOLVED); } p = t_getenv("ISC_TASKS_MIN"); if (p != NULL) ntasks = atoi(p); else ntasks = T2_NTASKS; if (ntasks == 0) { t_info("Bad config value for ISC_TASKS_MIN, %d\n", ntasks); return(T_UNRESOLVED); } t_info("Testing with %d tasks\n", ntasks); isc_result = isc_mutex_init(&T2_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mutex_init failed %d\n", isc_result); return(T_UNRESOLVED); } isc_result = isc_condition_init(&T2_cv); if (isc_result != ISC_R_SUCCESS) { t_info("isc_condition_init failed %d\n", isc_result); return(T_UNRESOLVED); } isc_result = isc_mem_create(0, 0, &T2_mctx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mem_create failed %d\n", isc_result); return(T_UNRESOLVED); } isc_result = isc_taskmgr_create(T2_mctx, workers, 0, &T2_manager); if (isc_result != ISC_R_SUCCESS) { t_info("isc_taskmgr_create failed %d\n", isc_result); return(T_FAIL); } T2_event = isc_event_allocate(T2_mctx, (void *)1, 1, t2_callback, (void *)ntasks, sizeof(*event)); if (T2_event == NULL) { t_info("isc_event_allocate failed\n"); return(T_UNRESOLVED); } isc_result = isc_mutex_lock(&T2_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mutex_lock failed %d\n", isc_result); return(T_UNRESOLVED); } t2_callback(NULL, T2_event); while (T2_done == 0) { isc_result = isc_condition_wait(&T2_cv, &T2_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_condition_wait failed %d\n", isc_result); return(T_UNRESOLVED); } } result = T_UNRESOLVED; if ((T2_nfails == 0) && (T2_nprobs == 0)) result = T_PASS; else if (T2_nfails != 0) result = T_FAIL; return(result);}static const char *a2 = "The task subsystem can create ISC_TASKS_MIN tasks";static void
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -