Beispiel #1
0
void
_bufferevent_init_generic_timeout_cbs(struct bufferevent *bev)
{
	evtimer_assign(&bev->ev_read, bev->ev_base,
	    bufferevent_generic_read_timeout_cb, bev);
	evtimer_assign(&bev->ev_write, bev->ev_base,
	    bufferevent_generic_write_timeout_cb, bev);
}
Beispiel #2
0
void run_in_event_loop(
    const lambda::function<void(void)>& f,
    EventLoopLogicFlow event_loop_logic_flow)
{
    if (__in_event_loop__ && event_loop_logic_flow == ALLOW_SHORT_CIRCUIT) {
        f();
        return;
    }

    synchronized (functions_mutex) {
        functions->push(f);

        // Add an event and activate it to interrupt the event loop.
        // TODO(jmlvanre): after libevent v 2.1 we can use
        // event_self_cbarg instead of re-assigning the event. For now we
        // manually re-assign the event to pass in the pointer to the
        // event itself as the callback argument.
        event* ev = evtimer_new(base, async_function, NULL);

        // 'event_assign' is only valid on non-pending AND non-active
        // events. This means we have to assign the callback before
        // calling 'event_active'.
        if (evtimer_assign(ev, base, async_function, ev) < 0) {
            LOG(FATAL) << "Failed to assign callback on event";
        }

        event_active(ev, EV_TIMEOUT, 0);
    }
}
static void dns_cb(int errcode, struct evutil_addrinfo *addr, void *ptr)
{
	struct evutil_addrinfo *ai;
	struct timeval tv;
	const char *host = ptr;

	if (errcode) {
		tmate_status_message("%s lookup failure. Retrying in %d seconds (%s)",
				     host, TMATE_DNS_RETRY_TIMEOUT,
				     evutil_gai_strerror(errcode));

		tv.tv_sec = TMATE_DNS_RETRY_TIMEOUT;
		tv.tv_usec = 0;

		evtimer_assign(&tmate_session.ev_dns_retry, tmate_session.ev_base,
			       on_dns_retry, NULL);
		evtimer_add(&tmate_session.ev_dns_retry, &tv);

		return;
	}

	tmate_status_message("Connecting to %s...", host);

	for (ai = addr; ai; ai = ai->ai_next) {
		char buf[128];
		const char *ip = NULL;
		if (ai->ai_family == AF_INET) {
			struct sockaddr_in *sin = (struct sockaddr_in *)ai->ai_addr;
			ip = evutil_inet_ntop(AF_INET, &sin->sin_addr, buf, 128);
		} else if (ai->ai_family == AF_INET6) {
			struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ai->ai_addr;
			ip = evutil_inet_ntop(AF_INET6, &sin6->sin6_addr, buf, 128);
		}

		tmate_debug("Trying server %s", ip);

		/*
		 * Note: We don't deal with the client list. Clients manage it
		 * and free client structs when necessary.
		 */
		(void)tmate_ssh_client_alloc(&tmate_session, ip);
	}

	evutil_freeaddrinfo(addr);

	/*
	 * XXX For some reason, freeing the DNS resolver makes MacOSX flip out...
	 * not sure what's going on...
	 * evdns_base_free(tmate_session.ev_dnsbase, 0);
	 * tmate_session.ev_dnsbase = NULL;
	 */
}
Beispiel #4
0
int add_timer(struct timeval t, struct event *event_timer)
{
	if (!event_timer) {
		event_timer = evtimer_new(base, cb_timer, NULL);
		if (!event_timer) {
			log4c_category_log(mycat, LOG4C_PRIORITY_ERROR, "%s %d: evtimer_new failed[%d]", __FUNCTION__, __LINE__, errno);					
			return (-1);
		}
		event_timer->ev_arg = event_timer;
	} else {
		evtimer_assign(event_timer, base, event_timer->ev_callback, NULL);
	}

	return evtimer_add(event_timer, &t);
}
Beispiel #5
0
static void create_base()
{
	signal(SIGINT,sig_int);
//	strTag->pid = getpid();
	struct event_base *base = event_base_new();
	struct timeval tv = {5,0};
	struct event sig;
	struct event timeout;
	evtimer_assign(&timeout,base,timerout1,&timeout);
	evtimer_add(&timeout,&tv);
	evsignal_assign(&sig,base,SIGUSR2,sig_act1,&sig);
	evsignal_add(&sig,NULL);
	event_base_dispatch(base);
	printf("child break loopbase!!\n");
	event_base_free(base);
	sleep(5);
}
Beispiel #6
0
static THREAD_FN
basic_thread(void *arg)
{
	struct cond_wait cw;
	struct event_base *base = arg;
	struct event ev;
	int i = 0;

	EVTHREAD_ALLOC_LOCK(cw.lock, 0);
	EVTHREAD_ALLOC_COND(cw.cond);
	assert(cw.lock);
	assert(cw.cond);

	evtimer_assign(&ev, base, wake_all_timeout, &cw);
	for (i = 0; i < NUM_ITERATIONS; i++) {
		struct timeval tv;
		evutil_timerclear(&tv);
		tv.tv_sec = 0;
		tv.tv_usec = 3000;

		EVLOCK_LOCK(cw.lock, 0);
		/* we need to make sure that event does not happen before
		 * we get to wait on the conditional variable */
		assert(evtimer_add(&ev, &tv) == 0);

		assert(EVTHREAD_COND_WAIT(cw.cond, cw.lock) == 0);
		EVLOCK_UNLOCK(cw.lock, 0);

		EVLOCK_LOCK(count_lock, 0);
		++count;
		EVLOCK_UNLOCK(count_lock, 0);
	}

	/* exit the loop only if all threads fired all timeouts */
	EVLOCK_LOCK(count_lock, 0);
	if (count >= NUM_THREADS * NUM_ITERATIONS)
		event_base_loopexit(base, NULL);
	EVLOCK_UNLOCK(count_lock, 0);

	EVTHREAD_FREE_LOCK(cw.lock, 0);
	EVTHREAD_FREE_COND(cw.cond);

	THREAD_RETURN();
}
void printflike2 tmate_notify_later(int timeout, const char *fmt, ...)
{
	struct timeval tv;
	va_list ap;
	char *msg;

	tv.tv_sec = timeout;
	tv.tv_usec = 0;

	va_start(ap, fmt);
	xvasprintf(&msg, fmt, ap);
	va_end(ap);

	/*
	 * FIXME leaks like crazy when calling tmate_notify_later()
	 * multiple times.
	 */

	evtimer_assign(&tmate_encoder->ev_notify_timer, ev_base,
		       __tmate_notify_later, msg);
	evtimer_add(&tmate_encoder->ev_notify_timer, &tv);
}
static void
pthread_basic(struct event_base *base)
{
	pthread_t threads[NUM_THREADS];
	struct event ev;
	struct timeval tv;
	int i;

	for (i = 0; i < NUM_THREADS; ++i)
		pthread_create(&threads[i], NULL, basic_thread, base);

	evtimer_assign(&ev, base, NULL, NULL);
	evutil_timerclear(&tv);
	tv.tv_sec = 1000;
	event_add(&ev, &tv);

	event_base_dispatch(base);

	for (i = 0; i < NUM_THREADS; ++i)
		pthread_join(threads[i], NULL);

	event_del(&ev);
}
static void *
basic_thread(void *arg)
{
	struct cond_wait cw;
	struct event_base *base = arg;
	struct event ev;
	int i = 0;

	assert(pthread_mutex_init(&cw.lock, NULL) == 0);
	assert(pthread_cond_init(&cw.cond, NULL) == 0);

	evtimer_assign(&ev, base, basic_timeout, &cw);
	for (i = 0; i < 100; i++) {
		struct timeval tv;
		evutil_timerclear(&tv);
		assert(evtimer_add(&ev, &tv) == 0);

		assert(pthread_mutex_lock(&cw.lock) == 0);
		assert(pthread_cond_wait(&cw.cond, &cw.lock) == 0);
		assert(pthread_mutex_unlock(&cw.lock) == 0);

		assert(pthread_mutex_lock(&count_lock) == 0);
		++count;
		assert(pthread_mutex_unlock(&count_lock) == 0);
	}

	/* exit the loop only if all threads fired all timeouts */
	assert(pthread_mutex_lock(&count_lock) == 0);
	if (count >= NUM_THREADS * 100)
		event_base_loopexit(base, NULL);
	assert(pthread_mutex_unlock(&count_lock) == 0);

	assert(pthread_cond_destroy(&cw.cond) == 0);
	assert(pthread_mutex_destroy(&cw.lock) == 0);

	return (NULL);
}
Beispiel #10
0
static void
thread_conditions_simple(void *arg)
{
	struct timeval tv_signal, tv_timeout, tv_broadcast;
	struct alerted_record alerted[NUM_THREADS];
	THREAD_T threads[NUM_THREADS];
	struct cond_wait cond;
	int i;
	struct timeval launched_at;
	struct event wake_one;
	struct event wake_all;
	struct basic_test_data *data = arg;
	struct event_base *base = data->base;
	int n_timed_out=0, n_signal=0, n_broadcast=0;

	tv_signal.tv_sec = tv_timeout.tv_sec = tv_broadcast.tv_sec = 0;
	tv_signal.tv_usec = 30*1000;
	tv_timeout.tv_usec = 150*1000;
	tv_broadcast.tv_usec = 500*1000;

	EVTHREAD_ALLOC_LOCK(cond.lock, EVTHREAD_LOCKTYPE_RECURSIVE);
	EVTHREAD_ALLOC_COND(cond.cond);
	tt_assert(cond.lock);
	tt_assert(cond.cond);
	for (i = 0; i < NUM_THREADS; ++i) {
		memset(&alerted[i], 0, sizeof(struct alerted_record));
		alerted[i].cond = &cond;
	}

	/* Threads 5 and 6 will be allowed to time out */
	memcpy(&alerted[5].delay, &tv_timeout, sizeof(tv_timeout));
	memcpy(&alerted[6].delay, &tv_timeout, sizeof(tv_timeout));

	evtimer_assign(&wake_one, base, wake_one_timeout, &cond);
	evtimer_assign(&wake_all, base, wake_all_timeout, &cond);

	evutil_gettimeofday(&launched_at, NULL);

	/* Launch the threads... */
	for (i = 0; i < NUM_THREADS; ++i) {
		THREAD_START(threads[i], wait_for_condition, &alerted[i]);
	}

	/* Start the timers... */
	tt_int_op(event_add(&wake_one, &tv_signal), ==, 0);
	tt_int_op(event_add(&wake_all, &tv_broadcast), ==, 0);

	/* And run for a bit... */
	event_base_dispatch(base);

	/* And wait till the threads are done. */
	for (i = 0; i < NUM_THREADS; ++i)
		THREAD_JOIN(threads[i]);

	/* Now, let's see what happened. At least one of 5 or 6 should
	 * have timed out. */
	n_timed_out = alerted[5].timed_out + alerted[6].timed_out;
	tt_int_op(n_timed_out, >=, 1);
	tt_int_op(n_timed_out, <=, 2);

	for (i = 0; i < NUM_THREADS; ++i) {
		const struct timeval *target_delay;
		struct timeval target_time, actual_delay;
		if (alerted[i].timed_out) {
			TT_BLATHER(("%d looks like a timeout\n", i));
			target_delay = &tv_timeout;
			tt_assert(i == 5 || i == 6);
		} else if (evutil_timerisset(&alerted[i].alerted_at)) {
			long diff1,diff2;
			evutil_timersub(&alerted[i].alerted_at,
			    &launched_at, &actual_delay);
			diff1 = timeval_msec_diff(&actual_delay,
			    &tv_signal);
			diff2 = timeval_msec_diff(&actual_delay,
			    &tv_broadcast);
			if (abs(diff1) < abs(diff2)) {
				TT_BLATHER(("%d looks like a signal\n", i));
				target_delay = &tv_signal;
				++n_signal;
			} else {
				TT_BLATHER(("%d looks like a broadcast\n", i));
				target_delay = &tv_broadcast;
				++n_broadcast;
			}
		} else {
			TT_FAIL(("Thread %d never got woken", i));
			continue;
		}
		evutil_timeradd(target_delay, &launched_at, &target_time);
		test_timeval_diff_leq(&target_time, &alerted[i].alerted_at,
		    0, 50);
	}
	tt_int_op(n_broadcast + n_signal + n_timed_out, ==, NUM_THREADS);
	tt_int_op(n_signal, ==, 1);

end:
	;
}
static void
test_fin_cb_invoked(void *arg)
{
	struct basic_test_data *data = arg;
	struct event_base *base = data->base;

	struct event *ev;
	struct event ev2;
	struct event_callback evcb;
	int cb_called = 0;
	int ev_called = 0;

	const struct timeval ten_sec = {10,0};

	event_deferred_cb_init_(&evcb, 0, simple_callback, &cb_called);
	ev = evtimer_new(base, timer_callback, &ev_called);
	/* Just finalize them; don't bother adding. */
	event_free_finalize(0, ev, event_finalize_callback_1);
	event_callback_finalize_(base, 0, &evcb, callback_finalize_callback_1);

	event_base_dispatch(base);

	tt_int_op(cb_called, ==, 100);
	tt_int_op(ev_called, ==, 100);

	ev_called = cb_called = 0;
	event_base_assert_ok_(base);

	/* Now try it when they're active. (actually, don't finalize: make
	 * sure activation can happen! */
	ev = evtimer_new(base, timer_callback, &ev_called);
	event_deferred_cb_init_(&evcb, 0, simple_callback, &cb_called);

	event_active(ev, EV_TIMEOUT, 1);
	event_callback_activate_(base, &evcb);

	event_base_dispatch(base);
	tt_int_op(cb_called, ==, 1);
	tt_int_op(ev_called, ==, 1);

	ev_called = cb_called = 0;
	event_base_assert_ok_(base);

	/* Great, it worked. Now activate and finalize and make sure only
	 * finalizing happens. */
	event_active(ev, EV_TIMEOUT, 1);
	event_callback_activate_(base, &evcb);
	event_free_finalize(0, ev, event_finalize_callback_1);
	event_callback_finalize_(base, 0, &evcb, callback_finalize_callback_1);

	event_base_dispatch(base);
	tt_int_op(cb_called, ==, 100);
	tt_int_op(ev_called, ==, 100);

	ev_called = 0;

	event_base_assert_ok_(base);

	/* Okay, now add but don't have it become active, and make sure *that*
	 * works. */
	ev = evtimer_new(base, timer_callback, &ev_called);
	event_add(ev, &ten_sec);
	event_free_finalize(0, ev, event_finalize_callback_1);

	event_base_dispatch(base);
	tt_int_op(ev_called, ==, 100);

	ev_called = 0;
	event_base_assert_ok_(base);

	/* Now try adding and deleting after finalizing. */
	ev = evtimer_new(base, timer_callback, &ev_called);
	evtimer_assign(&ev2, base, timer_callback, &ev_called);
	event_add(ev, &ten_sec);
	event_free_finalize(0, ev, event_finalize_callback_1);
	event_finalize(0, &ev2, event_finalize_callback_1);

	event_add(&ev2, &ten_sec);
	event_del(ev);
	event_active(&ev2, EV_TIMEOUT, 1);

	event_base_dispatch(base);
	tt_int_op(ev_called, ==, 200);

	event_base_assert_ok_(base);

end:
	;
}
Beispiel #12
0
bool TimedEventWatcher::DoInit() 
{
    evtimer_assign(&event_, event_base_, TimedEventWatcher::HandlerFn, this);
    return true;
}