示例#1
0
文件: t_timers.c 项目: jhbsz/netbsd
static void
t5_tick_event(isc_task_t *task, isc_event_t *event) {
	isc_result_t	isc_result;
	isc_time_t	expires;
	isc_interval_t	interval;

	UNUSED(task);

	++T5_eventcnt;
	t_info("t5_tick_event %d\n", T5_eventcnt);

	/*
	 * On the first tick, purge all remaining tick events
	 * and then shut down the task.
	 */
	if (T5_eventcnt == 1) {
		isc_time_settoepoch(&expires);
		isc_interval_set(&interval, T5_SECONDS, 0);
		isc_result = isc_timer_reset(T5_tickertimer,
					     isc_timertype_ticker, &expires,
					     &interval, ISC_TRUE);
		if (isc_result != ISC_R_SUCCESS) {
			t_info("isc_timer_reset failed %s\n",
			       isc_result_totext(isc_result));
			++T5_nfails;
		}
		isc_task_shutdown(task);
	}
	isc_event_free(&event);
}
示例#2
0
文件: t_timers.c 项目: jhbsz/netbsd
static void
t4(void) {
	int		result;
	isc_time_t	expires;
	isc_interval_t	interval;

	t_assert("isc_timer_reset", 4, T_REQUIRED, "%s", a4);

	if (threaded) {
		Tx_nfails = 0;
		Tx_nprobs = 0;
		Tx_nevents = 3;
		Tx_seconds = T4_SECONDS;
		Tx_nanoseconds = T4_NANOSECONDS;

		isc_interval_set(&interval, T4_SECONDS, T4_NANOSECONDS);
		isc_time_settoepoch(&expires);
		t_timers_x(isc_timertype_ticker, &expires, &interval, t4_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();
}
示例#3
0
static t_info *
new_task(isc_mem_t *mctx, const char *name) {
	t_info *ti;
	isc_time_t expires;
	isc_interval_t interval;

	RUNTIME_CHECK(task_count < MAX_TASKS);
	ti = &tasks[task_count];
	ti->mctx = mctx;
	ti->task = NULL;
	ti->timer = NULL;
	ti->ticks = 0;
	if (name != NULL) {
		INSIST(strlen(name) < sizeof(ti->name));
		strcpy(ti->name, name);
	} else
		sprintf(ti->name, "%d", task_count);
	RUNTIME_CHECK(isc_task_create(task_manager, 0, &ti->task) ==
		      ISC_R_SUCCESS);
	RUNTIME_CHECK(isc_task_onshutdown(ti->task, shutdown_action, ti) ==
		      ISC_R_SUCCESS);

	isc_time_settoepoch(&expires);
	isc_interval_set(&interval, 1, 0);
	RUNTIME_CHECK(isc_timer_create(timer_manager, isc_timertype_ticker,
				       &expires, &interval, ti->task,
				       tick, ti, &ti->timer) ==
		      ISC_R_SUCCESS);

	task_count++;

	return (ti);
}
示例#4
0
void
dns_badcache_flushtree(dns_badcache_t *bc, dns_name_t *name) {
	dns_bcentry_t *bad, *prev, *next;
	unsigned int i;
	int n;
	isc_time_t now;
	isc_result_t result;

	REQUIRE(VALID_BADCACHE(bc));
	REQUIRE(name != NULL);

	LOCK(&bc->lock);

	result = isc_time_now(&now);
	if (result != ISC_R_SUCCESS)
		isc_time_settoepoch(&now);

	for (i = 0; bc->count > 0 && i < bc->size; i++) {
		prev = NULL;
		for (bad = bc->table[i]; bad != NULL; bad = next) {
			next = bad->next;
			n = isc_time_compare(&bad->expire, &now);
			if (n < 0 || dns_name_issubdomain(&bad->name, name)) {
				if (prev == NULL)
					bc->table[i] = bad->next;
				else
					prev->next = bad->next;

				isc_mem_put(bc->mctx, bad, sizeof(*bad) +
					    bad->name.length);
				bc->count--;
			} else
				prev = bad;
		}
	}

	UNLOCK(&bc->lock);
}
示例#5
0
void
dns_badcache_flushname(dns_badcache_t *bc, dns_name_t *name) {
	dns_bcentry_t *bad, *prev, *next;
	isc_result_t result;
	isc_time_t now;
	unsigned int i;

	REQUIRE(VALID_BADCACHE(bc));
	REQUIRE(name != NULL);

	LOCK(&bc->lock);

	result = isc_time_now(&now);
	if (result != ISC_R_SUCCESS)
		isc_time_settoepoch(&now);
	i = dns_name_hash(name, ISC_FALSE) % bc->size;
	prev = NULL;
	for (bad = bc->table[i]; bad != NULL; bad = next) {
		int n;
		next = bad->next;
		n = isc_time_compare(&bad->expire, &now);
		if (n < 0 || dns_name_equal(name, &bad->name)) {
			if (prev == NULL)
				bc->table[i] = bad->next;
			else
				prev->next = bad->next;

			isc_mem_put(bc->mctx, bad, sizeof(*bad) +
				    bad->name.length);
			bc->count--;
		} else
			prev = bad;
	}

	UNLOCK(&bc->lock);
}
示例#6
0
ISC_TIMERFUNC_SCOPE isc_result_t
isc__timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) {
	isc__timermgr_t *manager;
	isc_result_t result;

	/*
	 * Create a timer manager.
	 */

	REQUIRE(managerp != NULL && *managerp == NULL);

#ifdef USE_SHARED_MANAGER
	if (timermgr != NULL) {
		timermgr->refs++;
		*managerp = (isc_timermgr_t *)timermgr;
		return (ISC_R_SUCCESS);
	}
#endif /* USE_SHARED_MANAGER */

	manager = isc_mem_get(mctx, sizeof(*manager));
	if (manager == NULL)
		return (ISC_R_NOMEMORY);

	manager->common.impmagic = TIMER_MANAGER_MAGIC;
	manager->common.magic = ISCAPI_TIMERMGR_MAGIC;
	manager->common.methods = (isc_timermgrmethods_t *)&timermgrmethods;
	manager->mctx = NULL;
	manager->done = ISC_FALSE;
	INIT_LIST(manager->timers);
	manager->nscheduled = 0;
	isc_time_settoepoch(&manager->due);
	manager->heap = NULL;
	result = isc_heap_create(mctx, sooner, set_index, 0, &manager->heap);
	if (result != ISC_R_SUCCESS) {
		INSIST(result == ISC_R_NOMEMORY);
		isc_mem_put(mctx, manager, sizeof(*manager));
		return (ISC_R_NOMEMORY);
	}
	result = isc_mutex_init(&manager->lock);
	if (result != ISC_R_SUCCESS) {
		isc_heap_destroy(&manager->heap);
		isc_mem_put(mctx, manager, sizeof(*manager));
		return (result);
	}
	isc_mem_attach(mctx, &manager->mctx);
#ifdef USE_TIMER_THREAD
	if (isc_condition_init(&manager->wakeup) != ISC_R_SUCCESS) {
		isc_mem_detach(&manager->mctx);
		DESTROYLOCK(&manager->lock);
		isc_heap_destroy(&manager->heap);
		isc_mem_put(mctx, manager, sizeof(*manager));
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "isc_condition_init() %s",
				 isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
						ISC_MSG_FAILED, "failed"));
		return (ISC_R_UNEXPECTED);
	}
	if (isc_thread_create(run, manager, &manager->thread) !=
	    ISC_R_SUCCESS) {
		isc_mem_detach(&manager->mctx);
		(void)isc_condition_destroy(&manager->wakeup);
		DESTROYLOCK(&manager->lock);
		isc_heap_destroy(&manager->heap);
		isc_mem_put(mctx, manager, sizeof(*manager));
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "isc_thread_create() %s",
				 isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
						ISC_MSG_FAILED, "failed"));
		return (ISC_R_UNEXPECTED);
	}
#endif
#ifdef USE_SHARED_MANAGER
	manager->refs = 1;
	timermgr = manager;
#endif /* USE_SHARED_MANAGER */

	*managerp = (isc_timermgr_t *)manager;

	return (ISC_R_SUCCESS);
}
示例#7
0
ISC_TIMERFUNC_SCOPE isc_result_t
isc__timer_reset(isc_timer_t *timer0, isc_timertype_t type,
		 isc_time_t *expires, isc_interval_t *interval,
		 isc_boolean_t purge)
{
	isc__timer_t *timer = (isc__timer_t *)timer0;
	isc_time_t now;
	isc__timermgr_t *manager;
	isc_result_t result;

	/*
	 * Change the timer's type, expires, and interval values to the given
	 * values.  If 'purge' is ISC_TRUE, any pending events from this timer
	 * are purged from its task's event queue.
	 */

	REQUIRE(VALID_TIMER(timer));
	manager = timer->manager;
	REQUIRE(VALID_MANAGER(manager));

	if (expires == NULL)
		expires = isc_time_epoch;
	if (interval == NULL)
		interval = isc_interval_zero;
	REQUIRE(type == isc_timertype_inactive ||
		!(isc_time_isepoch(expires) && isc_interval_iszero(interval)));
	REQUIRE(type != isc_timertype_limited ||
		!(isc_time_isepoch(expires) || isc_interval_iszero(interval)));

	/*
	 * Get current time.
	 */
	if (type != isc_timertype_inactive) {
		TIME_NOW(&now);
	} else {
		/*
		 * We don't have to do this, but it keeps the compiler from
		 * complaining about "now" possibly being used without being
		 * set, even though it will never actually happen.
		 */
		isc_time_settoepoch(&now);
	}

	LOCK(&manager->lock);
	LOCK(&timer->lock);

	if (purge)
		(void)isc_task_purgerange(timer->task,
					  timer,
					  ISC_TIMEREVENT_FIRSTEVENT,
					  ISC_TIMEREVENT_LASTEVENT,
					  NULL);
	timer->type = type;
	timer->expires = *expires;
	timer->interval = *interval;
	if (type == isc_timertype_once && !isc_interval_iszero(interval)) {
		result = isc_time_add(&now, interval, &timer->idle);
	} else {
		isc_time_settoepoch(&timer->idle);
		result = ISC_R_SUCCESS;
	}

	if (result == ISC_R_SUCCESS) {
		if (type == isc_timertype_inactive) {
			deschedule(timer);
			result = ISC_R_SUCCESS;
		} else
			result = schedule(timer, &now, ISC_TRUE);
	}

	UNLOCK(&timer->lock);
	UNLOCK(&manager->lock);

	return (result);
}
示例#8
0
ISC_TIMERFUNC_SCOPE isc_result_t
isc__timer_create(isc_timermgr_t *manager0, isc_timertype_t type,
		  isc_time_t *expires, isc_interval_t *interval,
		  isc_task_t *task, isc_taskaction_t action, const void *arg,
		  isc_timer_t **timerp)
{
	isc__timermgr_t *manager = (isc__timermgr_t *)manager0;
	isc__timer_t *timer;
	isc_result_t result;
	isc_time_t now;

	/*
	 * Create a new 'type' timer managed by 'manager'.  The timers
	 * parameters are specified by 'expires' and 'interval'.  Events
	 * will be posted to 'task' and when dispatched 'action' will be
	 * called with 'arg' as the arg value.  The new timer is returned
	 * in 'timerp'.
	 */

	REQUIRE(VALID_MANAGER(manager));
	REQUIRE(task != NULL);
	REQUIRE(action != NULL);
	if (expires == NULL)
		expires = isc_time_epoch;
	if (interval == NULL)
		interval = isc_interval_zero;
	REQUIRE(type == isc_timertype_inactive ||
		!(isc_time_isepoch(expires) && isc_interval_iszero(interval)));
	REQUIRE(timerp != NULL && *timerp == NULL);
	REQUIRE(type != isc_timertype_limited ||
		!(isc_time_isepoch(expires) || isc_interval_iszero(interval)));

	/*
	 * Get current time.
	 */
	if (type != isc_timertype_inactive) {
		TIME_NOW(&now);
	} else {
		/*
		 * We don't have to do this, but it keeps the compiler from
		 * complaining about "now" possibly being used without being
		 * set, even though it will never actually happen.
		 */
		isc_time_settoepoch(&now);
	}


	timer = isc_mem_get(manager->mctx, sizeof(*timer));
	if (timer == NULL)
		return (ISC_R_NOMEMORY);

	timer->manager = manager;
	timer->references = 1;

	if (type == isc_timertype_once && !isc_interval_iszero(interval)) {
		result = isc_time_add(&now, interval, &timer->idle);
		if (result != ISC_R_SUCCESS) {
			isc_mem_put(manager->mctx, timer, sizeof(*timer));
			return (result);
		}
	} else
		isc_time_settoepoch(&timer->idle);

	timer->type = type;
	timer->expires = *expires;
	timer->interval = *interval;
	timer->task = NULL;
	isc_task_attach(task, &timer->task);
	timer->action = action;
	/*
	 * Removing the const attribute from "arg" is the best of two
	 * evils here.  If the timer->arg member is made const, then
	 * it affects a great many recipients of the timer event
	 * which did not pass in an "arg" that was truly const.
	 * Changing isc_timer_create() to not have "arg" prototyped as const,
	 * though, can cause compilers warnings for calls that *do*
	 * have a truly const arg.  The caller will have to carefully
	 * keep track of whether arg started as a true const.
	 */
	DE_CONST(arg, timer->arg);
	timer->index = 0;
	result = isc_mutex_init(&timer->lock);
	if (result != ISC_R_SUCCESS) {
		isc_task_detach(&timer->task);
		isc_mem_put(manager->mctx, timer, sizeof(*timer));
		return (result);
	}
	ISC_LINK_INIT(timer, link);
	timer->common.impmagic = TIMER_MAGIC;
	timer->common.magic = ISCAPI_TIMER_MAGIC;
	timer->common.methods = (isc_timermethods_t *)&timermethods;

	LOCK(&manager->lock);

	/*
	 * Note we don't have to lock the timer like we normally would because
	 * there are no external references to it yet.
	 */

	if (type != isc_timertype_inactive)
		result = schedule(timer, &now, ISC_TRUE);
	else
		result = ISC_R_SUCCESS;
	if (result == ISC_R_SUCCESS)
		APPEND(manager->timers, timer, link);

	UNLOCK(&manager->lock);

	if (result != ISC_R_SUCCESS) {
		timer->common.impmagic = 0;
		timer->common.magic = 0;
		DESTROYLOCK(&timer->lock);
		isc_task_detach(&timer->task);
		isc_mem_put(manager->mctx, timer, sizeof(*timer));
		return (result);
	}

	*timerp = (isc_timer_t *)timer;

	return (ISC_R_SUCCESS);
}
示例#9
0
void
dns_badcache_add(dns_badcache_t *bc, dns_name_t *name,
		 dns_rdatatype_t type, isc_boolean_t update,
		 isc_uint32_t flags, isc_time_t *expire)
{
	isc_result_t result;
	unsigned int i, hashval;
	dns_bcentry_t *bad, *prev, *next;
	isc_time_t now;

	REQUIRE(VALID_BADCACHE(bc));
	REQUIRE(name != NULL);
	REQUIRE(expire != NULL);

	LOCK(&bc->lock);

	result = isc_time_now(&now);
	if (result != ISC_R_SUCCESS)
		isc_time_settoepoch(&now);

	hashval = dns_name_hash(name, ISC_FALSE);
	i = hashval % bc->size;
	prev = NULL;
	for (bad = bc->table[i]; bad != NULL; bad = next) {
		next = bad->next;
		if (bad->type == type && dns_name_equal(name, &bad->name)) {
			if (update) {
				bad->expire = *expire;
				bad->flags = flags;
			}
			break;
		}
		if (isc_time_compare(&bad->expire, &now) < 0) {
			if (prev == NULL)
				bc->table[i] = bad->next;
			else
				prev->next = bad->next;
			isc_mem_put(bc->mctx, bad,
				    sizeof(*bad) + bad->name.length);
			bc->count--;
		} else
			prev = bad;
	}

	if (bad == NULL) {
		isc_buffer_t buffer;
		bad = isc_mem_get(bc->mctx, sizeof(*bad) + name->length);
		if (bad == NULL)
			goto cleanup;
		bad->type = type;
		bad->hashval = hashval;
		bad->expire = *expire;
		bad->flags = flags;
		isc_buffer_init(&buffer, bad + 1, name->length);
		dns_name_init(&bad->name, NULL);
		dns_name_copy(name, &bad->name, &buffer);
		bad->next = bc->table[i];
		bc->table[i] = bad;
		bc->count++;
		if (bc->count > bc->size * 8)
			badcache_resize(bc, &now, ISC_TRUE);
		if (bc->count < bc->size * 2 && bc->size > bc->minsize)
			badcache_resize(bc, &now, ISC_FALSE);
	} else
		bad->expire = *expire;

 cleanup:
	UNLOCK(&bc->lock);
}
示例#10
0
文件: t_timers.c 项目: jhbsz/netbsd
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);
}
示例#11
0
文件: t_timers.c 项目: jhbsz/netbsd
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);

}
示例#12
0
int
main(int argc, char *argv[]) {
	isc_task_t *t1, *t2;
	isc_timermgr_t *timgr;
	isc_time_t expires;
	isc_interval_t interval;
	isc_timer_t *ti1;
	unsigned int workers;
	isc_socketmgr_t *socketmgr;
	isc_socket_t *so1, *so2;
	isc_sockaddr_t sockaddr;
	struct in_addr ina;
	struct in6_addr in6a;
	isc_result_t result;
	int pf;

	if (argc > 1)
		workers = atoi(argv[1]);
	else
		workers = 2;
	printf("%d workers\n", workers);

	if (isc_net_probeipv6() == ISC_R_SUCCESS)
		pf = PF_INET6;
	else
		pf = PF_INET;

	/*
	 * EVERYTHING needs a memory context.
	 */
	mctx = NULL;
	RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);

	/*
	 * The task manager is independent (other than memory context)
	 */
	manager = NULL;
	RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, 0, &manager) ==
		      ISC_R_SUCCESS);

	/*
	 * Timer manager depends only on the memory context as well.
	 */
	timgr = NULL;
	RUNTIME_CHECK(isc_timermgr_create(mctx, &timgr) == ISC_R_SUCCESS);

	t1 = NULL;
	RUNTIME_CHECK(isc_task_create(manager, 0, &t1) == ISC_R_SUCCESS);
	t2 = NULL;
	RUNTIME_CHECK(isc_task_create(manager, 0, &t2) == 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);

	printf("task 1 = %p\n", t1);
	printf("task 2 = %p\n", t2);

	socketmgr = NULL;
	RUNTIME_CHECK(isc_socketmgr_create(mctx, &socketmgr) == ISC_R_SUCCESS);

	/*
	 * Open up a listener socket.
	 */
	so1 = NULL;

	if (pf == PF_INET6) {
		in6a = in6addr_any;
		isc_sockaddr_fromin6(&sockaddr, &in6a, 5544);
	} else {
		ina.s_addr = INADDR_ANY;
		isc_sockaddr_fromin(&sockaddr, &ina, 5544);
	}
	RUNTIME_CHECK(isc_socket_create(socketmgr, pf, isc_sockettype_tcp,
					&so1) == ISC_R_SUCCESS);
	result = isc_socket_bind(so1, &sockaddr, ISC_SOCKET_REUSEADDRESS);
	RUNTIME_CHECK(result == ISC_R_SUCCESS);
	RUNTIME_CHECK(isc_socket_listen(so1, 0) == ISC_R_SUCCESS);

	/*
	 * Queue up the first accept event.
	 */
	RUNTIME_CHECK(isc_socket_accept(so1, t1, my_listen, "so1")
		      == ISC_R_SUCCESS);
	isc_time_settoepoch(&expires);
	isc_interval_set(&interval, 10, 0);
	ti1 = NULL;
	RUNTIME_CHECK(isc_timer_create(timgr, isc_timertype_once, &expires,
				       &interval, t1, timeout, so1, &ti1) ==
		      ISC_R_SUCCESS);

	/*
	 * Open up a socket that will connect to www.flame.org, port 80.
	 * Why not.  :)
	 */
	so2 = NULL;
	ina.s_addr = inet_addr("204.152.184.97");
	if (0 && pf == PF_INET6)
		isc_sockaddr_v6fromin(&sockaddr, &ina, 80);
	else
		isc_sockaddr_fromin(&sockaddr, &ina, 80);
	RUNTIME_CHECK(isc_socket_create(socketmgr, isc_sockaddr_pf(&sockaddr),
					isc_sockettype_tcp,
					&so2) == ISC_R_SUCCESS);

	RUNTIME_CHECK(isc_socket_connect(so2, &sockaddr, t2,
					 my_connect, "so2") == ISC_R_SUCCESS);

	/*
	 * Detaching these is safe, since the socket will attach to the
	 * task for any outstanding requests.
	 */
	isc_task_detach(&t1);
	isc_task_detach(&t2);

	/*
	 * Wait a short while.
	 */
	sleep(10);

	fprintf(stderr, "Destroying socket manager\n");
	isc_socketmgr_destroy(&socketmgr);

	fprintf(stderr, "Destroying timer manager\n");
	isc_timermgr_destroy(&timgr);

	fprintf(stderr, "Destroying task manager\n");
	isc_taskmgr_destroy(&manager);

	isc_mem_stats(mctx, stdout);
	isc_mem_destroy(&mctx);

	return (0);
}