⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 t_timers.c

📁 package of develop dns
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-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_timers.c,v 1.22.206.2 2004/06/21 06:57:59 marka Exp $ */#include <config.h>#include <stdlib.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;#endif#define	Tx_FUDGE_SECONDS	0	     /* in absence of clock_getres() */#define	Tx_FUDGE_NANOSECONDS	500000000    /* in absence of clock_getres() */static	isc_time_t	Tx_endtime;static	isc_time_t	Tx_lasttime;static	int		Tx_eventcnt;static	int		Tx_nevents;static	isc_mutex_t	Tx_mx;static	isc_condition_t	Tx_cv;static	int		Tx_nfails;static	int		Tx_nprobs;static	isc_timer_t    *Tx_timer;static	int		Tx_seconds;static	int		Tx_nanoseconds;static voidrequire_threads(void) {	t_info("This test requires threads\n");	t_result(T_THREADONLY);	return;}static voidtx_sde(isc_task_t *task, isc_event_t *event) {	isc_result_t	isc_result;	task = task;	event = event;	/*	 * Signal shutdown processing complete.	 */	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));		++Tx_nprobs;	}	isc_result = isc_condition_signal(&Tx_cv);	if (isc_result != ISC_R_SUCCESS) {		t_info("isc_condition_signal 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_event_free(&event);}static voidtx_te(isc_task_t *task, isc_event_t *event) {	isc_result_t	isc_result;	isc_time_t	now;	isc_time_t	base;	isc_time_t	ulim;	isc_time_t	llim;	isc_interval_t	interval;	isc_eventtype_t	expected_event_type;	++Tx_eventcnt;	t_info("tick %d\n", Tx_eventcnt);	expected_event_type = ISC_TIMEREVENT_LIFE;	if ((isc_timertype_t) event->ev_arg == isc_timertype_ticker)		expected_event_type = ISC_TIMEREVENT_TICK;	if (event->ev_type != expected_event_type) {		t_info("expected event type %d, got %d\n",			expected_event_type, (int) event->ev_type);		++Tx_nfails;	}	isc_result = isc_time_now(&now);	if (isc_result == ISC_R_SUCCESS) {		interval.seconds = Tx_seconds;		interval.nanoseconds = Tx_nanoseconds;		isc_result = isc_time_add(&Tx_lasttime, &interval, &base);		if (isc_result != ISC_R_SUCCESS) {			t_info("isc_time_add failed %s\n",			       isc_result_totext(isc_result));			++Tx_nprobs;		}	} else {		t_info("isc_time_now failed %s\n",			isc_result_totext(isc_result));		++Tx_nprobs;	}	if (isc_result == ISC_R_SUCCESS) {		interval.seconds = Tx_FUDGE_SECONDS;		interval.nanoseconds = Tx_FUDGE_NANOSECONDS;		isc_result = isc_time_add(&base, &interval, &ulim);		if (isc_result != ISC_R_SUCCESS) {			t_info("isc_time_add failed %s\n",			       isc_result_totext(isc_result));			++Tx_nprobs;		}	}	if (isc_result == ISC_R_SUCCESS) {		isc_result = isc_time_subtract(&base, &interval, &llim);		if (isc_result != ISC_R_SUCCESS) {			t_info("isc_time_subtract failed %s\n",			       isc_result_totext(isc_result));			++Tx_nprobs;		}	}	if (isc_result == ISC_R_SUCCESS) {		if (isc_time_compare(&llim, &now) > 0) {			t_info("timer range error: early by "			       "%lu microseconds\n",			       (unsigned long)isc_time_microdiff(&base, &now));			++Tx_nfails;		} else if (isc_time_compare(&ulim, &now) < 0) {			t_info("timer range error: late by "			       "%lu microseconds\n",			       (unsigned long)isc_time_microdiff(&now, &base));			++Tx_nfails;		}		Tx_lasttime = now;	}	if (Tx_eventcnt == Tx_nevents) {		isc_result = isc_time_now(&Tx_endtime);		if (isc_result != ISC_R_SUCCESS) {			t_info("isc_time_now failed %s\n",				isc_result_totext(isc_result));			++Tx_nprobs;		}		isc_timer_detach(&Tx_timer);		isc_task_shutdown(task);	}	isc_event_free(&event);}static voidt_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);		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);		isc_condition_destroy(&Tx_cv);		isc_mem_destroy(&mctx);		++Tx_nprobs;		return;	}	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);		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);		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);		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);		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);		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);	isc_condition_destroy(&Tx_cv);	isc_mem_destroy(&mctx);}#define	T1_SECONDS	2#define	T1_NANOSECONDS	500000000static const char *a1 =	"When type is isc_timertype_ticker, a call to isc_timer_create() "	"creates a timer that posts an ISC_TIMEREVENT_TICK event to the "	"specified task every 'interval' seconds and returns ISC_R_SUCCESS.";static voidt1(void) {	int		result;	isc_time_t	expires;	isc_interval_t	interval;	t_assert("isc_timer_create", 1, T_REQUIRED, a1);	if (threaded) {		Tx_nfails	= 0;		Tx_nprobs	= 0;		Tx_nevents	= 12;		Tx_seconds	= T1_SECONDS;		Tx_nanoseconds	= T1_NANOSECONDS;		isc_interval_set(&interval, Tx_seconds, Tx_nanoseconds);		isc_time_settoepoch(&expires);		t_timers_x(isc_timertype_ticker, &expires, &interval, tx_te);		result = T_UNRESOLVED;		if ((Tx_nfails == 0) && (Tx_nprobs == 0))			result = T_PASS;		else if (Tx_nfails)			result = T_FAIL;		t_result(result);	} else		require_threads();}#define	T2_SECONDS	5#define	T2_NANOSECONDS	300000000;static const char *a2 =	"When type is isc_timertype_once, a call to isc_timer_create() "	"creates a timer that posts an ISC_TIMEEVENT_LIFE event to the "	"specified task when the current time reaches or exceeds the time "	"specified by 'expires'.";static voidt2(void) {	int		result;	int		isc_result;	isc_time_t	expires;	isc_interval_t	interval;	t_assert("isc_timer_create", 2, T_REQUIRED, a2);	if (threaded) {		Tx_nfails	= 0;		Tx_nprobs	= 0;		Tx_nevents	= 1;		Tx_seconds	= T2_SECONDS;		Tx_nanoseconds	= T2_NANOSECONDS;		isc_interval_set(&interval, Tx_seconds, Tx_nanoseconds);		isc_result = isc_time_nowplusinterval(&expires, &interval);		if (isc_result == ISC_R_SUCCESS) {			isc_interval_set(&interval, 0, 0);			t_timers_x(isc_timertype_once, &expires, &interval,				   tx_te);		} else {			t_info("isc_time_nowplusinterval failed %s\n",			       isc_result_totext(isc_result));		}		result = T_UNRESOLVED;		if ((Tx_nfails == 0) && (Tx_nprobs == 0))			result = T_PASS;		else if (Tx_nfails)			result = T_FAIL;		t_result(result);	} else		require_threads();}static voidt3_te(isc_task_t *task, isc_event_t *event) {	isc_result_t	isc_result;	isc_time_t	now;	isc_time_t	base;	isc_time_t	ulim;	isc_time_t	llim;	isc_interval_t	interval;	++Tx_eventcnt;	t_info("tick %d\n", Tx_eventcnt);	isc_result = isc_time_now(&now);	if (isc_result != ISC_R_SUCCESS) {		t_info("isc_time_now failed %s\n",		       isc_result_totext(isc_result));		++Tx_nprobs;	}	if (isc_result == ISC_R_SUCCESS) {		interval.seconds = Tx_seconds;		interval.nanoseconds = Tx_nanoseconds;		isc_result = isc_time_add(&Tx_lasttime, &interval, &base);		if (isc_result != ISC_R_SUCCESS) {			t_info("isc_time_add failed %s\n",			       isc_result_totext(isc_result));			++Tx_nprobs;		}	}	if (isc_result == ISC_R_SUCCESS) {		interval.seconds = Tx_FUDGE_SECONDS;		interval.nanoseconds = Tx_FUDGE_NANOSECONDS;		isc_result = isc_time_add(&base, &interval, &ulim);		if (isc_result != ISC_R_SUCCESS) {			t_info("isc_time_add failed %s\n",			       isc_result_totext(isc_result));			++Tx_nprobs;		}	}	if (isc_result == ISC_R_SUCCESS) {		isc_result = isc_time_subtract(&base, &interval, &llim);		if (isc_result != ISC_R_SUCCESS) {			t_info("isc_time_subtract failed %s\n",			       isc_result_totext(isc_result));			++Tx_nprobs;		}	}	if (isc_result == ISC_R_SUCCESS) {		if (isc_time_compare(&llim, &now) > 0) {			t_info("timer range error: early by "			       "%lu microseconds\n",			       (unsigned long)isc_time_microdiff(&base, &now));			++Tx_nfails;		} else if (isc_time_compare(&ulim, &now) < 0) {			t_info("timer range error: late by "			       "%lu microseconds\n",			       (unsigned long)isc_time_microdiff(&now, &base));			++Tx_nfails;		}		Tx_lasttime = now;	}	if (event->ev_type != ISC_TIMEREVENT_IDLE) {		t_info("received event type %d, expected type %d\n",		       event->ev_type, ISC_TIMEREVENT_IDLE);		++Tx_nfails;	}	isc_timer_detach(&Tx_timer);	isc_task_shutdown(task);	isc_event_free(&event);}#define	T3_SECONDS	4#define	T3_NANOSECONDS	400000000static const char *a3 =	"When type is isc_timertype_once, a call to isc_timer_create() "	"creates a timer that posts an ISC_TIMEEVENT_IDLE event to the "	"specified task when the timer has been idle for 'interval' seconds.";static voidt3(void) {	int		result;	int		isc_result;	isc_time_t	expires;	isc_interval_t	interval;	t_assert("isc_timer_create", 3, T_REQUIRED, a3);	if (threaded) {		Tx_nfails	= 0;		Tx_nprobs	= 0;		Tx_nevents	= 1;		Tx_seconds	= T3_SECONDS;		Tx_nanoseconds	= T3_NANOSECONDS;		isc_interval_set(&interval, Tx_seconds + 1, Tx_nanoseconds);		isc_result = isc_time_nowplusinterval(&expires, &interval);		if (isc_result == ISC_R_SUCCESS) {			isc_interval_set(&interval, Tx_seconds,					 Tx_nanoseconds);			t_timers_x(isc_timertype_once, &expires, &interval,				   t3_te);		} else {			t_info("isc_time_nowplusinterval failed %s\n",			       isc_result_totext(isc_result));			++Tx_nprobs;		}		result = T_UNRESOLVED;		if ((Tx_nfails == 0) && (Tx_nprobs == 0))			result = T_PASS;		else if (Tx_nfails)			result = T_FAIL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -