Beispiel #1
0
static void on_check(struct evwatch *watcher, const struct evwatch_check_cb_info *info, void *arg)
{
	struct timeval actual, delay;
	evutil_gettimeofday(&check_time, NULL);
	evutil_timersub(&check_time, &prepare_time, &actual);
	evutil_timersub(&actual, &expected, &delay);
	if (delay.tv_sec >= 0)
		histogram_update(delays, delay.tv_sec + delay.tv_usec / 1000000.0l);
}
Beispiel #2
0
static int
_ev_timeout_add(AvahiTimeout *t, const struct timeval *tv)
{
  struct timeval e_tv;
  struct timeval now;
  int ret;

  if (t->ev)
    event_free(t->ev);

  t->ev = evtimer_new(evbase_main, evcb_timeout, t);
  if (!t->ev)
    {
      DPRINTF(E_LOG, L_MDNS, "Could not make event in _ev_timeout_add - out of memory?\n");
      return -1;
    }

  if ((tv->tv_sec == 0) && (tv->tv_usec == 0))
    {
      evutil_timerclear(&e_tv);
    }
  else
    {
      ret = gettimeofday(&now, NULL);
      if (ret != 0)
	return -1;

      evutil_timersub(tv, &now, &e_tv);
    }

  return evtimer_add(t->ev, &e_tv);
}
Beispiel #3
0
Datei: path.c Projekt: a1406/txgg
int refresh_path(PATH *path, struct timeval *old, struct timeval *now, uint16_t speed)
{
	assert(path);
	assert(old);
	assert(now);
	struct timeval diff;
	if (*(uint32_t *)&path->end == *(uint32_t *)&path->begin)
		return (0);
	evutil_timersub(old, now, &diff);
	if (diff.tv_sec <= 0)
		return (0);

	int path_distance = getdistance(&path->begin, &path->end);
	int move_distance = speed * diff.tv_sec + speed * diff.tv_usec / 1000000;

	if (move_distance >= path_distance) {
		*(uint32_t *)&path->begin = *(uint32_t *)&path->end;
		return (0);
	}
	
	float rate = move_distance / path_distance;

    int x = path->end.pos_x - path->begin.pos_x;
    int y = path->end.pos_y - path->begin.pos_y;
	
	path->begin.pos_x += x * rate;
	path->begin.pos_y += y * rate;	
	return (0);
}
Beispiel #4
0
static void
errorcb(struct bufferevent *b, short what, void *arg)
{
	struct request_info *ri = arg;
	struct timeval now, diff;
	if (what & BEV_EVENT_EOF) {
		++total_n_handled;
		total_n_bytes += ri->n_read;
		evutil_gettimeofday(&now, NULL);
		evutil_timersub(&now, &ri->started, &diff);
		evutil_timeradd(&diff, &total_time, &total_time);

		if (total_n_handled && (total_n_handled%1000)==0)
			printf("%d requests done\n",total_n_handled);

		if (total_n_launched < N_REQUESTS) {
			if (launch_request() < 0)
				perror("Can't launch");
		}
	} else {
		++total_n_errors;
		perror("Unexpected error");
	}

	bufferevent_setcb(b, NULL, NULL, NULL, NULL);
	free(ri);
	bufferevent_disable(b, EV_READ|EV_WRITE);
	bufferevent_free(b);
}
Beispiel #5
0
static void
get_cpu_usage(struct cpu_usage_timer *timer, double *secElapsedOut,
    double *secUsedOut, double *usageOut)
{
#ifdef _WIN32
	double usertime_seconds, kerneltime_seconds;
	FILETIME createtime, exittime, usertimeEnd, kerneltimeEnd;
	int r;
#else
	clock_t ticksEnd;
#endif
	struct timeval timeEnd, timeDiff;
	double secondsPassed, secondsUsed;

#ifdef _WIN32
	r = GetThreadTimes(timer->thread, &createtime, &exittime,
	    &usertimeEnd, &kerneltimeEnd);
	if (r==0) printf("GetThreadTimes failed.");
	usertime_seconds = filetime_diff(&timer->usertimeBegin, &usertimeEnd);
	kerneltime_seconds = filetime_diff(&timer->kerneltimeBegin, &kerneltimeEnd);
	secondsUsed = kerneltime_seconds + usertime_seconds;
#else
	ticksEnd = clock();
	secondsUsed = (ticksEnd - timer->ticksBegin) / (double)CLOCKS_PER_SEC;
#endif
	evutil_gettimeofday(&timeEnd, NULL);
	evutil_timersub(&timeEnd, &timer->timeBegin, &timeDiff);
	secondsPassed = timeDiff.tv_sec + (timeDiff.tv_usec / 1.0e6);

	*secElapsedOut = secondsPassed;
	*secUsedOut = secondsUsed;
	*usageOut = secondsUsed / secondsPassed;
}
Beispiel #6
0
static int
_ev_timeout_add(AvahiTimeout *t, const struct timeval *tv)
{
  struct timeval e_tv;
  struct timeval now;
  int ret;

  evtimer_set(&t->ev, evcb_timeout, t);
  event_base_set(evbase_main, &t->ev);

  if ((tv->tv_sec == 0) && (tv->tv_usec == 0))
    {
      evutil_timerclear(&e_tv);
    }
  else
    {
      ret = gettimeofday(&now, NULL);
      if (ret != 0)
	return -1;

      evutil_timersub(tv, &now, &e_tv);
    }

  return evtimer_add(&t->ev, &e_tv);
}
Beispiel #7
0
static struct timeval *
run_once(int num_pipes)
{
	int i;
	evutil_socket_t *cp;
	static struct timeval ts, te, tv_timeout;

	events = calloc(num_pipes, sizeof(struct event));
	pipes = calloc(num_pipes * 2, sizeof(evutil_socket_t));

	if (events == NULL || pipes == NULL) {
		perror("malloc");
		exit(1);
	}

	for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) {
		if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, cp) == -1) {
			perror("socketpair");
			exit(1);
		}
	}

	/* measurements includes event setup */
	evutil_gettimeofday(&ts, NULL);

	/* provide a default timeout for events */
	evutil_timerclear(&tv_timeout);
	tv_timeout.tv_sec = 60;

	for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) {
		evutil_socket_t fd = i < num_pipes - 1 ? cp[3] : -1;
		event_set(&events[i], cp[0], EV_READ, read_cb,
		    (void *)(ev_intptr_t)fd);
		event_add(&events[i], &tv_timeout);
	}

	fired = 0;

	/* kick everything off with a single write */
	if (send(pipes[1], "e", 1, 0) < 0)
		perror("send");

	event_dispatch();

	evutil_gettimeofday(&te, NULL);
	evutil_timersub(&te, &ts, &te);

	for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) {
		event_del(&events[i]);
		close(cp[0]);
		close(cp[1]);
	}

	free(pipes);
	free(events);

	return (&te);
}
Beispiel #8
0
static struct timeval *
run_once(void)
{
	int *cp, space;
	long i;
	static struct timeval ta, ts, te;
	gettimeofday(&ta, NULL);

	for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) {
		if (events[i].ev_base)
			event_del(&events[i]);
		event_set(&events[i], cp[0], EV_READ | EV_PERSIST, read_cb, (void *) i);
		event_add(&events[i], NULL);
	}

	event_loop(EVLOOP_ONCE | EVLOOP_NONBLOCK);

	fired = 0;
	space = num_pipes / num_active;
	space = space * 2;
	for (i = 0; i < num_active; i++, fired++)
		send(pipes[i * space + 1], "e", 1, 0);

	count = 0;
	writes = num_writes;
	{ int xcount = 0;
	gettimeofday(&ts, NULL);
	do {
		event_loop(EVLOOP_ONCE | EVLOOP_NONBLOCK);
		xcount++;
	} while (count != fired);
	gettimeofday(&te, NULL);

	//if (xcount != count) fprintf(stderr, "Xcount: %d, Rcount: %d\n", xcount, count);
	}

	evutil_timersub(&te, &ta, &ta);
	evutil_timersub(&te, &ts, &ts);
	fprintf(stdout, "%8ld %8ld\n",
			ta.tv_sec * 1000000L + ta.tv_usec,
			ts.tv_sec * 1000000L + ts.tv_usec);

	return (&te);
}
Beispiel #9
0
static void on_prepare(struct evwatch *watcher, const struct evwatch_prepare_cb_info *info, void *arg)
{
	struct timeval duration;
	evutil_gettimeofday(&prepare_time, NULL);
	evwatch_prepare_get_timeout(info, &expected);
	if (check_time.tv_sec != 0) {
		evutil_timersub(&prepare_time, &check_time, &duration);
		histogram_update(durations, duration.tv_sec + duration.tv_usec / 1000000.0l);
	}
}
Beispiel #10
0
int
main(int argc, char **argv)
{
	int i;
	struct timeval start, end, total;
	long long usec;
	double throughput;
	resource = "/ref";

	setvbuf(stdout, NULL, _IONBF, 0);

	base = event_base_new();

	for (i=0; i < PARALLELISM; ++i) {
		if (launch_request() < 0)
			perror("launch");
	}

	evutil_gettimeofday(&start, NULL);

	event_base_dispatch(base);

	evutil_gettimeofday(&end, NULL);
	evutil_timersub(&end, &start, &total);
	usec = total_time.tv_sec * 1000000 + total_time.tv_usec;

	if (!total_n_handled) {
		puts("Nothing worked.  You probably did something dumb.");
		return 0;
	}


	throughput = total_n_handled /
	    (total.tv_sec+ ((double)total.tv_usec)/1000000.0);

#ifdef WIN32
#define I64_FMT "%I64d"
#define I64_TYP __int64
#else
#define I64_FMT "%lld"
#define I64_TYP long long int
#endif

	printf("\n%d requests in %d.%06d sec. (%.2f throughput)\n"
	    "Each took about %.02f msec latency\n"
	    I64_FMT "bytes read. %d errors.\n",
	    total_n_handled,
	    (int)total.tv_sec, (int)total.tv_usec,
	    throughput,
	    (double)(usec/1000) / total_n_handled,
	    (I64_TYP)total_n_bytes, n_errors);

	return 0;
}
Beispiel #11
0
/* Must be an easier way to figure out when an event is going to fire */
uint32_t event_remaining_seconds(struct event *ev) 
{
    struct timeval now_tv;
    struct timeval event_tv;
    struct timeval remaining_tv;

    event_pending(ev, EV_TIMEOUT, &event_tv);
    evutil_gettimeofday(&now_tv, NULL);
    evutil_timersub(&event_tv, &now_tv, &remaining_tv);

    return remaining_tv.tv_sec;
}
Beispiel #12
0
	void MMaster::timeout_cb(evutil_socket_t fd, short ev, void *arg)
	{
		timeval newtime, difference;
		event* timeout = static_cast<event*>(arg);
		evutil_gettimeofday(&newtime, NULL);
		evutil_timersub(&newtime, &lasttime, &difference);
		lasttime = newtime;
		WorkerThread::GetMsgHandler()->Process(newtime, difference);
		struct timeval tv;
		evutil_timerclear(&tv);
		tv.tv_sec = 0;
		tv.tv_usec = micsec;
		event_add(timeout, &tv);
	}
Beispiel #13
0
	ev_uint64_t get_time_usec()
	{
		static timeval _start_timeval = {0};
		static bool _has_start_timeval = false;
		static timeval _current_timeval = {0};
		static timeval _timeinterval = {0};

		if (!_has_start_timeval) {
			evutil_gettimeofday(&_start_timeval, 0);
			_has_start_timeval = true;
			return 0;
		}
		evutil_gettimeofday(&_current_timeval, 0);
		evutil_timersub(&_current_timeval, &_start_timeval, &_timeinterval);
		return (ev_uint64_t)_timeinterval.tv_sec * 1000000 + _timeinterval.tv_usec;
	}
Beispiel #14
0
static void
thread_deferred_cb_skew(void *arg)
{
	struct timeval tv_timer = {1, 0};
	struct event_base *base = NULL;
	struct event_config *cfg = NULL;
	struct timeval elapsed;
	int elapsed_usec;
	int i;

	cfg = event_config_new();
	tt_assert(cfg);
	event_config_set_max_dispatch_interval(cfg, NULL, 16, 0);

	base = event_base_new_with_config(cfg);
	tt_assert(base);

	for (i = 0; i < QUEUE_THREAD_COUNT; ++i)
		deferred_data[i].queue = base;

	evutil_gettimeofday(&timer_start, NULL);
	event_base_once(base, -1, EV_TIMEOUT, timer_callback, NULL,
			&tv_timer);
	event_base_once(base, -1, EV_TIMEOUT, start_threads_callback,
			NULL, NULL);
	event_base_dispatch(base);

	evutil_timersub(&timer_end, &timer_start, &elapsed);
	TT_BLATHER(("callback count, %u", callback_count));
	elapsed_usec =
	    (unsigned)(elapsed.tv_sec*1000000 + elapsed.tv_usec);
	TT_BLATHER(("elapsed time, %u usec", elapsed_usec));

	/* XXX be more intelligent here.  just make sure skew is
	 * within .4 seconds for now. */
	tt_assert(elapsed_usec >= 600000 && elapsed_usec <= 1400000);

end:
	for (i = 0; i < QUEUE_THREAD_COUNT; ++i)
		THREAD_JOIN(load_threads[i]);
	if (base)
		event_base_free(base);
	if (cfg)
		event_config_free(cfg);
}
Beispiel #15
0
void NetworkManager::update()
{
    struct timeval tv, difference;
    evutil_gettimeofday(&tv, NULL);
    evutil_timersub(&tv, &m_timeval, &difference);
    double escape = difference.tv_sec + (difference.tv_usec / 1.0e6);
    m_timeval = tv;
    for (auto iter = m_connects.begin(); iter != m_connects.end(); ++iter)
    {
        (*iter)->update(escape);
    }
    for (auto& iter = m_observers.begin(); iter != m_observers.end(); ++iter)
    {
        (*iter)->onUpdateNotify(escape);
    }
    lua_State* L = GameLua::getInstance()->getLuaState();
    Lua_CallRef(L, m_luaUpdateRefId, 0, escape);
}
Beispiel #16
0
void timeout_cb(int fd, short event, void *arg)
{
    struct timeval newtime, diffirence;
    struct ST_EventWithDescription *pEvent = (struct ST_EventWithDescription *)arg;
    struct event *timeout = pEvent->p_event;
    double elaple;

    evutil_gettimeofday(&newtime, NULL);
    evutil_timersub(&newtime, &lasttime, &diffirence);
    elaple = diffirence.tv_sec + (diffirence.tv_usec /10e6);

    printf("%s called at %d: %3f seconds since my last work.\n",
                (char *)pEvent->lable,(int)newtime.tv_sec, elaple);

    lasttime = newtime;

    struct timeval tv;
    evutil_timerclear(&tv);
    tv.tv_sec = pEvent->time_interval;
    event_add(timeout, &tv);
}
Beispiel #17
0
static void
timeout_cb(evutil_socket_t fd, short event, void *arg)
{
	struct timeval newtime, difference;
	struct event *timeout = arg;
	double elapsed;

	evutil_gettimeofday(&newtime, NULL);
	evutil_timersub(&newtime, &lasttime, &difference);
	elapsed = difference.tv_sec + (difference.tv_usec/ 1.0e6);

	printf("timeout_cb called at %d: %.3f seconds elapsed.\n",
		(int)newtime.tv_sec, elapsed);
	lasttime = newtime;

	if (! event_is_persistent){
		struct timeval tv;
		evutil_timerclear(&tv);
		tv.tv_sec = 2;
		event_add(timeout, &tv);
	}
}
Beispiel #18
0
static struct timeval *
run_once(void)
{
	evutil_socket_t *cp, space;
	long i;
	static struct timeval ts, te;

	for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) {
		if (event_initialized(&events[i]))
			event_del(&events[i]);
		event_set(&events[i], cp[0], EV_READ | EV_PERSIST, read_cb, (void *)(ev_intptr_t) i);
		event_add(&events[i], NULL);
	}

	event_loop(EVLOOP_ONCE | EVLOOP_NONBLOCK);

	fired = 0;
	space = num_pipes / num_active;
	space = space * 2;
	for (i = 0; i < num_active; i++, fired++)
		send(pipes[i * space + 1], "e", 1, 0);

	count = 0;
	writes = num_writes;
	{ int xcount = 0;
	evutil_gettimeofday(&ts, NULL);
	do {
		event_loop(EVLOOP_ONCE | EVLOOP_NONBLOCK);
		xcount++;
	} while (count != fired);
	evutil_gettimeofday(&te, NULL);

	if (xcount != count) fprintf(stderr, "Xcount: %d, Rcount: %d\n", xcount, count);
	}

	evutil_timersub(&te, &ts, &te);

	return (&te);
}
Beispiel #19
0
static void
thread_no_events(void *arg)
{
	THREAD_T thread;
	struct basic_test_data *data = arg;
	struct timeval starttime, endtime;
	int i;
	exit_base = data->base;

	memset(times,0,sizeof(times));
	for (i=0;i<5;++i) {
		event_assign(&time_events[i], data->base,
		    -1, 0, note_time_cb, &times[i]);
	}

	evutil_gettimeofday(&starttime, NULL);
	THREAD_START(thread, register_events_subthread, data->base);
	event_base_loop(data->base, EVLOOP_NO_EXIT_ON_EMPTY);
	evutil_gettimeofday(&endtime, NULL);
	tt_assert(event_base_got_break(data->base));
	THREAD_JOIN(thread);
	for (i=0; i<5; ++i) {
		struct timeval diff;
		double sec;
		evutil_timersub(&times[i], &starttime, &diff);
		sec = diff.tv_sec + diff.tv_usec/1.0e6;
		TT_BLATHER(("event %d at %.4f seconds", i, sec));
	}
	test_timeval_diff_eq(&starttime, &times[0], 100);
	test_timeval_diff_eq(&starttime, &times[1], 200);
	test_timeval_diff_eq(&starttime, &times[2], 400);
	test_timeval_diff_eq(&starttime, &times[3], 450);
	test_timeval_diff_eq(&starttime, &times[4], 500);
	test_timeval_diff_eq(&starttime, &endtime,  500);

end:
	;
}
Data BasicDelayedEventQueue::serialize() {
	std::lock_guard<std::recursive_mutex> lock(_mutex);

	if (_isStarted) {
		_isStarted = false;
		event_base_loopbreak(_eventLoop);
	}
	if (_thread) {
		_thread->join();
		delete _thread;
		_thread = NULL;
	}

	Data serialized;

	for (auto event : _queue) {
		struct callbackData cb = _callbackData[event.getUUID()];

		struct timeval delay = {0, 0};
		struct timeval now = {0, 0};
		uint64_t delayMs = 0;
		evutil_gettimeofday(&now, NULL);

		evutil_timersub(&delay, &cb.due, &now);
		if (delay.tv_sec > 0 || (delay.tv_sec == 0 && delay.tv_usec > 0)) {
			delayMs = delay.tv_sec * 1000 + delay.tv_usec / (double)1000;
		}

		Data delayedEvent;
		delayedEvent["event"] = event;
		delayedEvent["delay"] = Data(delayMs, Data::INTERPRETED);

		serialized["BasicDelayedEventQueue"].array.push_back(event);
	}

	start();
	return serialized;
}
Beispiel #21
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:
	;
}
Beispiel #22
0
static void
http_chunked_test(void)
{
	struct bufferevent *bev;
	int fd;
	const char *http_request;
	short port = -1;
	struct timeval tv_start, tv_end;
	struct evhttp_connection *evcon = NULL;
	struct evhttp_request *req = NULL;
	int i;

	test_ok = 0;
	fprintf(stdout, "Testing Chunked HTTP Reply: ");

	http = http_setup(&port, NULL);

	fd = http_connect("127.0.0.1", port);

	/* Stupid thing to send a request */
	bev = bufferevent_new(fd, 
	    http_chunked_readcb, http_chunked_writecb,
	    http_chunked_errorcb, NULL);

	http_request =
	    "GET /chunked HTTP/1.1\r\n"
	    "Host: somehost\r\n"
	    "Connection: close\r\n"
	    "\r\n";

	bufferevent_write(bev, http_request, strlen(http_request));

	evutil_gettimeofday(&tv_start, NULL);
	
	event_dispatch();

	evutil_gettimeofday(&tv_end, NULL);
	evutil_timersub(&tv_end, &tv_start, &tv_end);

	if (tv_end.tv_sec >= 1) {
		fprintf(stdout, "FAILED (time)\n");
		exit (1);
	}


	if (test_ok != 2) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}

	/* now try again with the regular connection object */
	evcon = evhttp_connection_new("127.0.0.1", port);
	if (evcon == NULL) {
		fprintf(stdout, "FAILED\n");
		exit(1);
	}

	/* make two requests to check the keepalive behavior */
	for (i = 0; i < 2; i++) {
		test_ok = 0;
		req = evhttp_request_new(http_chunked_request_done, NULL);

		/* Add the information that we care about */
		evhttp_add_header(req->output_headers, "Host", "somehost");

		/* We give ownership of the request to the connection */
		if (evhttp_make_request(evcon, req,
			EVHTTP_REQ_GET, "/chunked") == -1) {
			fprintf(stdout, "FAILED\n");
			exit(1);
		}

		event_dispatch();

		if (test_ok != 1) {
			fprintf(stdout, "FAILED\n");
			exit(1);
		}
	}

	evhttp_connection_free(evcon);
	evhttp_free(http);
	
	fprintf(stdout, "OK\n");
}