xref: /freebsd/contrib/ntp/sntp/libevent/test/regress.c (revision a25439b68651d176ae05867f5090d45fd85e9f24)
12b15cb3dSCy Schubert /*
22b15cb3dSCy Schubert  * Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu>
32b15cb3dSCy Schubert  * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
42b15cb3dSCy Schubert  *
52b15cb3dSCy Schubert  * Redistribution and use in source and binary forms, with or without
62b15cb3dSCy Schubert  * modification, are permitted provided that the following conditions
72b15cb3dSCy Schubert  * are met:
82b15cb3dSCy Schubert  * 1. Redistributions of source code must retain the above copyright
92b15cb3dSCy Schubert  *    notice, this list of conditions and the following disclaimer.
102b15cb3dSCy Schubert  * 2. Redistributions in binary form must reproduce the above copyright
112b15cb3dSCy Schubert  *    notice, this list of conditions and the following disclaimer in the
122b15cb3dSCy Schubert  *    documentation and/or other materials provided with the distribution.
132b15cb3dSCy Schubert  * 3. The name of the author may not be used to endorse or promote products
142b15cb3dSCy Schubert  *    derived from this software without specific prior written permission.
152b15cb3dSCy Schubert  *
162b15cb3dSCy Schubert  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
172b15cb3dSCy Schubert  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
182b15cb3dSCy Schubert  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
192b15cb3dSCy Schubert  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
202b15cb3dSCy Schubert  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
212b15cb3dSCy Schubert  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
222b15cb3dSCy Schubert  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
232b15cb3dSCy Schubert  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
242b15cb3dSCy Schubert  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
252b15cb3dSCy Schubert  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
262b15cb3dSCy Schubert  */
272b15cb3dSCy Schubert #include "util-internal.h"
282b15cb3dSCy Schubert 
292b15cb3dSCy Schubert #ifdef _WIN32
302b15cb3dSCy Schubert #include <winsock2.h>
312b15cb3dSCy Schubert #include <windows.h>
322b15cb3dSCy Schubert #endif
332b15cb3dSCy Schubert 
342b15cb3dSCy Schubert #include "event2/event-config.h"
352b15cb3dSCy Schubert 
362b15cb3dSCy Schubert #include <sys/types.h>
372b15cb3dSCy Schubert #include <sys/stat.h>
382b15cb3dSCy Schubert #ifdef EVENT__HAVE_SYS_TIME_H
392b15cb3dSCy Schubert #include <sys/time.h>
402b15cb3dSCy Schubert #endif
412b15cb3dSCy Schubert #include <sys/queue.h>
422b15cb3dSCy Schubert #ifndef _WIN32
432b15cb3dSCy Schubert #include <sys/socket.h>
442b15cb3dSCy Schubert #include <sys/wait.h>
452b15cb3dSCy Schubert #include <signal.h>
462b15cb3dSCy Schubert #include <unistd.h>
472b15cb3dSCy Schubert #include <netdb.h>
482b15cb3dSCy Schubert #endif
492b15cb3dSCy Schubert #include <fcntl.h>
502b15cb3dSCy Schubert #include <signal.h>
512b15cb3dSCy Schubert #include <stdlib.h>
522b15cb3dSCy Schubert #include <stdio.h>
532b15cb3dSCy Schubert #include <string.h>
542b15cb3dSCy Schubert #include <errno.h>
552b15cb3dSCy Schubert #include <assert.h>
562b15cb3dSCy Schubert #include <ctype.h>
572b15cb3dSCy Schubert 
582b15cb3dSCy Schubert #include "event2/event.h"
592b15cb3dSCy Schubert #include "event2/event_struct.h"
602b15cb3dSCy Schubert #include "event2/event_compat.h"
612b15cb3dSCy Schubert #include "event2/tag.h"
622b15cb3dSCy Schubert #include "event2/buffer.h"
632b15cb3dSCy Schubert #include "event2/buffer_compat.h"
642b15cb3dSCy Schubert #include "event2/util.h"
652b15cb3dSCy Schubert #include "event-internal.h"
662b15cb3dSCy Schubert #include "evthread-internal.h"
672b15cb3dSCy Schubert #include "log-internal.h"
682b15cb3dSCy Schubert #include "time-internal.h"
692b15cb3dSCy Schubert 
702b15cb3dSCy Schubert #include "regress.h"
712b15cb3dSCy Schubert 
722b15cb3dSCy Schubert #ifndef _WIN32
732b15cb3dSCy Schubert #include "regress.gen.h"
742b15cb3dSCy Schubert #endif
752b15cb3dSCy Schubert 
762b15cb3dSCy Schubert evutil_socket_t pair[2];
772b15cb3dSCy Schubert int test_ok;
782b15cb3dSCy Schubert int called;
792b15cb3dSCy Schubert struct event_base *global_base;
802b15cb3dSCy Schubert 
812b15cb3dSCy Schubert static char wbuf[4096];
822b15cb3dSCy Schubert static char rbuf[4096];
832b15cb3dSCy Schubert static int woff;
842b15cb3dSCy Schubert static int roff;
852b15cb3dSCy Schubert static int usepersist;
862b15cb3dSCy Schubert static struct timeval tset;
872b15cb3dSCy Schubert static struct timeval tcalled;
882b15cb3dSCy Schubert 
892b15cb3dSCy Schubert 
902b15cb3dSCy Schubert #define TEST1	"this is a test"
912b15cb3dSCy Schubert 
922b15cb3dSCy Schubert #ifndef SHUT_WR
932b15cb3dSCy Schubert #define SHUT_WR 1
942b15cb3dSCy Schubert #endif
952b15cb3dSCy Schubert 
962b15cb3dSCy Schubert #ifdef _WIN32
972b15cb3dSCy Schubert #define write(fd,buf,len) send((fd),(buf),(int)(len),0)
982b15cb3dSCy Schubert #define read(fd,buf,len) recv((fd),(buf),(int)(len),0)
992b15cb3dSCy Schubert #endif
1002b15cb3dSCy Schubert 
1012b15cb3dSCy Schubert struct basic_cb_args
1022b15cb3dSCy Schubert {
1032b15cb3dSCy Schubert 	struct event_base *eb;
1042b15cb3dSCy Schubert 	struct event *ev;
1052b15cb3dSCy Schubert 	unsigned int callcount;
1062b15cb3dSCy Schubert };
1072b15cb3dSCy Schubert 
1082b15cb3dSCy Schubert static void
1092b15cb3dSCy Schubert simple_read_cb(evutil_socket_t fd, short event, void *arg)
1102b15cb3dSCy Schubert {
1112b15cb3dSCy Schubert 	char buf[256];
1122b15cb3dSCy Schubert 	int len;
1132b15cb3dSCy Schubert 
1142b15cb3dSCy Schubert 	len = read(fd, buf, sizeof(buf));
1152b15cb3dSCy Schubert 
1162b15cb3dSCy Schubert 	if (len) {
1172b15cb3dSCy Schubert 		if (!called) {
1182b15cb3dSCy Schubert 			if (event_add(arg, NULL) == -1)
1192b15cb3dSCy Schubert 				exit(1);
1202b15cb3dSCy Schubert 		}
1212b15cb3dSCy Schubert 	} else if (called == 1)
1222b15cb3dSCy Schubert 		test_ok = 1;
1232b15cb3dSCy Schubert 
1242b15cb3dSCy Schubert 	called++;
1252b15cb3dSCy Schubert }
1262b15cb3dSCy Schubert 
1272b15cb3dSCy Schubert static void
1282b15cb3dSCy Schubert basic_read_cb(evutil_socket_t fd, short event, void *data)
1292b15cb3dSCy Schubert {
1302b15cb3dSCy Schubert 	char buf[256];
1312b15cb3dSCy Schubert 	int len;
1322b15cb3dSCy Schubert 	struct basic_cb_args *arg = data;
1332b15cb3dSCy Schubert 
1342b15cb3dSCy Schubert 	len = read(fd, buf, sizeof(buf));
1352b15cb3dSCy Schubert 
1362b15cb3dSCy Schubert 	if (len < 0) {
1372b15cb3dSCy Schubert 		tt_fail_perror("read (callback)");
1382b15cb3dSCy Schubert 	} else {
1392b15cb3dSCy Schubert 		switch (arg->callcount++) {
1402b15cb3dSCy Schubert 		case 0:	 /* first call: expect to read data; cycle */
1412b15cb3dSCy Schubert 			if (len > 0)
1422b15cb3dSCy Schubert 				return;
1432b15cb3dSCy Schubert 
1442b15cb3dSCy Schubert 			tt_fail_msg("EOF before data read");
1452b15cb3dSCy Schubert 			break;
1462b15cb3dSCy Schubert 
1472b15cb3dSCy Schubert 		case 1:	 /* second call: expect EOF; stop */
1482b15cb3dSCy Schubert 			if (len > 0)
1492b15cb3dSCy Schubert 				tt_fail_msg("not all data read on first cycle");
1502b15cb3dSCy Schubert 			break;
1512b15cb3dSCy Schubert 
1522b15cb3dSCy Schubert 		default:  /* third call: should not happen */
1532b15cb3dSCy Schubert 			tt_fail_msg("too many cycles");
1542b15cb3dSCy Schubert 		}
1552b15cb3dSCy Schubert 	}
1562b15cb3dSCy Schubert 
1572b15cb3dSCy Schubert 	event_del(arg->ev);
1582b15cb3dSCy Schubert 	event_base_loopexit(arg->eb, NULL);
1592b15cb3dSCy Schubert }
1602b15cb3dSCy Schubert 
1612b15cb3dSCy Schubert static void
1622b15cb3dSCy Schubert dummy_read_cb(evutil_socket_t fd, short event, void *arg)
1632b15cb3dSCy Schubert {
1642b15cb3dSCy Schubert }
1652b15cb3dSCy Schubert 
1662b15cb3dSCy Schubert static void
1672b15cb3dSCy Schubert simple_write_cb(evutil_socket_t fd, short event, void *arg)
1682b15cb3dSCy Schubert {
1692b15cb3dSCy Schubert 	int len;
1702b15cb3dSCy Schubert 
1712b15cb3dSCy Schubert 	len = write(fd, TEST1, strlen(TEST1) + 1);
1722b15cb3dSCy Schubert 	if (len == -1)
1732b15cb3dSCy Schubert 		test_ok = 0;
1742b15cb3dSCy Schubert 	else
1752b15cb3dSCy Schubert 		test_ok = 1;
1762b15cb3dSCy Schubert }
1772b15cb3dSCy Schubert 
1782b15cb3dSCy Schubert static void
1792b15cb3dSCy Schubert multiple_write_cb(evutil_socket_t fd, short event, void *arg)
1802b15cb3dSCy Schubert {
1812b15cb3dSCy Schubert 	struct event *ev = arg;
1822b15cb3dSCy Schubert 	int len;
1832b15cb3dSCy Schubert 
1842b15cb3dSCy Schubert 	len = 128;
1852b15cb3dSCy Schubert 	if (woff + len >= (int)sizeof(wbuf))
1862b15cb3dSCy Schubert 		len = sizeof(wbuf) - woff;
1872b15cb3dSCy Schubert 
1882b15cb3dSCy Schubert 	len = write(fd, wbuf + woff, len);
1892b15cb3dSCy Schubert 	if (len == -1) {
1902b15cb3dSCy Schubert 		fprintf(stderr, "%s: write\n", __func__);
1912b15cb3dSCy Schubert 		if (usepersist)
1922b15cb3dSCy Schubert 			event_del(ev);
1932b15cb3dSCy Schubert 		return;
1942b15cb3dSCy Schubert 	}
1952b15cb3dSCy Schubert 
1962b15cb3dSCy Schubert 	woff += len;
1972b15cb3dSCy Schubert 
1982b15cb3dSCy Schubert 	if (woff >= (int)sizeof(wbuf)) {
1992b15cb3dSCy Schubert 		shutdown(fd, SHUT_WR);
2002b15cb3dSCy Schubert 		if (usepersist)
2012b15cb3dSCy Schubert 			event_del(ev);
2022b15cb3dSCy Schubert 		return;
2032b15cb3dSCy Schubert 	}
2042b15cb3dSCy Schubert 
2052b15cb3dSCy Schubert 	if (!usepersist) {
2062b15cb3dSCy Schubert 		if (event_add(ev, NULL) == -1)
2072b15cb3dSCy Schubert 			exit(1);
2082b15cb3dSCy Schubert 	}
2092b15cb3dSCy Schubert }
2102b15cb3dSCy Schubert 
2112b15cb3dSCy Schubert static void
2122b15cb3dSCy Schubert multiple_read_cb(evutil_socket_t fd, short event, void *arg)
2132b15cb3dSCy Schubert {
2142b15cb3dSCy Schubert 	struct event *ev = arg;
2152b15cb3dSCy Schubert 	int len;
2162b15cb3dSCy Schubert 
2172b15cb3dSCy Schubert 	len = read(fd, rbuf + roff, sizeof(rbuf) - roff);
2182b15cb3dSCy Schubert 	if (len == -1)
2192b15cb3dSCy Schubert 		fprintf(stderr, "%s: read\n", __func__);
2202b15cb3dSCy Schubert 	if (len <= 0) {
2212b15cb3dSCy Schubert 		if (usepersist)
2222b15cb3dSCy Schubert 			event_del(ev);
2232b15cb3dSCy Schubert 		return;
2242b15cb3dSCy Schubert 	}
2252b15cb3dSCy Schubert 
2262b15cb3dSCy Schubert 	roff += len;
2272b15cb3dSCy Schubert 	if (!usepersist) {
2282b15cb3dSCy Schubert 		if (event_add(ev, NULL) == -1)
2292b15cb3dSCy Schubert 			exit(1);
2302b15cb3dSCy Schubert 	}
2312b15cb3dSCy Schubert }
2322b15cb3dSCy Schubert 
2332b15cb3dSCy Schubert static void
2342b15cb3dSCy Schubert timeout_cb(evutil_socket_t fd, short event, void *arg)
2352b15cb3dSCy Schubert {
2362b15cb3dSCy Schubert 	evutil_gettimeofday(&tcalled, NULL);
2372b15cb3dSCy Schubert }
2382b15cb3dSCy Schubert 
2392b15cb3dSCy Schubert struct both {
2402b15cb3dSCy Schubert 	struct event ev;
2412b15cb3dSCy Schubert 	int nread;
2422b15cb3dSCy Schubert };
2432b15cb3dSCy Schubert 
2442b15cb3dSCy Schubert static void
2452b15cb3dSCy Schubert combined_read_cb(evutil_socket_t fd, short event, void *arg)
2462b15cb3dSCy Schubert {
2472b15cb3dSCy Schubert 	struct both *both = arg;
2482b15cb3dSCy Schubert 	char buf[128];
2492b15cb3dSCy Schubert 	int len;
2502b15cb3dSCy Schubert 
2512b15cb3dSCy Schubert 	len = read(fd, buf, sizeof(buf));
2522b15cb3dSCy Schubert 	if (len == -1)
2532b15cb3dSCy Schubert 		fprintf(stderr, "%s: read\n", __func__);
2542b15cb3dSCy Schubert 	if (len <= 0)
2552b15cb3dSCy Schubert 		return;
2562b15cb3dSCy Schubert 
2572b15cb3dSCy Schubert 	both->nread += len;
2582b15cb3dSCy Schubert 	if (event_add(&both->ev, NULL) == -1)
2592b15cb3dSCy Schubert 		exit(1);
2602b15cb3dSCy Schubert }
2612b15cb3dSCy Schubert 
2622b15cb3dSCy Schubert static void
2632b15cb3dSCy Schubert combined_write_cb(evutil_socket_t fd, short event, void *arg)
2642b15cb3dSCy Schubert {
2652b15cb3dSCy Schubert 	struct both *both = arg;
2662b15cb3dSCy Schubert 	char buf[128];
2672b15cb3dSCy Schubert 	int len;
2682b15cb3dSCy Schubert 
2692b15cb3dSCy Schubert 	len = sizeof(buf);
2702b15cb3dSCy Schubert 	if (len > both->nread)
2712b15cb3dSCy Schubert 		len = both->nread;
2722b15cb3dSCy Schubert 
2732b15cb3dSCy Schubert 	memset(buf, 'q', len);
2742b15cb3dSCy Schubert 
2752b15cb3dSCy Schubert 	len = write(fd, buf, len);
2762b15cb3dSCy Schubert 	if (len == -1)
2772b15cb3dSCy Schubert 		fprintf(stderr, "%s: write\n", __func__);
2782b15cb3dSCy Schubert 	if (len <= 0) {
2792b15cb3dSCy Schubert 		shutdown(fd, SHUT_WR);
2802b15cb3dSCy Schubert 		return;
2812b15cb3dSCy Schubert 	}
2822b15cb3dSCy Schubert 
2832b15cb3dSCy Schubert 	both->nread -= len;
2842b15cb3dSCy Schubert 	if (event_add(&both->ev, NULL) == -1)
2852b15cb3dSCy Schubert 		exit(1);
2862b15cb3dSCy Schubert }
2872b15cb3dSCy Schubert 
2882b15cb3dSCy Schubert /* These macros used to replicate the work of the legacy test wrapper code */
2892b15cb3dSCy Schubert #define setup_test(x) do {						\
2902b15cb3dSCy Schubert 	if (!in_legacy_test_wrapper) {					\
2912b15cb3dSCy Schubert 		TT_FAIL(("Legacy test %s not wrapped properly", x));	\
2922b15cb3dSCy Schubert 		return;							\
2932b15cb3dSCy Schubert 	}								\
2942b15cb3dSCy Schubert 	} while (0)
2952b15cb3dSCy Schubert #define cleanup_test() setup_test("cleanup")
2962b15cb3dSCy Schubert 
2972b15cb3dSCy Schubert static void
2982b15cb3dSCy Schubert test_simpleread(void)
2992b15cb3dSCy Schubert {
3002b15cb3dSCy Schubert 	struct event ev;
3012b15cb3dSCy Schubert 
3022b15cb3dSCy Schubert 	/* Very simple read test */
3032b15cb3dSCy Schubert 	setup_test("Simple read: ");
3042b15cb3dSCy Schubert 
3052b15cb3dSCy Schubert 	if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) {
3062b15cb3dSCy Schubert 		tt_fail_perror("write");
3072b15cb3dSCy Schubert 	}
3082b15cb3dSCy Schubert 
3092b15cb3dSCy Schubert 	shutdown(pair[0], SHUT_WR);
3102b15cb3dSCy Schubert 
3112b15cb3dSCy Schubert 	event_set(&ev, pair[1], EV_READ, simple_read_cb, &ev);
3122b15cb3dSCy Schubert 	if (event_add(&ev, NULL) == -1)
3132b15cb3dSCy Schubert 		exit(1);
3142b15cb3dSCy Schubert 	event_dispatch();
3152b15cb3dSCy Schubert 
3162b15cb3dSCy Schubert 	cleanup_test();
3172b15cb3dSCy Schubert }
3182b15cb3dSCy Schubert 
3192b15cb3dSCy Schubert static void
3202b15cb3dSCy Schubert test_simplewrite(void)
3212b15cb3dSCy Schubert {
3222b15cb3dSCy Schubert 	struct event ev;
3232b15cb3dSCy Schubert 
3242b15cb3dSCy Schubert 	/* Very simple write test */
3252b15cb3dSCy Schubert 	setup_test("Simple write: ");
3262b15cb3dSCy Schubert 
3272b15cb3dSCy Schubert 	event_set(&ev, pair[0], EV_WRITE, simple_write_cb, &ev);
3282b15cb3dSCy Schubert 	if (event_add(&ev, NULL) == -1)
3292b15cb3dSCy Schubert 		exit(1);
3302b15cb3dSCy Schubert 	event_dispatch();
3312b15cb3dSCy Schubert 
3322b15cb3dSCy Schubert 	cleanup_test();
3332b15cb3dSCy Schubert }
3342b15cb3dSCy Schubert 
3352b15cb3dSCy Schubert static void
3362b15cb3dSCy Schubert simpleread_multiple_cb(evutil_socket_t fd, short event, void *arg)
3372b15cb3dSCy Schubert {
3382b15cb3dSCy Schubert 	if (++called == 2)
3392b15cb3dSCy Schubert 		test_ok = 1;
3402b15cb3dSCy Schubert }
3412b15cb3dSCy Schubert 
3422b15cb3dSCy Schubert static void
3432b15cb3dSCy Schubert test_simpleread_multiple(void)
3442b15cb3dSCy Schubert {
3452b15cb3dSCy Schubert 	struct event one, two;
3462b15cb3dSCy Schubert 
3472b15cb3dSCy Schubert 	/* Very simple read test */
3482b15cb3dSCy Schubert 	setup_test("Simple read to multiple evens: ");
3492b15cb3dSCy Schubert 
3502b15cb3dSCy Schubert 	if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) {
3512b15cb3dSCy Schubert 		tt_fail_perror("write");
3522b15cb3dSCy Schubert 	}
3532b15cb3dSCy Schubert 
3542b15cb3dSCy Schubert 	shutdown(pair[0], SHUT_WR);
3552b15cb3dSCy Schubert 
3562b15cb3dSCy Schubert 	event_set(&one, pair[1], EV_READ, simpleread_multiple_cb, NULL);
3572b15cb3dSCy Schubert 	if (event_add(&one, NULL) == -1)
3582b15cb3dSCy Schubert 		exit(1);
3592b15cb3dSCy Schubert 	event_set(&two, pair[1], EV_READ, simpleread_multiple_cb, NULL);
3602b15cb3dSCy Schubert 	if (event_add(&two, NULL) == -1)
3612b15cb3dSCy Schubert 		exit(1);
3622b15cb3dSCy Schubert 	event_dispatch();
3632b15cb3dSCy Schubert 
3642b15cb3dSCy Schubert 	cleanup_test();
3652b15cb3dSCy Schubert }
3662b15cb3dSCy Schubert 
3672b15cb3dSCy Schubert static int have_closed = 0;
3682b15cb3dSCy Schubert static int premature_event = 0;
3692b15cb3dSCy Schubert static void
3702b15cb3dSCy Schubert simpleclose_close_fd_cb(evutil_socket_t s, short what, void *ptr)
3712b15cb3dSCy Schubert {
3722b15cb3dSCy Schubert 	evutil_socket_t **fds = ptr;
3732b15cb3dSCy Schubert 	TT_BLATHER(("Closing"));
3742b15cb3dSCy Schubert 	evutil_closesocket(*fds[0]);
3752b15cb3dSCy Schubert 	evutil_closesocket(*fds[1]);
3762b15cb3dSCy Schubert 	*fds[0] = -1;
3772b15cb3dSCy Schubert 	*fds[1] = -1;
3782b15cb3dSCy Schubert 	have_closed = 1;
3792b15cb3dSCy Schubert }
3802b15cb3dSCy Schubert 
3812b15cb3dSCy Schubert static void
3822b15cb3dSCy Schubert record_event_cb(evutil_socket_t s, short what, void *ptr)
3832b15cb3dSCy Schubert {
3842b15cb3dSCy Schubert 	short *whatp = ptr;
3852b15cb3dSCy Schubert 	if (!have_closed)
3862b15cb3dSCy Schubert 		premature_event = 1;
3872b15cb3dSCy Schubert 	*whatp = what;
3882b15cb3dSCy Schubert 	TT_BLATHER(("Recorded %d on socket %d", (int)what, (int)s));
3892b15cb3dSCy Schubert }
3902b15cb3dSCy Schubert 
3912b15cb3dSCy Schubert static void
3922b15cb3dSCy Schubert test_simpleclose(void *ptr)
3932b15cb3dSCy Schubert {
3942b15cb3dSCy Schubert 	/* Test that a close of FD is detected as a read and as a write. */
3952b15cb3dSCy Schubert 	struct event_base *base = event_base_new();
3962b15cb3dSCy Schubert 	evutil_socket_t pair1[2]={-1,-1}, pair2[2] = {-1, -1};
3972b15cb3dSCy Schubert 	evutil_socket_t *to_close[2];
3982b15cb3dSCy Schubert 	struct event *rev=NULL, *wev=NULL, *closeev=NULL;
3992b15cb3dSCy Schubert 	struct timeval tv;
4002b15cb3dSCy Schubert 	short got_read_on_close = 0, got_write_on_close = 0;
4012b15cb3dSCy Schubert 	char buf[1024];
4022b15cb3dSCy Schubert 	memset(buf, 99, sizeof(buf));
4032b15cb3dSCy Schubert #ifdef _WIN32
4042b15cb3dSCy Schubert #define LOCAL_SOCKETPAIR_AF AF_INET
4052b15cb3dSCy Schubert #else
4062b15cb3dSCy Schubert #define LOCAL_SOCKETPAIR_AF AF_UNIX
4072b15cb3dSCy Schubert #endif
4082b15cb3dSCy Schubert 	if (evutil_socketpair(LOCAL_SOCKETPAIR_AF, SOCK_STREAM, 0, pair1)<0)
4092b15cb3dSCy Schubert 		TT_DIE(("socketpair: %s", strerror(errno)));
4102b15cb3dSCy Schubert 	if (evutil_socketpair(LOCAL_SOCKETPAIR_AF, SOCK_STREAM, 0, pair2)<0)
4112b15cb3dSCy Schubert 		TT_DIE(("socketpair: %s", strerror(errno)));
4122b15cb3dSCy Schubert 	if (evutil_make_socket_nonblocking(pair1[1]) < 0)
4132b15cb3dSCy Schubert 		TT_DIE(("make_socket_nonblocking"));
4142b15cb3dSCy Schubert 	if (evutil_make_socket_nonblocking(pair2[1]) < 0)
4152b15cb3dSCy Schubert 		TT_DIE(("make_socket_nonblocking"));
4162b15cb3dSCy Schubert 
4172b15cb3dSCy Schubert 	/** Stuff pair2[1] full of data, until write fails */
4182b15cb3dSCy Schubert 	while (1) {
4192b15cb3dSCy Schubert 		int r = write(pair2[1], buf, sizeof(buf));
4202b15cb3dSCy Schubert 		if (r<0) {
4212b15cb3dSCy Schubert 			int err = evutil_socket_geterror(pair2[1]);
4222b15cb3dSCy Schubert 			if (! EVUTIL_ERR_RW_RETRIABLE(err))
4232b15cb3dSCy Schubert 				TT_DIE(("write failed strangely: %s",
4242b15cb3dSCy Schubert 					evutil_socket_error_to_string(err)));
4252b15cb3dSCy Schubert 			break;
4262b15cb3dSCy Schubert 		}
4272b15cb3dSCy Schubert 	}
4282b15cb3dSCy Schubert 	to_close[0] = &pair1[0];
4292b15cb3dSCy Schubert 	to_close[1] = &pair2[0];
4302b15cb3dSCy Schubert 
4312b15cb3dSCy Schubert 	closeev = event_new(base, -1, EV_TIMEOUT, simpleclose_close_fd_cb,
4322b15cb3dSCy Schubert 	    to_close);
4332b15cb3dSCy Schubert 	rev = event_new(base, pair1[1], EV_READ, record_event_cb,
4342b15cb3dSCy Schubert 	    &got_read_on_close);
4352b15cb3dSCy Schubert 	TT_BLATHER(("Waiting for read on %d", (int)pair1[1]));
4362b15cb3dSCy Schubert 	wev = event_new(base, pair2[1], EV_WRITE, record_event_cb,
4372b15cb3dSCy Schubert 	    &got_write_on_close);
4382b15cb3dSCy Schubert 	TT_BLATHER(("Waiting for write on %d", (int)pair2[1]));
4392b15cb3dSCy Schubert 	tv.tv_sec = 0;
4402b15cb3dSCy Schubert 	tv.tv_usec = 100*1000; /* Close pair1[0] after a little while, and make
4412b15cb3dSCy Schubert 			       * sure we get a read event. */
4422b15cb3dSCy Schubert 	event_add(closeev, &tv);
4432b15cb3dSCy Schubert 	event_add(rev, NULL);
4442b15cb3dSCy Schubert 	event_add(wev, NULL);
4452b15cb3dSCy Schubert 	/* Don't let the test go on too long. */
4462b15cb3dSCy Schubert 	tv.tv_sec = 0;
4472b15cb3dSCy Schubert 	tv.tv_usec = 200*1000;
4482b15cb3dSCy Schubert 	event_base_loopexit(base, &tv);
4492b15cb3dSCy Schubert 	event_base_loop(base, 0);
4502b15cb3dSCy Schubert 
4512b15cb3dSCy Schubert 	tt_int_op(got_read_on_close, ==, EV_READ);
4522b15cb3dSCy Schubert 	tt_int_op(got_write_on_close, ==, EV_WRITE);
4532b15cb3dSCy Schubert 	tt_int_op(premature_event, ==, 0);
4542b15cb3dSCy Schubert 
4552b15cb3dSCy Schubert end:
4562b15cb3dSCy Schubert 	if (pair1[0] >= 0)
4572b15cb3dSCy Schubert 		evutil_closesocket(pair1[0]);
4582b15cb3dSCy Schubert 	if (pair1[1] >= 0)
4592b15cb3dSCy Schubert 		evutil_closesocket(pair1[1]);
4602b15cb3dSCy Schubert 	if (pair2[0] >= 0)
4612b15cb3dSCy Schubert 		evutil_closesocket(pair2[0]);
4622b15cb3dSCy Schubert 	if (pair2[1] >= 0)
4632b15cb3dSCy Schubert 		evutil_closesocket(pair2[1]);
4642b15cb3dSCy Schubert 	if (rev)
4652b15cb3dSCy Schubert 		event_free(rev);
4662b15cb3dSCy Schubert 	if (wev)
4672b15cb3dSCy Schubert 		event_free(wev);
4682b15cb3dSCy Schubert 	if (closeev)
4692b15cb3dSCy Schubert 		event_free(closeev);
4702b15cb3dSCy Schubert 	if (base)
4712b15cb3dSCy Schubert 		event_base_free(base);
4722b15cb3dSCy Schubert }
4732b15cb3dSCy Schubert 
4742b15cb3dSCy Schubert 
4752b15cb3dSCy Schubert static void
4762b15cb3dSCy Schubert test_multiple(void)
4772b15cb3dSCy Schubert {
4782b15cb3dSCy Schubert 	struct event ev, ev2;
4792b15cb3dSCy Schubert 	int i;
4802b15cb3dSCy Schubert 
4812b15cb3dSCy Schubert 	/* Multiple read and write test */
4822b15cb3dSCy Schubert 	setup_test("Multiple read/write: ");
4832b15cb3dSCy Schubert 	memset(rbuf, 0, sizeof(rbuf));
4842b15cb3dSCy Schubert 	for (i = 0; i < (int)sizeof(wbuf); i++)
4852b15cb3dSCy Schubert 		wbuf[i] = i;
4862b15cb3dSCy Schubert 
4872b15cb3dSCy Schubert 	roff = woff = 0;
4882b15cb3dSCy Schubert 	usepersist = 0;
4892b15cb3dSCy Schubert 
4902b15cb3dSCy Schubert 	event_set(&ev, pair[0], EV_WRITE, multiple_write_cb, &ev);
4912b15cb3dSCy Schubert 	if (event_add(&ev, NULL) == -1)
4922b15cb3dSCy Schubert 		exit(1);
4932b15cb3dSCy Schubert 	event_set(&ev2, pair[1], EV_READ, multiple_read_cb, &ev2);
4942b15cb3dSCy Schubert 	if (event_add(&ev2, NULL) == -1)
4952b15cb3dSCy Schubert 		exit(1);
4962b15cb3dSCy Schubert 	event_dispatch();
4972b15cb3dSCy Schubert 
4982b15cb3dSCy Schubert 	if (roff == woff)
4992b15cb3dSCy Schubert 		test_ok = memcmp(rbuf, wbuf, sizeof(wbuf)) == 0;
5002b15cb3dSCy Schubert 
5012b15cb3dSCy Schubert 	cleanup_test();
5022b15cb3dSCy Schubert }
5032b15cb3dSCy Schubert 
5042b15cb3dSCy Schubert static void
5052b15cb3dSCy Schubert test_persistent(void)
5062b15cb3dSCy Schubert {
5072b15cb3dSCy Schubert 	struct event ev, ev2;
5082b15cb3dSCy Schubert 	int i;
5092b15cb3dSCy Schubert 
5102b15cb3dSCy Schubert 	/* Multiple read and write test with persist */
5112b15cb3dSCy Schubert 	setup_test("Persist read/write: ");
5122b15cb3dSCy Schubert 	memset(rbuf, 0, sizeof(rbuf));
5132b15cb3dSCy Schubert 	for (i = 0; i < (int)sizeof(wbuf); i++)
5142b15cb3dSCy Schubert 		wbuf[i] = i;
5152b15cb3dSCy Schubert 
5162b15cb3dSCy Schubert 	roff = woff = 0;
5172b15cb3dSCy Schubert 	usepersist = 1;
5182b15cb3dSCy Schubert 
5192b15cb3dSCy Schubert 	event_set(&ev, pair[0], EV_WRITE|EV_PERSIST, multiple_write_cb, &ev);
5202b15cb3dSCy Schubert 	if (event_add(&ev, NULL) == -1)
5212b15cb3dSCy Schubert 		exit(1);
5222b15cb3dSCy Schubert 	event_set(&ev2, pair[1], EV_READ|EV_PERSIST, multiple_read_cb, &ev2);
5232b15cb3dSCy Schubert 	if (event_add(&ev2, NULL) == -1)
5242b15cb3dSCy Schubert 		exit(1);
5252b15cb3dSCy Schubert 	event_dispatch();
5262b15cb3dSCy Schubert 
5272b15cb3dSCy Schubert 	if (roff == woff)
5282b15cb3dSCy Schubert 		test_ok = memcmp(rbuf, wbuf, sizeof(wbuf)) == 0;
5292b15cb3dSCy Schubert 
5302b15cb3dSCy Schubert 	cleanup_test();
5312b15cb3dSCy Schubert }
5322b15cb3dSCy Schubert 
5332b15cb3dSCy Schubert static void
5342b15cb3dSCy Schubert test_combined(void)
5352b15cb3dSCy Schubert {
5362b15cb3dSCy Schubert 	struct both r1, r2, w1, w2;
5372b15cb3dSCy Schubert 
5382b15cb3dSCy Schubert 	setup_test("Combined read/write: ");
5392b15cb3dSCy Schubert 	memset(&r1, 0, sizeof(r1));
5402b15cb3dSCy Schubert 	memset(&r2, 0, sizeof(r2));
5412b15cb3dSCy Schubert 	memset(&w1, 0, sizeof(w1));
5422b15cb3dSCy Schubert 	memset(&w2, 0, sizeof(w2));
5432b15cb3dSCy Schubert 
5442b15cb3dSCy Schubert 	w1.nread = 4096;
5452b15cb3dSCy Schubert 	w2.nread = 8192;
5462b15cb3dSCy Schubert 
5472b15cb3dSCy Schubert 	event_set(&r1.ev, pair[0], EV_READ, combined_read_cb, &r1);
5482b15cb3dSCy Schubert 	event_set(&w1.ev, pair[0], EV_WRITE, combined_write_cb, &w1);
5492b15cb3dSCy Schubert 	event_set(&r2.ev, pair[1], EV_READ, combined_read_cb, &r2);
5502b15cb3dSCy Schubert 	event_set(&w2.ev, pair[1], EV_WRITE, combined_write_cb, &w2);
5512b15cb3dSCy Schubert 	tt_assert(event_add(&r1.ev, NULL) != -1);
5522b15cb3dSCy Schubert 	tt_assert(!event_add(&w1.ev, NULL));
5532b15cb3dSCy Schubert 	tt_assert(!event_add(&r2.ev, NULL));
5542b15cb3dSCy Schubert 	tt_assert(!event_add(&w2.ev, NULL));
5552b15cb3dSCy Schubert 	event_dispatch();
5562b15cb3dSCy Schubert 
5572b15cb3dSCy Schubert 	if (r1.nread == 8192 && r2.nread == 4096)
5582b15cb3dSCy Schubert 		test_ok = 1;
5592b15cb3dSCy Schubert 
5602b15cb3dSCy Schubert end:
5612b15cb3dSCy Schubert 	cleanup_test();
5622b15cb3dSCy Schubert }
5632b15cb3dSCy Schubert 
5642b15cb3dSCy Schubert static void
5652b15cb3dSCy Schubert test_simpletimeout(void)
5662b15cb3dSCy Schubert {
5672b15cb3dSCy Schubert 	struct timeval tv;
5682b15cb3dSCy Schubert 	struct event ev;
5692b15cb3dSCy Schubert 
5702b15cb3dSCy Schubert 	setup_test("Simple timeout: ");
5712b15cb3dSCy Schubert 
5722b15cb3dSCy Schubert 	tv.tv_usec = 200*1000;
5732b15cb3dSCy Schubert 	tv.tv_sec = 0;
5742b15cb3dSCy Schubert 	evutil_timerclear(&tcalled);
5752b15cb3dSCy Schubert 	evtimer_set(&ev, timeout_cb, NULL);
5762b15cb3dSCy Schubert 	evtimer_add(&ev, &tv);
5772b15cb3dSCy Schubert 
5782b15cb3dSCy Schubert 	evutil_gettimeofday(&tset, NULL);
5792b15cb3dSCy Schubert 	event_dispatch();
5802b15cb3dSCy Schubert 	test_timeval_diff_eq(&tset, &tcalled, 200);
5812b15cb3dSCy Schubert 
5822b15cb3dSCy Schubert 	test_ok = 1;
5832b15cb3dSCy Schubert end:
5842b15cb3dSCy Schubert 	cleanup_test();
5852b15cb3dSCy Schubert }
5862b15cb3dSCy Schubert 
5872b15cb3dSCy Schubert static void
5882b15cb3dSCy Schubert periodic_timeout_cb(evutil_socket_t fd, short event, void *arg)
5892b15cb3dSCy Schubert {
5902b15cb3dSCy Schubert 	int *count = arg;
5912b15cb3dSCy Schubert 
5922b15cb3dSCy Schubert 	(*count)++;
5932b15cb3dSCy Schubert 	if (*count == 6) {
5942b15cb3dSCy Schubert 		/* call loopexit only once - on slow machines(?), it is
5952b15cb3dSCy Schubert 		 * apparently possible for this to get called twice. */
5962b15cb3dSCy Schubert 		test_ok = 1;
5972b15cb3dSCy Schubert 		event_base_loopexit(global_base, NULL);
5982b15cb3dSCy Schubert 	}
5992b15cb3dSCy Schubert }
6002b15cb3dSCy Schubert 
6012b15cb3dSCy Schubert static void
6022b15cb3dSCy Schubert test_persistent_timeout(void)
6032b15cb3dSCy Schubert {
6042b15cb3dSCy Schubert 	struct timeval tv;
6052b15cb3dSCy Schubert 	struct event ev;
6062b15cb3dSCy Schubert 	int count = 0;
6072b15cb3dSCy Schubert 
6082b15cb3dSCy Schubert 	evutil_timerclear(&tv);
6092b15cb3dSCy Schubert 	tv.tv_usec = 10000;
6102b15cb3dSCy Schubert 
6112b15cb3dSCy Schubert 	event_assign(&ev, global_base, -1, EV_TIMEOUT|EV_PERSIST,
6122b15cb3dSCy Schubert 	    periodic_timeout_cb, &count);
6132b15cb3dSCy Schubert 	event_add(&ev, &tv);
6142b15cb3dSCy Schubert 
6152b15cb3dSCy Schubert 	event_dispatch();
6162b15cb3dSCy Schubert 
6172b15cb3dSCy Schubert 	event_del(&ev);
6182b15cb3dSCy Schubert }
6192b15cb3dSCy Schubert 
6202b15cb3dSCy Schubert static void
6212b15cb3dSCy Schubert test_persistent_timeout_jump(void *ptr)
6222b15cb3dSCy Schubert {
6232b15cb3dSCy Schubert 	struct basic_test_data *data = ptr;
6242b15cb3dSCy Schubert 	struct event ev;
6252b15cb3dSCy Schubert 	int count = 0;
6262b15cb3dSCy Schubert 	struct timeval msec100 = { 0, 100 * 1000 };
6272b15cb3dSCy Schubert 	struct timeval msec50 = { 0, 50 * 1000 };
6282b15cb3dSCy Schubert 	struct timeval msec300 = { 0, 300 * 1000 };
6292b15cb3dSCy Schubert 
6302b15cb3dSCy Schubert 	event_assign(&ev, data->base, -1, EV_PERSIST, periodic_timeout_cb, &count);
6312b15cb3dSCy Schubert 	event_add(&ev, &msec100);
6322b15cb3dSCy Schubert 	/* Wait for a bit */
6332b15cb3dSCy Schubert 	evutil_usleep_(&msec300);
6342b15cb3dSCy Schubert 	event_base_loopexit(data->base, &msec50);
6352b15cb3dSCy Schubert 	event_base_dispatch(data->base);
6362b15cb3dSCy Schubert 	tt_int_op(count, ==, 1);
6372b15cb3dSCy Schubert 
6382b15cb3dSCy Schubert end:
6392b15cb3dSCy Schubert 	event_del(&ev);
6402b15cb3dSCy Schubert }
6412b15cb3dSCy Schubert 
6422b15cb3dSCy Schubert struct persist_active_timeout_called {
6432b15cb3dSCy Schubert 	int n;
6442b15cb3dSCy Schubert 	short events[16];
6452b15cb3dSCy Schubert 	struct timeval tvs[16];
6462b15cb3dSCy Schubert };
6472b15cb3dSCy Schubert 
6482b15cb3dSCy Schubert static void
6492b15cb3dSCy Schubert activate_cb(evutil_socket_t fd, short event, void *arg)
6502b15cb3dSCy Schubert {
6512b15cb3dSCy Schubert 	struct event *ev = arg;
6522b15cb3dSCy Schubert 	event_active(ev, EV_READ, 1);
6532b15cb3dSCy Schubert }
6542b15cb3dSCy Schubert 
6552b15cb3dSCy Schubert static void
6562b15cb3dSCy Schubert persist_active_timeout_cb(evutil_socket_t fd, short event, void *arg)
6572b15cb3dSCy Schubert {
6582b15cb3dSCy Schubert 	struct persist_active_timeout_called *c = arg;
6592b15cb3dSCy Schubert 	if (c->n < 15) {
6602b15cb3dSCy Schubert 		c->events[c->n] = event;
6612b15cb3dSCy Schubert 		evutil_gettimeofday(&c->tvs[c->n], NULL);
6622b15cb3dSCy Schubert 		++c->n;
6632b15cb3dSCy Schubert 	}
6642b15cb3dSCy Schubert }
6652b15cb3dSCy Schubert 
6662b15cb3dSCy Schubert static void
6672b15cb3dSCy Schubert test_persistent_active_timeout(void *ptr)
6682b15cb3dSCy Schubert {
6692b15cb3dSCy Schubert 	struct timeval tv, tv2, tv_exit, start;
6702b15cb3dSCy Schubert 	struct event ev;
6712b15cb3dSCy Schubert 	struct persist_active_timeout_called res;
6722b15cb3dSCy Schubert 
6732b15cb3dSCy Schubert 	struct basic_test_data *data = ptr;
6742b15cb3dSCy Schubert 	struct event_base *base = data->base;
6752b15cb3dSCy Schubert 
6762b15cb3dSCy Schubert 	memset(&res, 0, sizeof(res));
6772b15cb3dSCy Schubert 
6782b15cb3dSCy Schubert 	tv.tv_sec = 0;
6792b15cb3dSCy Schubert 	tv.tv_usec = 200 * 1000;
6802b15cb3dSCy Schubert 	event_assign(&ev, base, -1, EV_TIMEOUT|EV_PERSIST,
6812b15cb3dSCy Schubert 	    persist_active_timeout_cb, &res);
6822b15cb3dSCy Schubert 	event_add(&ev, &tv);
6832b15cb3dSCy Schubert 
6842b15cb3dSCy Schubert 	tv2.tv_sec = 0;
6852b15cb3dSCy Schubert 	tv2.tv_usec = 100 * 1000;
6862b15cb3dSCy Schubert 	event_base_once(base, -1, EV_TIMEOUT, activate_cb, &ev, &tv2);
6872b15cb3dSCy Schubert 
6882b15cb3dSCy Schubert 	tv_exit.tv_sec = 0;
6892b15cb3dSCy Schubert 	tv_exit.tv_usec = 600 * 1000;
6902b15cb3dSCy Schubert 	event_base_loopexit(base, &tv_exit);
6912b15cb3dSCy Schubert 
6922b15cb3dSCy Schubert 	event_base_assert_ok_(base);
6932b15cb3dSCy Schubert 	evutil_gettimeofday(&start, NULL);
6942b15cb3dSCy Schubert 
6952b15cb3dSCy Schubert 	event_base_dispatch(base);
6962b15cb3dSCy Schubert 	event_base_assert_ok_(base);
6972b15cb3dSCy Schubert 
6982b15cb3dSCy Schubert 	tt_int_op(res.n, ==, 3);
6992b15cb3dSCy Schubert 	tt_int_op(res.events[0], ==, EV_READ);
7002b15cb3dSCy Schubert 	tt_int_op(res.events[1], ==, EV_TIMEOUT);
7012b15cb3dSCy Schubert 	tt_int_op(res.events[2], ==, EV_TIMEOUT);
7022b15cb3dSCy Schubert 	test_timeval_diff_eq(&start, &res.tvs[0], 100);
7032b15cb3dSCy Schubert 	test_timeval_diff_eq(&start, &res.tvs[1], 300);
7042b15cb3dSCy Schubert 	test_timeval_diff_eq(&start, &res.tvs[2], 500);
7052b15cb3dSCy Schubert end:
7062b15cb3dSCy Schubert 	event_del(&ev);
7072b15cb3dSCy Schubert }
7082b15cb3dSCy Schubert 
7092b15cb3dSCy Schubert struct common_timeout_info {
7102b15cb3dSCy Schubert 	struct event ev;
7112b15cb3dSCy Schubert 	struct timeval called_at;
7122b15cb3dSCy Schubert 	int which;
7132b15cb3dSCy Schubert 	int count;
7142b15cb3dSCy Schubert };
7152b15cb3dSCy Schubert 
7162b15cb3dSCy Schubert static void
7172b15cb3dSCy Schubert common_timeout_cb(evutil_socket_t fd, short event, void *arg)
7182b15cb3dSCy Schubert {
7192b15cb3dSCy Schubert 	struct common_timeout_info *ti = arg;
7202b15cb3dSCy Schubert 	++ti->count;
7212b15cb3dSCy Schubert 	evutil_gettimeofday(&ti->called_at, NULL);
7222b15cb3dSCy Schubert 	if (ti->count >= 4)
7232b15cb3dSCy Schubert 		event_del(&ti->ev);
7242b15cb3dSCy Schubert }
7252b15cb3dSCy Schubert 
7262b15cb3dSCy Schubert static void
7272b15cb3dSCy Schubert test_common_timeout(void *ptr)
7282b15cb3dSCy Schubert {
7292b15cb3dSCy Schubert 	struct basic_test_data *data = ptr;
7302b15cb3dSCy Schubert 
7312b15cb3dSCy Schubert 	struct event_base *base = data->base;
7322b15cb3dSCy Schubert 	int i;
7332b15cb3dSCy Schubert 	struct common_timeout_info info[100];
7342b15cb3dSCy Schubert 
7352b15cb3dSCy Schubert 	struct timeval start;
7362b15cb3dSCy Schubert 	struct timeval tmp_100_ms = { 0, 100*1000 };
7372b15cb3dSCy Schubert 	struct timeval tmp_200_ms = { 0, 200*1000 };
7382b15cb3dSCy Schubert 	struct timeval tmp_5_sec = { 5, 0 };
7392b15cb3dSCy Schubert 	struct timeval tmp_5M_usec = { 0, 5*1000*1000 };
7402b15cb3dSCy Schubert 
7412b15cb3dSCy Schubert 	const struct timeval *ms_100, *ms_200, *sec_5;
7422b15cb3dSCy Schubert 
7432b15cb3dSCy Schubert 	ms_100 = event_base_init_common_timeout(base, &tmp_100_ms);
7442b15cb3dSCy Schubert 	ms_200 = event_base_init_common_timeout(base, &tmp_200_ms);
7452b15cb3dSCy Schubert 	sec_5 = event_base_init_common_timeout(base, &tmp_5_sec);
7462b15cb3dSCy Schubert 	tt_assert(ms_100);
7472b15cb3dSCy Schubert 	tt_assert(ms_200);
7482b15cb3dSCy Schubert 	tt_assert(sec_5);
7492b15cb3dSCy Schubert 	tt_ptr_op(event_base_init_common_timeout(base, &tmp_200_ms),
7502b15cb3dSCy Schubert 	    ==, ms_200);
7512b15cb3dSCy Schubert 	tt_ptr_op(event_base_init_common_timeout(base, ms_200), ==, ms_200);
7522b15cb3dSCy Schubert 	tt_ptr_op(event_base_init_common_timeout(base, &tmp_5M_usec), ==, sec_5);
7532b15cb3dSCy Schubert 	tt_int_op(ms_100->tv_sec, ==, 0);
7542b15cb3dSCy Schubert 	tt_int_op(ms_200->tv_sec, ==, 0);
7552b15cb3dSCy Schubert 	tt_int_op(sec_5->tv_sec, ==, 5);
7562b15cb3dSCy Schubert 	tt_int_op(ms_100->tv_usec, ==, 100000|0x50000000);
7572b15cb3dSCy Schubert 	tt_int_op(ms_200->tv_usec, ==, 200000|0x50100000);
7582b15cb3dSCy Schubert 	tt_int_op(sec_5->tv_usec, ==, 0|0x50200000);
7592b15cb3dSCy Schubert 
7602b15cb3dSCy Schubert 	memset(info, 0, sizeof(info));
7612b15cb3dSCy Schubert 
7622b15cb3dSCy Schubert 	for (i=0; i<100; ++i) {
7632b15cb3dSCy Schubert 		info[i].which = i;
7642b15cb3dSCy Schubert 		event_assign(&info[i].ev, base, -1, EV_TIMEOUT|EV_PERSIST,
7652b15cb3dSCy Schubert 		    common_timeout_cb, &info[i]);
7662b15cb3dSCy Schubert 		if (i % 2) {
7672b15cb3dSCy Schubert 			if ((i%20)==1) {
7682b15cb3dSCy Schubert 				/* Glass-box test: Make sure we survive the
7692b15cb3dSCy Schubert 				 * transition to non-common timeouts. It's
7702b15cb3dSCy Schubert 				 * a little tricky. */
7712b15cb3dSCy Schubert 				event_add(&info[i].ev, ms_200);
7722b15cb3dSCy Schubert 				event_add(&info[i].ev, &tmp_100_ms);
7732b15cb3dSCy Schubert 			} else if ((i%20)==3) {
7742b15cb3dSCy Schubert 				/* Check heap-to-common too. */
7752b15cb3dSCy Schubert 				event_add(&info[i].ev, &tmp_200_ms);
7762b15cb3dSCy Schubert 				event_add(&info[i].ev, ms_100);
7772b15cb3dSCy Schubert 			} else if ((i%20)==5) {
7782b15cb3dSCy Schubert 				/* Also check common-to-common. */
7792b15cb3dSCy Schubert 				event_add(&info[i].ev, ms_200);
7802b15cb3dSCy Schubert 				event_add(&info[i].ev, ms_100);
7812b15cb3dSCy Schubert 			} else {
7822b15cb3dSCy Schubert 				event_add(&info[i].ev, ms_100);
7832b15cb3dSCy Schubert 			}
7842b15cb3dSCy Schubert 		} else {
7852b15cb3dSCy Schubert 			event_add(&info[i].ev, ms_200);
7862b15cb3dSCy Schubert 		}
7872b15cb3dSCy Schubert 	}
7882b15cb3dSCy Schubert 
7892b15cb3dSCy Schubert 	event_base_assert_ok_(base);
7902b15cb3dSCy Schubert 	evutil_gettimeofday(&start, NULL);
7912b15cb3dSCy Schubert 	event_base_dispatch(base);
7922b15cb3dSCy Schubert 
7932b15cb3dSCy Schubert 	event_base_assert_ok_(base);
7942b15cb3dSCy Schubert 
7952b15cb3dSCy Schubert 	for (i=0; i<10; ++i) {
7962b15cb3dSCy Schubert 		tt_int_op(info[i].count, ==, 4);
7972b15cb3dSCy Schubert 		if (i % 2) {
7982b15cb3dSCy Schubert 			test_timeval_diff_eq(&start, &info[i].called_at, 400);
7992b15cb3dSCy Schubert 		} else {
8002b15cb3dSCy Schubert 			test_timeval_diff_eq(&start, &info[i].called_at, 800);
8012b15cb3dSCy Schubert 		}
8022b15cb3dSCy Schubert 	}
8032b15cb3dSCy Schubert 
8042b15cb3dSCy Schubert 	/* Make sure we can free the base with some events in. */
8052b15cb3dSCy Schubert 	for (i=0; i<100; ++i) {
8062b15cb3dSCy Schubert 		if (i % 2) {
8072b15cb3dSCy Schubert 			event_add(&info[i].ev, ms_100);
8082b15cb3dSCy Schubert 		} else {
8092b15cb3dSCy Schubert 			event_add(&info[i].ev, ms_200);
8102b15cb3dSCy Schubert 		}
8112b15cb3dSCy Schubert 	}
8122b15cb3dSCy Schubert 
8132b15cb3dSCy Schubert end:
8142b15cb3dSCy Schubert 	event_base_free(data->base); /* need to do this here before info is
8152b15cb3dSCy Schubert 				      * out-of-scope */
8162b15cb3dSCy Schubert 	data->base = NULL;
8172b15cb3dSCy Schubert }
8182b15cb3dSCy Schubert 
8192b15cb3dSCy Schubert #ifndef _WIN32
8202b15cb3dSCy Schubert static void signal_cb(evutil_socket_t fd, short event, void *arg);
8212b15cb3dSCy Schubert 
8222b15cb3dSCy Schubert #define current_base event_global_current_base_
8232b15cb3dSCy Schubert extern struct event_base *current_base;
8242b15cb3dSCy Schubert 
8252b15cb3dSCy Schubert static void
8262b15cb3dSCy Schubert child_signal_cb(evutil_socket_t fd, short event, void *arg)
8272b15cb3dSCy Schubert {
8282b15cb3dSCy Schubert 	struct timeval tv;
8292b15cb3dSCy Schubert 	int *pint = arg;
8302b15cb3dSCy Schubert 
8312b15cb3dSCy Schubert 	*pint = 1;
8322b15cb3dSCy Schubert 
8332b15cb3dSCy Schubert 	tv.tv_usec = 500000;
8342b15cb3dSCy Schubert 	tv.tv_sec = 0;
8352b15cb3dSCy Schubert 	event_loopexit(&tv);
8362b15cb3dSCy Schubert }
8372b15cb3dSCy Schubert 
8382b15cb3dSCy Schubert static void
8392b15cb3dSCy Schubert test_fork(void)
8402b15cb3dSCy Schubert {
8412b15cb3dSCy Schubert 	int status, got_sigchld = 0;
8422b15cb3dSCy Schubert 	struct event ev, sig_ev;
8432b15cb3dSCy Schubert 	pid_t pid;
8442b15cb3dSCy Schubert 
8452b15cb3dSCy Schubert 	setup_test("After fork: ");
8462b15cb3dSCy Schubert 
8472b15cb3dSCy Schubert 	tt_assert(current_base);
8482b15cb3dSCy Schubert 	evthread_make_base_notifiable(current_base);
8492b15cb3dSCy Schubert 
8502b15cb3dSCy Schubert 	if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) {
8512b15cb3dSCy Schubert 		tt_fail_perror("write");
8522b15cb3dSCy Schubert 	}
8532b15cb3dSCy Schubert 
8542b15cb3dSCy Schubert 	event_set(&ev, pair[1], EV_READ, simple_read_cb, &ev);
8552b15cb3dSCy Schubert 	if (event_add(&ev, NULL) == -1)
8562b15cb3dSCy Schubert 		exit(1);
8572b15cb3dSCy Schubert 
8582b15cb3dSCy Schubert 	evsignal_set(&sig_ev, SIGCHLD, child_signal_cb, &got_sigchld);
8592b15cb3dSCy Schubert 	evsignal_add(&sig_ev, NULL);
8602b15cb3dSCy Schubert 
8612b15cb3dSCy Schubert 	event_base_assert_ok_(current_base);
8622b15cb3dSCy Schubert 	TT_BLATHER(("Before fork"));
8632b15cb3dSCy Schubert 	if ((pid = regress_fork()) == 0) {
8642b15cb3dSCy Schubert 		/* in the child */
8652b15cb3dSCy Schubert 		TT_BLATHER(("In child, before reinit"));
8662b15cb3dSCy Schubert 		event_base_assert_ok_(current_base);
8672b15cb3dSCy Schubert 		if (event_reinit(current_base) == -1) {
8682b15cb3dSCy Schubert 			fprintf(stdout, "FAILED (reinit)\n");
8692b15cb3dSCy Schubert 			exit(1);
8702b15cb3dSCy Schubert 		}
8712b15cb3dSCy Schubert 		TT_BLATHER(("After reinit"));
8722b15cb3dSCy Schubert 		event_base_assert_ok_(current_base);
8732b15cb3dSCy Schubert 		TT_BLATHER(("After assert-ok"));
8742b15cb3dSCy Schubert 
8752b15cb3dSCy Schubert 		evsignal_del(&sig_ev);
8762b15cb3dSCy Schubert 
8772b15cb3dSCy Schubert 		called = 0;
8782b15cb3dSCy Schubert 
8792b15cb3dSCy Schubert 		event_dispatch();
8802b15cb3dSCy Schubert 
8812b15cb3dSCy Schubert 		event_base_free(current_base);
8822b15cb3dSCy Schubert 
8832b15cb3dSCy Schubert 		/* we do not send an EOF; simple_read_cb requires an EOF
8842b15cb3dSCy Schubert 		 * to set test_ok.  we just verify that the callback was
8852b15cb3dSCy Schubert 		 * called. */
8862b15cb3dSCy Schubert 		exit(test_ok != 0 || called != 2 ? -2 : 76);
8872b15cb3dSCy Schubert 	}
8882b15cb3dSCy Schubert 
8892b15cb3dSCy Schubert 	/* wait for the child to read the data */
8902b15cb3dSCy Schubert 	{
8912b15cb3dSCy Schubert 		const struct timeval tv = { 0, 100000 };
8922b15cb3dSCy Schubert 		evutil_usleep_(&tv);
8932b15cb3dSCy Schubert 	}
8942b15cb3dSCy Schubert 
8952b15cb3dSCy Schubert 	if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) {
8962b15cb3dSCy Schubert 		tt_fail_perror("write");
8972b15cb3dSCy Schubert 	}
8982b15cb3dSCy Schubert 
8992b15cb3dSCy Schubert 	TT_BLATHER(("Before waitpid"));
9002b15cb3dSCy Schubert 	if (waitpid(pid, &status, 0) == -1) {
9012b15cb3dSCy Schubert 		fprintf(stdout, "FAILED (fork)\n");
9022b15cb3dSCy Schubert 		exit(1);
9032b15cb3dSCy Schubert 	}
9042b15cb3dSCy Schubert 	TT_BLATHER(("After waitpid"));
9052b15cb3dSCy Schubert 
9062b15cb3dSCy Schubert 	if (WEXITSTATUS(status) != 76) {
9072b15cb3dSCy Schubert 		fprintf(stdout, "FAILED (exit): %d\n", WEXITSTATUS(status));
9082b15cb3dSCy Schubert 		exit(1);
9092b15cb3dSCy Schubert 	}
9102b15cb3dSCy Schubert 
9112b15cb3dSCy Schubert 	/* test that the current event loop still works */
9122b15cb3dSCy Schubert 	if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) {
9132b15cb3dSCy Schubert 		fprintf(stderr, "%s: write\n", __func__);
9142b15cb3dSCy Schubert 	}
9152b15cb3dSCy Schubert 
9162b15cb3dSCy Schubert 	shutdown(pair[0], SHUT_WR);
9172b15cb3dSCy Schubert 
9182b15cb3dSCy Schubert 	event_dispatch();
9192b15cb3dSCy Schubert 
9202b15cb3dSCy Schubert 	if (!got_sigchld) {
9212b15cb3dSCy Schubert 		fprintf(stdout, "FAILED (sigchld)\n");
9222b15cb3dSCy Schubert 		exit(1);
9232b15cb3dSCy Schubert 	}
9242b15cb3dSCy Schubert 
9252b15cb3dSCy Schubert 	evsignal_del(&sig_ev);
9262b15cb3dSCy Schubert 
9272b15cb3dSCy Schubert 	end:
9282b15cb3dSCy Schubert 	cleanup_test();
9292b15cb3dSCy Schubert }
9302b15cb3dSCy Schubert 
9312b15cb3dSCy Schubert static void
9322b15cb3dSCy Schubert signal_cb_sa(int sig)
9332b15cb3dSCy Schubert {
9342b15cb3dSCy Schubert 	test_ok = 2;
9352b15cb3dSCy Schubert }
9362b15cb3dSCy Schubert 
9372b15cb3dSCy Schubert static void
9382b15cb3dSCy Schubert signal_cb(evutil_socket_t fd, short event, void *arg)
9392b15cb3dSCy Schubert {
9402b15cb3dSCy Schubert 	struct event *ev = arg;
9412b15cb3dSCy Schubert 
9422b15cb3dSCy Schubert 	evsignal_del(ev);
9432b15cb3dSCy Schubert 	test_ok = 1;
9442b15cb3dSCy Schubert }
9452b15cb3dSCy Schubert 
9462b15cb3dSCy Schubert static void
947*a25439b6SCy Schubert test_simplesignal_impl(int find_reorder)
9482b15cb3dSCy Schubert {
9492b15cb3dSCy Schubert 	struct event ev;
9502b15cb3dSCy Schubert 	struct itimerval itv;
9512b15cb3dSCy Schubert 
9522b15cb3dSCy Schubert 	evsignal_set(&ev, SIGALRM, signal_cb, &ev);
9532b15cb3dSCy Schubert 	evsignal_add(&ev, NULL);
9542b15cb3dSCy Schubert 	/* find bugs in which operations are re-ordered */
955*a25439b6SCy Schubert 	if (find_reorder) {
9562b15cb3dSCy Schubert 		evsignal_del(&ev);
9572b15cb3dSCy Schubert 		evsignal_add(&ev, NULL);
958*a25439b6SCy Schubert 	}
9592b15cb3dSCy Schubert 
9602b15cb3dSCy Schubert 	memset(&itv, 0, sizeof(itv));
9612b15cb3dSCy Schubert 	itv.it_value.tv_sec = 0;
9622b15cb3dSCy Schubert 	itv.it_value.tv_usec = 100000;
9632b15cb3dSCy Schubert 	if (setitimer(ITIMER_REAL, &itv, NULL) == -1)
9642b15cb3dSCy Schubert 		goto skip_simplesignal;
9652b15cb3dSCy Schubert 
9662b15cb3dSCy Schubert 	event_dispatch();
9672b15cb3dSCy Schubert  skip_simplesignal:
9682b15cb3dSCy Schubert 	if (evsignal_del(&ev) == -1)
9692b15cb3dSCy Schubert 		test_ok = 0;
9702b15cb3dSCy Schubert 
9712b15cb3dSCy Schubert 	cleanup_test();
9722b15cb3dSCy Schubert }
9732b15cb3dSCy Schubert 
9742b15cb3dSCy Schubert static void
975*a25439b6SCy Schubert test_simplestsignal(void)
976*a25439b6SCy Schubert {
977*a25439b6SCy Schubert 	setup_test("Simplest one signal: ");
978*a25439b6SCy Schubert 	test_simplesignal_impl(0);
979*a25439b6SCy Schubert }
980*a25439b6SCy Schubert 
981*a25439b6SCy Schubert static void
982*a25439b6SCy Schubert test_simplesignal(void)
983*a25439b6SCy Schubert {
984*a25439b6SCy Schubert 	setup_test("Simple signal: ");
985*a25439b6SCy Schubert 	test_simplesignal_impl(1);
986*a25439b6SCy Schubert }
987*a25439b6SCy Schubert 
988*a25439b6SCy Schubert static void
9892b15cb3dSCy Schubert test_multiplesignal(void)
9902b15cb3dSCy Schubert {
9912b15cb3dSCy Schubert 	struct event ev_one, ev_two;
9922b15cb3dSCy Schubert 	struct itimerval itv;
9932b15cb3dSCy Schubert 
9942b15cb3dSCy Schubert 	setup_test("Multiple signal: ");
9952b15cb3dSCy Schubert 
9962b15cb3dSCy Schubert 	evsignal_set(&ev_one, SIGALRM, signal_cb, &ev_one);
9972b15cb3dSCy Schubert 	evsignal_add(&ev_one, NULL);
9982b15cb3dSCy Schubert 
9992b15cb3dSCy Schubert 	evsignal_set(&ev_two, SIGALRM, signal_cb, &ev_two);
10002b15cb3dSCy Schubert 	evsignal_add(&ev_two, NULL);
10012b15cb3dSCy Schubert 
10022b15cb3dSCy Schubert 	memset(&itv, 0, sizeof(itv));
10032b15cb3dSCy Schubert 	itv.it_value.tv_sec = 0;
10042b15cb3dSCy Schubert 	itv.it_value.tv_usec = 100000;
10052b15cb3dSCy Schubert 	if (setitimer(ITIMER_REAL, &itv, NULL) == -1)
10062b15cb3dSCy Schubert 		goto skip_simplesignal;
10072b15cb3dSCy Schubert 
10082b15cb3dSCy Schubert 	event_dispatch();
10092b15cb3dSCy Schubert 
10102b15cb3dSCy Schubert  skip_simplesignal:
10112b15cb3dSCy Schubert 	if (evsignal_del(&ev_one) == -1)
10122b15cb3dSCy Schubert 		test_ok = 0;
10132b15cb3dSCy Schubert 	if (evsignal_del(&ev_two) == -1)
10142b15cb3dSCy Schubert 		test_ok = 0;
10152b15cb3dSCy Schubert 
10162b15cb3dSCy Schubert 	cleanup_test();
10172b15cb3dSCy Schubert }
10182b15cb3dSCy Schubert 
10192b15cb3dSCy Schubert static void
10202b15cb3dSCy Schubert test_immediatesignal(void)
10212b15cb3dSCy Schubert {
10222b15cb3dSCy Schubert 	struct event ev;
10232b15cb3dSCy Schubert 
10242b15cb3dSCy Schubert 	test_ok = 0;
10252b15cb3dSCy Schubert 	evsignal_set(&ev, SIGUSR1, signal_cb, &ev);
10262b15cb3dSCy Schubert 	evsignal_add(&ev, NULL);
10272b15cb3dSCy Schubert 	raise(SIGUSR1);
10282b15cb3dSCy Schubert 	event_loop(EVLOOP_NONBLOCK);
10292b15cb3dSCy Schubert 	evsignal_del(&ev);
10302b15cb3dSCy Schubert 	cleanup_test();
10312b15cb3dSCy Schubert }
10322b15cb3dSCy Schubert 
10332b15cb3dSCy Schubert static void
10342b15cb3dSCy Schubert test_signal_dealloc(void)
10352b15cb3dSCy Schubert {
10362b15cb3dSCy Schubert 	/* make sure that evsignal_event is event_del'ed and pipe closed */
10372b15cb3dSCy Schubert 	struct event ev;
10382b15cb3dSCy Schubert 	struct event_base *base = event_init();
10392b15cb3dSCy Schubert 	evsignal_set(&ev, SIGUSR1, signal_cb, &ev);
10402b15cb3dSCy Schubert 	evsignal_add(&ev, NULL);
10412b15cb3dSCy Schubert 	evsignal_del(&ev);
10422b15cb3dSCy Schubert 	event_base_free(base);
10432b15cb3dSCy Schubert 	/* If we got here without asserting, we're fine. */
10442b15cb3dSCy Schubert 	test_ok = 1;
10452b15cb3dSCy Schubert 	cleanup_test();
10462b15cb3dSCy Schubert }
10472b15cb3dSCy Schubert 
10482b15cb3dSCy Schubert static void
10492b15cb3dSCy Schubert test_signal_pipeloss(void)
10502b15cb3dSCy Schubert {
10512b15cb3dSCy Schubert 	/* make sure that the base1 pipe is closed correctly. */
10522b15cb3dSCy Schubert 	struct event_base *base1, *base2;
10532b15cb3dSCy Schubert 	int pipe1;
10542b15cb3dSCy Schubert 	test_ok = 0;
10552b15cb3dSCy Schubert 	base1 = event_init();
10562b15cb3dSCy Schubert 	pipe1 = base1->sig.ev_signal_pair[0];
10572b15cb3dSCy Schubert 	base2 = event_init();
10582b15cb3dSCy Schubert 	event_base_free(base2);
10592b15cb3dSCy Schubert 	event_base_free(base1);
10602b15cb3dSCy Schubert 	if (close(pipe1) != -1 || errno!=EBADF) {
10612b15cb3dSCy Schubert 		/* fd must be closed, so second close gives -1, EBADF */
10622b15cb3dSCy Schubert 		printf("signal pipe not closed. ");
10632b15cb3dSCy Schubert 		test_ok = 0;
10642b15cb3dSCy Schubert 	} else {
10652b15cb3dSCy Schubert 		test_ok = 1;
10662b15cb3dSCy Schubert 	}
10672b15cb3dSCy Schubert 	cleanup_test();
10682b15cb3dSCy Schubert }
10692b15cb3dSCy Schubert 
10702b15cb3dSCy Schubert /*
10712b15cb3dSCy Schubert  * make two bases to catch signals, use both of them.  this only works
10722b15cb3dSCy Schubert  * for event mechanisms that use our signal pipe trick.	 kqueue handles
10732b15cb3dSCy Schubert  * signals internally, and all interested kqueues get all the signals.
10742b15cb3dSCy Schubert  */
10752b15cb3dSCy Schubert static void
10762b15cb3dSCy Schubert test_signal_switchbase(void)
10772b15cb3dSCy Schubert {
10782b15cb3dSCy Schubert 	struct event ev1, ev2;
10792b15cb3dSCy Schubert 	struct event_base *base1, *base2;
10802b15cb3dSCy Schubert 	int is_kqueue;
10812b15cb3dSCy Schubert 	test_ok = 0;
10822b15cb3dSCy Schubert 	base1 = event_init();
10832b15cb3dSCy Schubert 	base2 = event_init();
10842b15cb3dSCy Schubert 	is_kqueue = !strcmp(event_get_method(),"kqueue");
10852b15cb3dSCy Schubert 	evsignal_set(&ev1, SIGUSR1, signal_cb, &ev1);
10862b15cb3dSCy Schubert 	evsignal_set(&ev2, SIGUSR1, signal_cb, &ev2);
10872b15cb3dSCy Schubert 	if (event_base_set(base1, &ev1) ||
10882b15cb3dSCy Schubert 	    event_base_set(base2, &ev2) ||
10892b15cb3dSCy Schubert 	    event_add(&ev1, NULL) ||
10902b15cb3dSCy Schubert 	    event_add(&ev2, NULL)) {
10912b15cb3dSCy Schubert 		fprintf(stderr, "%s: cannot set base, add\n", __func__);
10922b15cb3dSCy Schubert 		exit(1);
10932b15cb3dSCy Schubert 	}
10942b15cb3dSCy Schubert 
10952b15cb3dSCy Schubert 	tt_ptr_op(event_get_base(&ev1), ==, base1);
10962b15cb3dSCy Schubert 	tt_ptr_op(event_get_base(&ev2), ==, base2);
10972b15cb3dSCy Schubert 
10982b15cb3dSCy Schubert 	test_ok = 0;
10992b15cb3dSCy Schubert 	/* can handle signal before loop is called */
11002b15cb3dSCy Schubert 	raise(SIGUSR1);
11012b15cb3dSCy Schubert 	event_base_loop(base2, EVLOOP_NONBLOCK);
11022b15cb3dSCy Schubert 	if (is_kqueue) {
11032b15cb3dSCy Schubert 		if (!test_ok)
11042b15cb3dSCy Schubert 			goto end;
11052b15cb3dSCy Schubert 		test_ok = 0;
11062b15cb3dSCy Schubert 	}
11072b15cb3dSCy Schubert 	event_base_loop(base1, EVLOOP_NONBLOCK);
11082b15cb3dSCy Schubert 	if (test_ok && !is_kqueue) {
11092b15cb3dSCy Schubert 		test_ok = 0;
11102b15cb3dSCy Schubert 
11112b15cb3dSCy Schubert 		/* set base1 to handle signals */
11122b15cb3dSCy Schubert 		event_base_loop(base1, EVLOOP_NONBLOCK);
11132b15cb3dSCy Schubert 		raise(SIGUSR1);
11142b15cb3dSCy Schubert 		event_base_loop(base1, EVLOOP_NONBLOCK);
11152b15cb3dSCy Schubert 		event_base_loop(base2, EVLOOP_NONBLOCK);
11162b15cb3dSCy Schubert 	}
11172b15cb3dSCy Schubert end:
11182b15cb3dSCy Schubert 	event_base_free(base1);
11192b15cb3dSCy Schubert 	event_base_free(base2);
11202b15cb3dSCy Schubert 	cleanup_test();
11212b15cb3dSCy Schubert }
11222b15cb3dSCy Schubert 
11232b15cb3dSCy Schubert /*
11242b15cb3dSCy Schubert  * assert that a signal event removed from the event queue really is
11252b15cb3dSCy Schubert  * removed - with no possibility of it's parent handler being fired.
11262b15cb3dSCy Schubert  */
11272b15cb3dSCy Schubert static void
11282b15cb3dSCy Schubert test_signal_assert(void)
11292b15cb3dSCy Schubert {
11302b15cb3dSCy Schubert 	struct event ev;
11312b15cb3dSCy Schubert 	struct event_base *base = event_init();
11322b15cb3dSCy Schubert 	test_ok = 0;
11332b15cb3dSCy Schubert 	/* use SIGCONT so we don't kill ourselves when we signal to nowhere */
11342b15cb3dSCy Schubert 	evsignal_set(&ev, SIGCONT, signal_cb, &ev);
11352b15cb3dSCy Schubert 	evsignal_add(&ev, NULL);
11362b15cb3dSCy Schubert 	/*
11372b15cb3dSCy Schubert 	 * if evsignal_del() fails to reset the handler, it's current handler
11382b15cb3dSCy Schubert 	 * will still point to evsig_handler().
11392b15cb3dSCy Schubert 	 */
11402b15cb3dSCy Schubert 	evsignal_del(&ev);
11412b15cb3dSCy Schubert 
11422b15cb3dSCy Schubert 	raise(SIGCONT);
11432b15cb3dSCy Schubert #if 0
11442b15cb3dSCy Schubert 	/* only way to verify we were in evsig_handler() */
11452b15cb3dSCy Schubert 	/* XXXX Now there's no longer a good way. */
11462b15cb3dSCy Schubert 	if (base->sig.evsig_caught)
11472b15cb3dSCy Schubert 		test_ok = 0;
11482b15cb3dSCy Schubert 	else
11492b15cb3dSCy Schubert 		test_ok = 1;
11502b15cb3dSCy Schubert #else
11512b15cb3dSCy Schubert 	test_ok = 1;
11522b15cb3dSCy Schubert #endif
11532b15cb3dSCy Schubert 
11542b15cb3dSCy Schubert 	event_base_free(base);
11552b15cb3dSCy Schubert 	cleanup_test();
11562b15cb3dSCy Schubert 	return;
11572b15cb3dSCy Schubert }
11582b15cb3dSCy Schubert 
11592b15cb3dSCy Schubert /*
11602b15cb3dSCy Schubert  * assert that we restore our previous signal handler properly.
11612b15cb3dSCy Schubert  */
11622b15cb3dSCy Schubert static void
11632b15cb3dSCy Schubert test_signal_restore(void)
11642b15cb3dSCy Schubert {
11652b15cb3dSCy Schubert 	struct event ev;
11662b15cb3dSCy Schubert 	struct event_base *base = event_init();
11672b15cb3dSCy Schubert #ifdef EVENT__HAVE_SIGACTION
11682b15cb3dSCy Schubert 	struct sigaction sa;
11692b15cb3dSCy Schubert #endif
11702b15cb3dSCy Schubert 
11712b15cb3dSCy Schubert 	test_ok = 0;
11722b15cb3dSCy Schubert #ifdef EVENT__HAVE_SIGACTION
11732b15cb3dSCy Schubert 	sa.sa_handler = signal_cb_sa;
11742b15cb3dSCy Schubert 	sa.sa_flags = 0x0;
11752b15cb3dSCy Schubert 	sigemptyset(&sa.sa_mask);
11762b15cb3dSCy Schubert 	if (sigaction(SIGUSR1, &sa, NULL) == -1)
11772b15cb3dSCy Schubert 		goto out;
11782b15cb3dSCy Schubert #else
11792b15cb3dSCy Schubert 	if (signal(SIGUSR1, signal_cb_sa) == SIG_ERR)
11802b15cb3dSCy Schubert 		goto out;
11812b15cb3dSCy Schubert #endif
11822b15cb3dSCy Schubert 	evsignal_set(&ev, SIGUSR1, signal_cb, &ev);
11832b15cb3dSCy Schubert 	evsignal_add(&ev, NULL);
11842b15cb3dSCy Schubert 	evsignal_del(&ev);
11852b15cb3dSCy Schubert 
11862b15cb3dSCy Schubert 	raise(SIGUSR1);
11872b15cb3dSCy Schubert 	/* 1 == signal_cb, 2 == signal_cb_sa, we want our previous handler */
11882b15cb3dSCy Schubert 	if (test_ok != 2)
11892b15cb3dSCy Schubert 		test_ok = 0;
11902b15cb3dSCy Schubert out:
11912b15cb3dSCy Schubert 	event_base_free(base);
11922b15cb3dSCy Schubert 	cleanup_test();
11932b15cb3dSCy Schubert 	return;
11942b15cb3dSCy Schubert }
11952b15cb3dSCy Schubert 
11962b15cb3dSCy Schubert static void
11972b15cb3dSCy Schubert signal_cb_swp(int sig, short event, void *arg)
11982b15cb3dSCy Schubert {
11992b15cb3dSCy Schubert 	called++;
12002b15cb3dSCy Schubert 	if (called < 5)
12012b15cb3dSCy Schubert 		raise(sig);
12022b15cb3dSCy Schubert 	else
12032b15cb3dSCy Schubert 		event_loopexit(NULL);
12042b15cb3dSCy Schubert }
12052b15cb3dSCy Schubert static void
12062b15cb3dSCy Schubert timeout_cb_swp(evutil_socket_t fd, short event, void *arg)
12072b15cb3dSCy Schubert {
12082b15cb3dSCy Schubert 	if (called == -1) {
12092b15cb3dSCy Schubert 		struct timeval tv = {5, 0};
12102b15cb3dSCy Schubert 
12112b15cb3dSCy Schubert 		called = 0;
12122b15cb3dSCy Schubert 		evtimer_add((struct event *)arg, &tv);
12132b15cb3dSCy Schubert 		raise(SIGUSR1);
12142b15cb3dSCy Schubert 		return;
12152b15cb3dSCy Schubert 	}
12162b15cb3dSCy Schubert 	test_ok = 0;
12172b15cb3dSCy Schubert 	event_loopexit(NULL);
12182b15cb3dSCy Schubert }
12192b15cb3dSCy Schubert 
12202b15cb3dSCy Schubert static void
12212b15cb3dSCy Schubert test_signal_while_processing(void)
12222b15cb3dSCy Schubert {
12232b15cb3dSCy Schubert 	struct event_base *base = event_init();
12242b15cb3dSCy Schubert 	struct event ev, ev_timer;
12252b15cb3dSCy Schubert 	struct timeval tv = {0, 0};
12262b15cb3dSCy Schubert 
12272b15cb3dSCy Schubert 	setup_test("Receiving a signal while processing other signal: ");
12282b15cb3dSCy Schubert 
12292b15cb3dSCy Schubert 	called = -1;
12302b15cb3dSCy Schubert 	test_ok = 1;
12312b15cb3dSCy Schubert 	signal_set(&ev, SIGUSR1, signal_cb_swp, NULL);
12322b15cb3dSCy Schubert 	signal_add(&ev, NULL);
12332b15cb3dSCy Schubert 	evtimer_set(&ev_timer, timeout_cb_swp, &ev_timer);
12342b15cb3dSCy Schubert 	evtimer_add(&ev_timer, &tv);
12352b15cb3dSCy Schubert 	event_dispatch();
12362b15cb3dSCy Schubert 
12372b15cb3dSCy Schubert 	event_base_free(base);
12382b15cb3dSCy Schubert 	cleanup_test();
12392b15cb3dSCy Schubert 	return;
12402b15cb3dSCy Schubert }
12412b15cb3dSCy Schubert #endif
12422b15cb3dSCy Schubert 
12432b15cb3dSCy Schubert static void
12442b15cb3dSCy Schubert test_free_active_base(void *ptr)
12452b15cb3dSCy Schubert {
12462b15cb3dSCy Schubert 	struct basic_test_data *data = ptr;
12472b15cb3dSCy Schubert 	struct event_base *base1;
12482b15cb3dSCy Schubert 	struct event ev1;
12492b15cb3dSCy Schubert 
12502b15cb3dSCy Schubert 	base1 = event_init();
12512b15cb3dSCy Schubert 	if (base1) {
12522b15cb3dSCy Schubert 		event_assign(&ev1, base1, data->pair[1], EV_READ,
12532b15cb3dSCy Schubert 			     dummy_read_cb, NULL);
12542b15cb3dSCy Schubert 		event_add(&ev1, NULL);
12552b15cb3dSCy Schubert 		event_base_free(base1);	 /* should not crash */
12562b15cb3dSCy Schubert 	} else {
12572b15cb3dSCy Schubert 		tt_fail_msg("failed to create event_base for test");
12582b15cb3dSCy Schubert 	}
12592b15cb3dSCy Schubert 
12602b15cb3dSCy Schubert 	base1 = event_init();
12612b15cb3dSCy Schubert 	tt_assert(base1);
12622b15cb3dSCy Schubert 	event_assign(&ev1, base1, 0, 0, dummy_read_cb, NULL);
12632b15cb3dSCy Schubert 	event_active(&ev1, EV_READ, 1);
12642b15cb3dSCy Schubert 	event_base_free(base1);
12652b15cb3dSCy Schubert end:
12662b15cb3dSCy Schubert 	;
12672b15cb3dSCy Schubert }
12682b15cb3dSCy Schubert 
12692b15cb3dSCy Schubert static void
12702b15cb3dSCy Schubert test_manipulate_active_events(void *ptr)
12712b15cb3dSCy Schubert {
12722b15cb3dSCy Schubert 	struct basic_test_data *data = ptr;
12732b15cb3dSCy Schubert 	struct event_base *base = data->base;
12742b15cb3dSCy Schubert 	struct event ev1;
12752b15cb3dSCy Schubert 
12762b15cb3dSCy Schubert 	event_assign(&ev1, base, -1, EV_TIMEOUT, dummy_read_cb, NULL);
12772b15cb3dSCy Schubert 
12782b15cb3dSCy Schubert 	/* Make sure an active event is pending. */
12792b15cb3dSCy Schubert 	event_active(&ev1, EV_READ, 1);
12802b15cb3dSCy Schubert 	tt_int_op(event_pending(&ev1, EV_READ|EV_TIMEOUT|EV_WRITE, NULL),
12812b15cb3dSCy Schubert 	    ==, EV_READ);
12822b15cb3dSCy Schubert 
12832b15cb3dSCy Schubert 	/* Make sure that activating an event twice works. */
12842b15cb3dSCy Schubert 	event_active(&ev1, EV_WRITE, 1);
12852b15cb3dSCy Schubert 	tt_int_op(event_pending(&ev1, EV_READ|EV_TIMEOUT|EV_WRITE, NULL),
12862b15cb3dSCy Schubert 	    ==, EV_READ|EV_WRITE);
12872b15cb3dSCy Schubert 
12882b15cb3dSCy Schubert end:
12892b15cb3dSCy Schubert 	event_del(&ev1);
12902b15cb3dSCy Schubert }
12912b15cb3dSCy Schubert 
12922b15cb3dSCy Schubert static void
12932b15cb3dSCy Schubert event_selfarg_cb(evutil_socket_t fd, short event, void *arg)
12942b15cb3dSCy Schubert {
12952b15cb3dSCy Schubert 	struct event *ev = arg;
12962b15cb3dSCy Schubert 	struct event_base *base = event_get_base(ev);
12972b15cb3dSCy Schubert 	event_base_assert_ok_(base);
12982b15cb3dSCy Schubert 	event_base_loopexit(base, NULL);
12992b15cb3dSCy Schubert 	tt_want(ev == event_base_get_running_event(base));
13002b15cb3dSCy Schubert }
13012b15cb3dSCy Schubert 
13022b15cb3dSCy Schubert static void
13032b15cb3dSCy Schubert test_event_new_selfarg(void *ptr)
13042b15cb3dSCy Schubert {
13052b15cb3dSCy Schubert 	struct basic_test_data *data = ptr;
13062b15cb3dSCy Schubert 	struct event_base *base = data->base;
13072b15cb3dSCy Schubert 	struct event *ev = event_new(base, -1, EV_READ, event_selfarg_cb,
13082b15cb3dSCy Schubert                                      event_self_cbarg());
13092b15cb3dSCy Schubert 
13102b15cb3dSCy Schubert 	event_active(ev, EV_READ, 1);
13112b15cb3dSCy Schubert 	event_base_dispatch(base);
13122b15cb3dSCy Schubert 
13132b15cb3dSCy Schubert 	event_free(ev);
13142b15cb3dSCy Schubert }
13152b15cb3dSCy Schubert 
13162b15cb3dSCy Schubert static void
13172b15cb3dSCy Schubert test_event_assign_selfarg(void *ptr)
13182b15cb3dSCy Schubert {
13192b15cb3dSCy Schubert 	struct basic_test_data *data = ptr;
13202b15cb3dSCy Schubert 	struct event_base *base = data->base;
13212b15cb3dSCy Schubert 	struct event ev;
13222b15cb3dSCy Schubert 
13232b15cb3dSCy Schubert 	event_assign(&ev, base, -1, EV_READ, event_selfarg_cb,
13242b15cb3dSCy Schubert                      event_self_cbarg());
13252b15cb3dSCy Schubert 	event_active(&ev, EV_READ, 1);
13262b15cb3dSCy Schubert 	event_base_dispatch(base);
13272b15cb3dSCy Schubert }
13282b15cb3dSCy Schubert 
13292b15cb3dSCy Schubert static void
13302b15cb3dSCy Schubert test_event_base_get_num_events(void *ptr)
13312b15cb3dSCy Schubert {
13322b15cb3dSCy Schubert 	struct basic_test_data *data = ptr;
13332b15cb3dSCy Schubert 	struct event_base *base = data->base;
13342b15cb3dSCy Schubert 	struct event ev;
13352b15cb3dSCy Schubert 	int event_count_active;
13362b15cb3dSCy Schubert 	int event_count_virtual;
13372b15cb3dSCy Schubert 	int event_count_added;
13382b15cb3dSCy Schubert 	int event_count_active_virtual;
13392b15cb3dSCy Schubert 	int event_count_active_added;
13402b15cb3dSCy Schubert 	int event_count_virtual_added;
13412b15cb3dSCy Schubert 	int event_count_active_added_virtual;
13422b15cb3dSCy Schubert 
13432b15cb3dSCy Schubert 	struct timeval qsec = {0, 100000};
13442b15cb3dSCy Schubert 
13452b15cb3dSCy Schubert 	event_assign(&ev, base, -1, EV_READ, event_selfarg_cb,
13462b15cb3dSCy Schubert 	    event_self_cbarg());
13472b15cb3dSCy Schubert 
13482b15cb3dSCy Schubert 	event_add(&ev, &qsec);
13492b15cb3dSCy Schubert 	event_count_active = event_base_get_num_events(base,
13502b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ACTIVE);
13512b15cb3dSCy Schubert 	event_count_virtual = event_base_get_num_events(base,
13522b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_VIRTUAL);
13532b15cb3dSCy Schubert 	event_count_added = event_base_get_num_events(base,
13542b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ADDED);
13552b15cb3dSCy Schubert 	event_count_active_virtual = event_base_get_num_events(base,
13562b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ACTIVE|EVENT_BASE_COUNT_VIRTUAL);
13572b15cb3dSCy Schubert 	event_count_active_added = event_base_get_num_events(base,
13582b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ACTIVE|EVENT_BASE_COUNT_ADDED);
13592b15cb3dSCy Schubert 	event_count_virtual_added = event_base_get_num_events(base,
13602b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_VIRTUAL|EVENT_BASE_COUNT_ADDED);
13612b15cb3dSCy Schubert 	event_count_active_added_virtual = event_base_get_num_events(base,
13622b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ACTIVE|
13632b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ADDED|
13642b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_VIRTUAL);
13652b15cb3dSCy Schubert 	tt_int_op(event_count_active, ==, 0);
13662b15cb3dSCy Schubert 	tt_int_op(event_count_virtual, ==, 0);
13672b15cb3dSCy Schubert 	/* libevent itself adds a timeout event, so the event_count is 2 here */
13682b15cb3dSCy Schubert 	tt_int_op(event_count_added, ==, 2);
13692b15cb3dSCy Schubert 	tt_int_op(event_count_active_virtual, ==, 0);
13702b15cb3dSCy Schubert 	tt_int_op(event_count_active_added, ==, 2);
13712b15cb3dSCy Schubert 	tt_int_op(event_count_virtual_added, ==, 2);
13722b15cb3dSCy Schubert 	tt_int_op(event_count_active_added_virtual, ==, 2);
13732b15cb3dSCy Schubert 
13742b15cb3dSCy Schubert 	event_active(&ev, EV_READ, 1);
13752b15cb3dSCy Schubert 	event_count_active = event_base_get_num_events(base,
13762b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ACTIVE);
13772b15cb3dSCy Schubert 	event_count_virtual = event_base_get_num_events(base,
13782b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_VIRTUAL);
13792b15cb3dSCy Schubert 	event_count_added = event_base_get_num_events(base,
13802b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ADDED);
13812b15cb3dSCy Schubert 	event_count_active_virtual = event_base_get_num_events(base,
13822b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ACTIVE|EVENT_BASE_COUNT_VIRTUAL);
13832b15cb3dSCy Schubert 	event_count_active_added = event_base_get_num_events(base,
13842b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ACTIVE|EVENT_BASE_COUNT_ADDED);
13852b15cb3dSCy Schubert 	event_count_virtual_added = event_base_get_num_events(base,
13862b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_VIRTUAL|EVENT_BASE_COUNT_ADDED);
13872b15cb3dSCy Schubert 	event_count_active_added_virtual = event_base_get_num_events(base,
13882b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ACTIVE|
13892b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ADDED|
13902b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_VIRTUAL);
13912b15cb3dSCy Schubert 	tt_int_op(event_count_active, ==, 1);
13922b15cb3dSCy Schubert 	tt_int_op(event_count_virtual, ==, 0);
13932b15cb3dSCy Schubert 	tt_int_op(event_count_added, ==, 3);
13942b15cb3dSCy Schubert 	tt_int_op(event_count_active_virtual, ==, 1);
13952b15cb3dSCy Schubert 	tt_int_op(event_count_active_added, ==, 4);
13962b15cb3dSCy Schubert 	tt_int_op(event_count_virtual_added, ==, 3);
13972b15cb3dSCy Schubert 	tt_int_op(event_count_active_added_virtual, ==, 4);
13982b15cb3dSCy Schubert 
13992b15cb3dSCy Schubert        event_base_loop(base, 0);
14002b15cb3dSCy Schubert        event_count_active = event_base_get_num_events(base,
14012b15cb3dSCy Schubert 	   EVENT_BASE_COUNT_ACTIVE);
14022b15cb3dSCy Schubert        event_count_virtual = event_base_get_num_events(base,
14032b15cb3dSCy Schubert 	   EVENT_BASE_COUNT_VIRTUAL);
14042b15cb3dSCy Schubert        event_count_added = event_base_get_num_events(base,
14052b15cb3dSCy Schubert 	   EVENT_BASE_COUNT_ADDED);
14062b15cb3dSCy Schubert        event_count_active_virtual = event_base_get_num_events(base,
14072b15cb3dSCy Schubert 	   EVENT_BASE_COUNT_ACTIVE|EVENT_BASE_COUNT_VIRTUAL);
14082b15cb3dSCy Schubert        event_count_active_added = event_base_get_num_events(base,
14092b15cb3dSCy Schubert 	   EVENT_BASE_COUNT_ACTIVE|EVENT_BASE_COUNT_ADDED);
14102b15cb3dSCy Schubert        event_count_virtual_added = event_base_get_num_events(base,
14112b15cb3dSCy Schubert 	   EVENT_BASE_COUNT_VIRTUAL|EVENT_BASE_COUNT_ADDED);
14122b15cb3dSCy Schubert        event_count_active_added_virtual = event_base_get_num_events(base,
14132b15cb3dSCy Schubert 	   EVENT_BASE_COUNT_ACTIVE|
14142b15cb3dSCy Schubert 	   EVENT_BASE_COUNT_ADDED|
14152b15cb3dSCy Schubert 	   EVENT_BASE_COUNT_VIRTUAL);
14162b15cb3dSCy Schubert        tt_int_op(event_count_active, ==, 0);
14172b15cb3dSCy Schubert        tt_int_op(event_count_virtual, ==, 0);
14182b15cb3dSCy Schubert        tt_int_op(event_count_added, ==, 0);
14192b15cb3dSCy Schubert        tt_int_op(event_count_active_virtual, ==, 0);
14202b15cb3dSCy Schubert        tt_int_op(event_count_active_added, ==, 0);
14212b15cb3dSCy Schubert        tt_int_op(event_count_virtual_added, ==, 0);
14222b15cb3dSCy Schubert        tt_int_op(event_count_active_added_virtual, ==, 0);
14232b15cb3dSCy Schubert 
14242b15cb3dSCy Schubert        event_base_add_virtual_(base);
14252b15cb3dSCy Schubert        event_count_active = event_base_get_num_events(base,
14262b15cb3dSCy Schubert 	   EVENT_BASE_COUNT_ACTIVE);
14272b15cb3dSCy Schubert        event_count_virtual = event_base_get_num_events(base,
14282b15cb3dSCy Schubert 	   EVENT_BASE_COUNT_VIRTUAL);
14292b15cb3dSCy Schubert        event_count_added = event_base_get_num_events(base,
14302b15cb3dSCy Schubert 	   EVENT_BASE_COUNT_ADDED);
14312b15cb3dSCy Schubert        event_count_active_virtual = event_base_get_num_events(base,
14322b15cb3dSCy Schubert 	   EVENT_BASE_COUNT_ACTIVE|EVENT_BASE_COUNT_VIRTUAL);
14332b15cb3dSCy Schubert        event_count_active_added = event_base_get_num_events(base,
14342b15cb3dSCy Schubert 	   EVENT_BASE_COUNT_ACTIVE|EVENT_BASE_COUNT_ADDED);
14352b15cb3dSCy Schubert        event_count_virtual_added = event_base_get_num_events(base,
14362b15cb3dSCy Schubert 	   EVENT_BASE_COUNT_VIRTUAL|EVENT_BASE_COUNT_ADDED);
14372b15cb3dSCy Schubert        event_count_active_added_virtual = event_base_get_num_events(base,
14382b15cb3dSCy Schubert 	   EVENT_BASE_COUNT_ACTIVE|
14392b15cb3dSCy Schubert 	   EVENT_BASE_COUNT_ADDED|
14402b15cb3dSCy Schubert 	   EVENT_BASE_COUNT_VIRTUAL);
14412b15cb3dSCy Schubert        tt_int_op(event_count_active, ==, 0);
14422b15cb3dSCy Schubert        tt_int_op(event_count_virtual, ==, 1);
14432b15cb3dSCy Schubert        tt_int_op(event_count_added, ==, 0);
14442b15cb3dSCy Schubert        tt_int_op(event_count_active_virtual, ==, 1);
14452b15cb3dSCy Schubert        tt_int_op(event_count_active_added, ==, 0);
14462b15cb3dSCy Schubert        tt_int_op(event_count_virtual_added, ==, 1);
14472b15cb3dSCy Schubert        tt_int_op(event_count_active_added_virtual, ==, 1);
14482b15cb3dSCy Schubert 
14492b15cb3dSCy Schubert end:
14502b15cb3dSCy Schubert        ;
14512b15cb3dSCy Schubert }
14522b15cb3dSCy Schubert 
14532b15cb3dSCy Schubert static void
14542b15cb3dSCy Schubert test_event_base_get_max_events(void *ptr)
14552b15cb3dSCy Schubert {
14562b15cb3dSCy Schubert 	struct basic_test_data *data = ptr;
14572b15cb3dSCy Schubert 	struct event_base *base = data->base;
14582b15cb3dSCy Schubert 	struct event ev;
14592b15cb3dSCy Schubert 	struct event ev2;
14602b15cb3dSCy Schubert 	int event_count_active;
14612b15cb3dSCy Schubert 	int event_count_virtual;
14622b15cb3dSCy Schubert 	int event_count_added;
14632b15cb3dSCy Schubert 	int event_count_active_virtual;
14642b15cb3dSCy Schubert 	int event_count_active_added;
14652b15cb3dSCy Schubert 	int event_count_virtual_added;
14662b15cb3dSCy Schubert 	int event_count_active_added_virtual;
14672b15cb3dSCy Schubert 
14682b15cb3dSCy Schubert 	struct timeval qsec = {0, 100000};
14692b15cb3dSCy Schubert 
14702b15cb3dSCy Schubert 	event_assign(&ev, base, -1, EV_READ, event_selfarg_cb,
14712b15cb3dSCy Schubert 	    event_self_cbarg());
14722b15cb3dSCy Schubert 	event_assign(&ev2, base, -1, EV_READ, event_selfarg_cb,
14732b15cb3dSCy Schubert 	    event_self_cbarg());
14742b15cb3dSCy Schubert 
14752b15cb3dSCy Schubert 	event_add(&ev, &qsec);
14762b15cb3dSCy Schubert 	event_add(&ev2, &qsec);
14772b15cb3dSCy Schubert 	event_del(&ev2);
14782b15cb3dSCy Schubert 
14792b15cb3dSCy Schubert 	event_count_active = event_base_get_max_events(base,
14802b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ACTIVE, 0);
14812b15cb3dSCy Schubert 	event_count_virtual = event_base_get_max_events(base,
14822b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_VIRTUAL, 0);
14832b15cb3dSCy Schubert 	event_count_added = event_base_get_max_events(base,
14842b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ADDED, 0);
14852b15cb3dSCy Schubert 	event_count_active_virtual = event_base_get_max_events(base,
14862b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ACTIVE | EVENT_BASE_COUNT_VIRTUAL, 0);
14872b15cb3dSCy Schubert 	event_count_active_added = event_base_get_max_events(base,
14882b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ACTIVE | EVENT_BASE_COUNT_ADDED, 0);
14892b15cb3dSCy Schubert 	event_count_virtual_added = event_base_get_max_events(base,
14902b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_VIRTUAL | EVENT_BASE_COUNT_ADDED, 0);
14912b15cb3dSCy Schubert 	event_count_active_added_virtual = event_base_get_max_events(base,
14922b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ACTIVE |
14932b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ADDED |
14942b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_VIRTUAL, 0);
14952b15cb3dSCy Schubert 
14962b15cb3dSCy Schubert 	tt_int_op(event_count_active, ==, 0);
14972b15cb3dSCy Schubert 	tt_int_op(event_count_virtual, ==, 0);
14982b15cb3dSCy Schubert 	/* libevent itself adds a timeout event, so the event_count is 4 here */
14992b15cb3dSCy Schubert 	tt_int_op(event_count_added, ==, 4);
15002b15cb3dSCy Schubert 	tt_int_op(event_count_active_virtual, ==, 0);
15012b15cb3dSCy Schubert 	tt_int_op(event_count_active_added, ==, 4);
15022b15cb3dSCy Schubert 	tt_int_op(event_count_virtual_added, ==, 4);
15032b15cb3dSCy Schubert 	tt_int_op(event_count_active_added_virtual, ==, 4);
15042b15cb3dSCy Schubert 
15052b15cb3dSCy Schubert 	event_active(&ev, EV_READ, 1);
15062b15cb3dSCy Schubert 	event_count_active = event_base_get_max_events(base,
15072b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ACTIVE, 0);
15082b15cb3dSCy Schubert 	event_count_virtual = event_base_get_max_events(base,
15092b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_VIRTUAL, 0);
15102b15cb3dSCy Schubert 	event_count_added = event_base_get_max_events(base,
15112b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ADDED, 0);
15122b15cb3dSCy Schubert 	event_count_active_virtual = event_base_get_max_events(base,
15132b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ACTIVE | EVENT_BASE_COUNT_VIRTUAL, 0);
15142b15cb3dSCy Schubert 	event_count_active_added = event_base_get_max_events(base,
15152b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ACTIVE | EVENT_BASE_COUNT_ADDED, 0);
15162b15cb3dSCy Schubert 	event_count_virtual_added = event_base_get_max_events(base,
15172b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_VIRTUAL | EVENT_BASE_COUNT_ADDED, 0);
15182b15cb3dSCy Schubert 	event_count_active_added_virtual = event_base_get_max_events(base,
15192b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ACTIVE |
15202b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ADDED |
15212b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_VIRTUAL, 0);
15222b15cb3dSCy Schubert 
15232b15cb3dSCy Schubert 	tt_int_op(event_count_active, ==, 1);
15242b15cb3dSCy Schubert 	tt_int_op(event_count_virtual, ==, 0);
15252b15cb3dSCy Schubert 	tt_int_op(event_count_added, ==, 4);
15262b15cb3dSCy Schubert 	tt_int_op(event_count_active_virtual, ==, 1);
15272b15cb3dSCy Schubert 	tt_int_op(event_count_active_added, ==, 5);
15282b15cb3dSCy Schubert 	tt_int_op(event_count_virtual_added, ==, 4);
15292b15cb3dSCy Schubert 	tt_int_op(event_count_active_added_virtual, ==, 5);
15302b15cb3dSCy Schubert 
15312b15cb3dSCy Schubert 	event_base_loop(base, 0);
15322b15cb3dSCy Schubert 	event_count_active = event_base_get_max_events(base,
15332b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ACTIVE, 1);
15342b15cb3dSCy Schubert 	event_count_virtual = event_base_get_max_events(base,
15352b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_VIRTUAL, 1);
15362b15cb3dSCy Schubert 	event_count_added = event_base_get_max_events(base,
15372b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ADDED, 1);
15382b15cb3dSCy Schubert 	event_count_active_virtual = event_base_get_max_events(base,
15392b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ACTIVE | EVENT_BASE_COUNT_VIRTUAL, 0);
15402b15cb3dSCy Schubert 	event_count_active_added = event_base_get_max_events(base,
15412b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ACTIVE | EVENT_BASE_COUNT_ADDED, 0);
15422b15cb3dSCy Schubert 	event_count_virtual_added = event_base_get_max_events(base,
15432b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_VIRTUAL | EVENT_BASE_COUNT_ADDED, 0);
15442b15cb3dSCy Schubert 	event_count_active_added_virtual = event_base_get_max_events(base,
15452b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ACTIVE |
15462b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ADDED |
15472b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_VIRTUAL, 1);
15482b15cb3dSCy Schubert 
15492b15cb3dSCy Schubert 	tt_int_op(event_count_active, ==, 1);
15502b15cb3dSCy Schubert 	tt_int_op(event_count_virtual, ==, 0);
15512b15cb3dSCy Schubert 	tt_int_op(event_count_added, ==, 4);
15522b15cb3dSCy Schubert 	tt_int_op(event_count_active_virtual, ==, 0);
15532b15cb3dSCy Schubert 	tt_int_op(event_count_active_added, ==, 0);
15542b15cb3dSCy Schubert 	tt_int_op(event_count_virtual_added, ==, 0);
15552b15cb3dSCy Schubert 	tt_int_op(event_count_active_added_virtual, ==, 0);
15562b15cb3dSCy Schubert 
15572b15cb3dSCy Schubert 	event_count_active = event_base_get_max_events(base,
15582b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ACTIVE, 0);
15592b15cb3dSCy Schubert 	event_count_virtual = event_base_get_max_events(base,
15602b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_VIRTUAL, 0);
15612b15cb3dSCy Schubert 	event_count_added = event_base_get_max_events(base,
15622b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ADDED, 0);
15632b15cb3dSCy Schubert 	tt_int_op(event_count_active, ==, 0);
15642b15cb3dSCy Schubert 	tt_int_op(event_count_virtual, ==, 0);
15652b15cb3dSCy Schubert 	tt_int_op(event_count_added, ==, 0);
15662b15cb3dSCy Schubert 
15672b15cb3dSCy Schubert 	event_base_add_virtual_(base);
15682b15cb3dSCy Schubert 	event_count_active = event_base_get_max_events(base,
15692b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ACTIVE, 0);
15702b15cb3dSCy Schubert 	event_count_virtual = event_base_get_max_events(base,
15712b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_VIRTUAL, 0);
15722b15cb3dSCy Schubert 	event_count_added = event_base_get_max_events(base,
15732b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ADDED, 0);
15742b15cb3dSCy Schubert 	event_count_active_virtual = event_base_get_max_events(base,
15752b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ACTIVE | EVENT_BASE_COUNT_VIRTUAL, 0);
15762b15cb3dSCy Schubert 	event_count_active_added = event_base_get_max_events(base,
15772b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ACTIVE | EVENT_BASE_COUNT_ADDED, 0);
15782b15cb3dSCy Schubert 	event_count_virtual_added = event_base_get_max_events(base,
15792b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_VIRTUAL | EVENT_BASE_COUNT_ADDED, 0);
15802b15cb3dSCy Schubert 	event_count_active_added_virtual = event_base_get_max_events(base,
15812b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ACTIVE |
15822b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_ADDED |
15832b15cb3dSCy Schubert 	    EVENT_BASE_COUNT_VIRTUAL, 0);
15842b15cb3dSCy Schubert 
15852b15cb3dSCy Schubert 	tt_int_op(event_count_active, ==, 0);
15862b15cb3dSCy Schubert 	tt_int_op(event_count_virtual, ==, 1);
15872b15cb3dSCy Schubert 	tt_int_op(event_count_added, ==, 0);
15882b15cb3dSCy Schubert 	tt_int_op(event_count_active_virtual, ==, 1);
15892b15cb3dSCy Schubert 	tt_int_op(event_count_active_added, ==, 0);
15902b15cb3dSCy Schubert 	tt_int_op(event_count_virtual_added, ==, 1);
15912b15cb3dSCy Schubert 	tt_int_op(event_count_active_added_virtual, ==, 1);
15922b15cb3dSCy Schubert 
15932b15cb3dSCy Schubert end:
15942b15cb3dSCy Schubert        ;
15952b15cb3dSCy Schubert }
15962b15cb3dSCy Schubert 
15972b15cb3dSCy Schubert static void
15982b15cb3dSCy Schubert test_bad_assign(void *ptr)
15992b15cb3dSCy Schubert {
16002b15cb3dSCy Schubert 	struct event ev;
16012b15cb3dSCy Schubert 	int r;
16022b15cb3dSCy Schubert 	/* READ|SIGNAL is not allowed */
16032b15cb3dSCy Schubert 	r = event_assign(&ev, NULL, -1, EV_SIGNAL|EV_READ, dummy_read_cb, NULL);
16042b15cb3dSCy Schubert 	tt_int_op(r,==,-1);
16052b15cb3dSCy Schubert 
16062b15cb3dSCy Schubert end:
16072b15cb3dSCy Schubert 	;
16082b15cb3dSCy Schubert }
16092b15cb3dSCy Schubert 
16102b15cb3dSCy Schubert static int reentrant_cb_run = 0;
16112b15cb3dSCy Schubert 
16122b15cb3dSCy Schubert static void
16132b15cb3dSCy Schubert bad_reentrant_run_loop_cb(evutil_socket_t fd, short what, void *ptr)
16142b15cb3dSCy Schubert {
16152b15cb3dSCy Schubert 	struct event_base *base = ptr;
16162b15cb3dSCy Schubert 	int r;
16172b15cb3dSCy Schubert 	reentrant_cb_run = 1;
16182b15cb3dSCy Schubert 	/* This reentrant call to event_base_loop should be detected and
16192b15cb3dSCy Schubert 	 * should fail */
16202b15cb3dSCy Schubert 	r = event_base_loop(base, 0);
16212b15cb3dSCy Schubert 	tt_int_op(r, ==, -1);
16222b15cb3dSCy Schubert end:
16232b15cb3dSCy Schubert 	;
16242b15cb3dSCy Schubert }
16252b15cb3dSCy Schubert 
16262b15cb3dSCy Schubert static void
16272b15cb3dSCy Schubert test_bad_reentrant(void *ptr)
16282b15cb3dSCy Schubert {
16292b15cb3dSCy Schubert 	struct basic_test_data *data = ptr;
16302b15cb3dSCy Schubert 	struct event_base *base = data->base;
16312b15cb3dSCy Schubert 	struct event ev;
16322b15cb3dSCy Schubert 	int r;
16332b15cb3dSCy Schubert 	event_assign(&ev, base, -1,
16342b15cb3dSCy Schubert 	    0, bad_reentrant_run_loop_cb, base);
16352b15cb3dSCy Schubert 
16362b15cb3dSCy Schubert 	event_active(&ev, EV_WRITE, 1);
16372b15cb3dSCy Schubert 	r = event_base_loop(base, 0);
16382b15cb3dSCy Schubert 	tt_int_op(r, ==, 1);
16392b15cb3dSCy Schubert 	tt_int_op(reentrant_cb_run, ==, 1);
16402b15cb3dSCy Schubert end:
16412b15cb3dSCy Schubert 	;
16422b15cb3dSCy Schubert }
16432b15cb3dSCy Schubert 
16442b15cb3dSCy Schubert static int n_write_a_byte_cb=0;
16452b15cb3dSCy Schubert static int n_read_and_drain_cb=0;
16462b15cb3dSCy Schubert static int n_activate_other_event_cb=0;
16472b15cb3dSCy Schubert static void
16482b15cb3dSCy Schubert write_a_byte_cb(evutil_socket_t fd, short what, void *arg)
16492b15cb3dSCy Schubert {
16502b15cb3dSCy Schubert 	char buf[] = "x";
16512b15cb3dSCy Schubert 	if (write(fd, buf, 1) == 1)
16522b15cb3dSCy Schubert 		++n_write_a_byte_cb;
16532b15cb3dSCy Schubert }
16542b15cb3dSCy Schubert static void
16552b15cb3dSCy Schubert read_and_drain_cb(evutil_socket_t fd, short what, void *arg)
16562b15cb3dSCy Schubert {
16572b15cb3dSCy Schubert 	char buf[128];
16582b15cb3dSCy Schubert 	int n;
16592b15cb3dSCy Schubert 	++n_read_and_drain_cb;
16602b15cb3dSCy Schubert 	while ((n = read(fd, buf, sizeof(buf))) > 0)
16612b15cb3dSCy Schubert 		;
16622b15cb3dSCy Schubert }
16632b15cb3dSCy Schubert 
16642b15cb3dSCy Schubert static void
16652b15cb3dSCy Schubert activate_other_event_cb(evutil_socket_t fd, short what, void *other_)
16662b15cb3dSCy Schubert {
16672b15cb3dSCy Schubert 	struct event *ev_activate = other_;
16682b15cb3dSCy Schubert 	++n_activate_other_event_cb;
16692b15cb3dSCy Schubert 	event_active_later_(ev_activate, EV_READ);
16702b15cb3dSCy Schubert }
16712b15cb3dSCy Schubert 
16722b15cb3dSCy Schubert static void
16732b15cb3dSCy Schubert test_active_later(void *ptr)
16742b15cb3dSCy Schubert {
16752b15cb3dSCy Schubert 	struct basic_test_data *data = ptr;
1676*a25439b6SCy Schubert 	struct event *ev1 = NULL, *ev2 = NULL;
16772b15cb3dSCy Schubert 	struct event ev3, ev4;
16782b15cb3dSCy Schubert 	struct timeval qsec = {0, 100000};
16792b15cb3dSCy Schubert 	ev1 = event_new(data->base, data->pair[0], EV_READ|EV_PERSIST, read_and_drain_cb, NULL);
16802b15cb3dSCy Schubert 	ev2 = event_new(data->base, data->pair[1], EV_WRITE|EV_PERSIST, write_a_byte_cb, NULL);
16812b15cb3dSCy Schubert 	event_assign(&ev3, data->base, -1, 0, activate_other_event_cb, &ev4);
16822b15cb3dSCy Schubert 	event_assign(&ev4, data->base, -1, 0, activate_other_event_cb, &ev3);
16832b15cb3dSCy Schubert 	event_add(ev1, NULL);
16842b15cb3dSCy Schubert 	event_add(ev2, NULL);
16852b15cb3dSCy Schubert 	event_active_later_(&ev3, EV_READ);
16862b15cb3dSCy Schubert 
16872b15cb3dSCy Schubert 	event_base_loopexit(data->base, &qsec);
16882b15cb3dSCy Schubert 
16892b15cb3dSCy Schubert 	event_base_loop(data->base, 0);
16902b15cb3dSCy Schubert 
16912b15cb3dSCy Schubert 	TT_BLATHER(("%d write calls, %d read calls, %d activate-other calls.",
16922b15cb3dSCy Schubert 		n_write_a_byte_cb, n_read_and_drain_cb, n_activate_other_event_cb));
16932b15cb3dSCy Schubert 	event_del(&ev3);
16942b15cb3dSCy Schubert 	event_del(&ev4);
16952b15cb3dSCy Schubert 
16962b15cb3dSCy Schubert 	tt_int_op(n_write_a_byte_cb, ==, n_activate_other_event_cb);
16972b15cb3dSCy Schubert 	tt_int_op(n_write_a_byte_cb, >, 100);
16982b15cb3dSCy Schubert 	tt_int_op(n_read_and_drain_cb, >, 100);
16992b15cb3dSCy Schubert 	tt_int_op(n_activate_other_event_cb, >, 100);
17002b15cb3dSCy Schubert 
17012b15cb3dSCy Schubert 	event_active_later_(&ev4, EV_READ);
17022b15cb3dSCy Schubert 	event_active(&ev4, EV_READ, 1); /* This should make the event
17032b15cb3dSCy Schubert 					   active immediately. */
17042b15cb3dSCy Schubert 	tt_assert((ev4.ev_flags & EVLIST_ACTIVE) != 0);
17052b15cb3dSCy Schubert 	tt_assert((ev4.ev_flags & EVLIST_ACTIVE_LATER) == 0);
17062b15cb3dSCy Schubert 
17072b15cb3dSCy Schubert 	/* Now leave this one around, so that event_free sees it and removes
17082b15cb3dSCy Schubert 	 * it. */
17092b15cb3dSCy Schubert 	event_active_later_(&ev3, EV_READ);
17102b15cb3dSCy Schubert 	event_base_assert_ok_(data->base);
1711*a25439b6SCy Schubert 
1712*a25439b6SCy Schubert end:
1713*a25439b6SCy Schubert 	if (ev1)
1714*a25439b6SCy Schubert 		event_free(ev1);
1715*a25439b6SCy Schubert 	if (ev2)
1716*a25439b6SCy Schubert 		event_free(ev2);
1717*a25439b6SCy Schubert 
17182b15cb3dSCy Schubert 	event_base_free(data->base);
17192b15cb3dSCy Schubert 	data->base = NULL;
17202b15cb3dSCy Schubert }
17212b15cb3dSCy Schubert 
17222b15cb3dSCy Schubert 
17232b15cb3dSCy Schubert static void incr_arg_cb(evutil_socket_t fd, short what, void *arg)
17242b15cb3dSCy Schubert {
17252b15cb3dSCy Schubert 	int *intptr = arg;
17262b15cb3dSCy Schubert 	(void) fd; (void) what;
17272b15cb3dSCy Schubert 	++*intptr;
17282b15cb3dSCy Schubert }
17292b15cb3dSCy Schubert static void remove_timers_cb(evutil_socket_t fd, short what, void *arg)
17302b15cb3dSCy Schubert {
17312b15cb3dSCy Schubert 	struct event **ep = arg;
17322b15cb3dSCy Schubert 	(void) fd; (void) what;
17332b15cb3dSCy Schubert 	event_remove_timer(ep[0]);
17342b15cb3dSCy Schubert 	event_remove_timer(ep[1]);
17352b15cb3dSCy Schubert }
17362b15cb3dSCy Schubert static void send_a_byte_cb(evutil_socket_t fd, short what, void *arg)
17372b15cb3dSCy Schubert {
17382b15cb3dSCy Schubert 	evutil_socket_t *sockp = arg;
17392b15cb3dSCy Schubert 	(void) fd; (void) what;
17402b15cb3dSCy Schubert 	(void) write(*sockp, "A", 1);
17412b15cb3dSCy Schubert }
17422b15cb3dSCy Schubert struct read_not_timeout_param
17432b15cb3dSCy Schubert {
17442b15cb3dSCy Schubert 	struct event **ev;
17452b15cb3dSCy Schubert 	int events;
17462b15cb3dSCy Schubert 	int count;
17472b15cb3dSCy Schubert };
17482b15cb3dSCy Schubert static void read_not_timeout_cb(evutil_socket_t fd, short what, void *arg)
17492b15cb3dSCy Schubert {
17502b15cb3dSCy Schubert 	struct read_not_timeout_param *rntp = arg;
17512b15cb3dSCy Schubert 	char c;
17522b15cb3dSCy Schubert 	ev_ssize_t n;
17532b15cb3dSCy Schubert 	(void) fd; (void) what;
17542b15cb3dSCy Schubert 	n = read(fd, &c, 1);
17552b15cb3dSCy Schubert 	tt_int_op(n, ==, 1);
17562b15cb3dSCy Schubert 	rntp->events |= what;
17572b15cb3dSCy Schubert 	++rntp->count;
17582b15cb3dSCy Schubert 	if(2 == rntp->count) event_del(rntp->ev[0]);
17592b15cb3dSCy Schubert end:
17602b15cb3dSCy Schubert 	;
17612b15cb3dSCy Schubert }
17622b15cb3dSCy Schubert 
17632b15cb3dSCy Schubert static void
17642b15cb3dSCy Schubert test_event_remove_timeout(void *ptr)
17652b15cb3dSCy Schubert {
17662b15cb3dSCy Schubert 	struct basic_test_data *data = ptr;
17672b15cb3dSCy Schubert 	struct event_base *base = data->base;
17682b15cb3dSCy Schubert 	struct event *ev[5];
17692b15cb3dSCy Schubert 	int ev1_fired=0;
17702b15cb3dSCy Schubert 	struct timeval ms25 = { 0, 25*1000 },
17712b15cb3dSCy Schubert 		ms40 = { 0, 40*1000 },
17722b15cb3dSCy Schubert 		ms75 = { 0, 75*1000 },
17732b15cb3dSCy Schubert 		ms125 = { 0, 125*1000 };
17742b15cb3dSCy Schubert 	struct read_not_timeout_param rntp = { ev, 0, 0 };
17752b15cb3dSCy Schubert 
17762b15cb3dSCy Schubert 	event_base_assert_ok_(base);
17772b15cb3dSCy Schubert 
17782b15cb3dSCy Schubert 	ev[0] = event_new(base, data->pair[0], EV_READ|EV_PERSIST,
17792b15cb3dSCy Schubert 	    read_not_timeout_cb, &rntp);
17802b15cb3dSCy Schubert 	ev[1] = evtimer_new(base, incr_arg_cb, &ev1_fired);
17812b15cb3dSCy Schubert 	ev[2] = evtimer_new(base, remove_timers_cb, ev);
17822b15cb3dSCy Schubert 	ev[3] = evtimer_new(base, send_a_byte_cb, &data->pair[1]);
17832b15cb3dSCy Schubert 	ev[4] = evtimer_new(base, send_a_byte_cb, &data->pair[1]);
17842b15cb3dSCy Schubert 	tt_assert(base);
17852b15cb3dSCy Schubert 	event_add(ev[2], &ms25); /* remove timers */
17862b15cb3dSCy Schubert 	event_add(ev[4], &ms40); /* write to test if timer re-activates */
17872b15cb3dSCy Schubert 	event_add(ev[0], &ms75); /* read */
17882b15cb3dSCy Schubert 	event_add(ev[1], &ms75); /* timer */
17892b15cb3dSCy Schubert 	event_add(ev[3], &ms125); /* timeout. */
17902b15cb3dSCy Schubert 	event_base_assert_ok_(base);
17912b15cb3dSCy Schubert 
17922b15cb3dSCy Schubert 	event_base_dispatch(base);
17932b15cb3dSCy Schubert 
17942b15cb3dSCy Schubert 	tt_int_op(ev1_fired, ==, 0);
17952b15cb3dSCy Schubert 	tt_int_op(rntp.events, ==, EV_READ);
17962b15cb3dSCy Schubert 
17972b15cb3dSCy Schubert 	event_base_assert_ok_(base);
17982b15cb3dSCy Schubert end:
17992b15cb3dSCy Schubert 	event_free(ev[0]);
18002b15cb3dSCy Schubert 	event_free(ev[1]);
18012b15cb3dSCy Schubert 	event_free(ev[2]);
18022b15cb3dSCy Schubert 	event_free(ev[3]);
18032b15cb3dSCy Schubert 	event_free(ev[4]);
18042b15cb3dSCy Schubert }
18052b15cb3dSCy Schubert 
18062b15cb3dSCy Schubert static void
18072b15cb3dSCy Schubert test_event_base_new(void *ptr)
18082b15cb3dSCy Schubert {
18092b15cb3dSCy Schubert 	struct basic_test_data *data = ptr;
18102b15cb3dSCy Schubert 	struct event_base *base = 0;
18112b15cb3dSCy Schubert 	struct event ev1;
18122b15cb3dSCy Schubert 	struct basic_cb_args args;
18132b15cb3dSCy Schubert 
18142b15cb3dSCy Schubert 	int towrite = (int)strlen(TEST1)+1;
18152b15cb3dSCy Schubert 	int len = write(data->pair[0], TEST1, towrite);
18162b15cb3dSCy Schubert 
18172b15cb3dSCy Schubert 	if (len < 0)
18182b15cb3dSCy Schubert 		tt_abort_perror("initial write");
18192b15cb3dSCy Schubert 	else if (len != towrite)
18202b15cb3dSCy Schubert 		tt_abort_printf(("initial write fell short (%d of %d bytes)",
18212b15cb3dSCy Schubert 				 len, towrite));
18222b15cb3dSCy Schubert 
18232b15cb3dSCy Schubert 	if (shutdown(data->pair[0], SHUT_WR))
18242b15cb3dSCy Schubert 		tt_abort_perror("initial write shutdown");
18252b15cb3dSCy Schubert 
18262b15cb3dSCy Schubert 	base = event_base_new();
18272b15cb3dSCy Schubert 	if (!base)
18282b15cb3dSCy Schubert 		tt_abort_msg("failed to create event base");
18292b15cb3dSCy Schubert 
18302b15cb3dSCy Schubert 	args.eb = base;
18312b15cb3dSCy Schubert 	args.ev = &ev1;
18322b15cb3dSCy Schubert 	args.callcount = 0;
18332b15cb3dSCy Schubert 	event_assign(&ev1, base, data->pair[1],
18342b15cb3dSCy Schubert 		     EV_READ|EV_PERSIST, basic_read_cb, &args);
18352b15cb3dSCy Schubert 
18362b15cb3dSCy Schubert 	if (event_add(&ev1, NULL))
18372b15cb3dSCy Schubert 		tt_abort_perror("initial event_add");
18382b15cb3dSCy Schubert 
18392b15cb3dSCy Schubert 	if (event_base_loop(base, 0))
18402b15cb3dSCy Schubert 		tt_abort_msg("unsuccessful exit from event loop");
18412b15cb3dSCy Schubert 
18422b15cb3dSCy Schubert end:
18432b15cb3dSCy Schubert 	if (base)
18442b15cb3dSCy Schubert 		event_base_free(base);
18452b15cb3dSCy Schubert }
18462b15cb3dSCy Schubert 
18472b15cb3dSCy Schubert static void
18482b15cb3dSCy Schubert test_loopexit(void)
18492b15cb3dSCy Schubert {
18502b15cb3dSCy Schubert 	struct timeval tv, tv_start, tv_end;
18512b15cb3dSCy Schubert 	struct event ev;
18522b15cb3dSCy Schubert 
18532b15cb3dSCy Schubert 	setup_test("Loop exit: ");
18542b15cb3dSCy Schubert 
18552b15cb3dSCy Schubert 	tv.tv_usec = 0;
18562b15cb3dSCy Schubert 	tv.tv_sec = 60*60*24;
18572b15cb3dSCy Schubert 	evtimer_set(&ev, timeout_cb, NULL);
18582b15cb3dSCy Schubert 	evtimer_add(&ev, &tv);
18592b15cb3dSCy Schubert 
18602b15cb3dSCy Schubert 	tv.tv_usec = 300*1000;
18612b15cb3dSCy Schubert 	tv.tv_sec = 0;
18622b15cb3dSCy Schubert 	event_loopexit(&tv);
18632b15cb3dSCy Schubert 
18642b15cb3dSCy Schubert 	evutil_gettimeofday(&tv_start, NULL);
18652b15cb3dSCy Schubert 	event_dispatch();
18662b15cb3dSCy Schubert 	evutil_gettimeofday(&tv_end, NULL);
18672b15cb3dSCy Schubert 
18682b15cb3dSCy Schubert 	evtimer_del(&ev);
18692b15cb3dSCy Schubert 
18702b15cb3dSCy Schubert 	tt_assert(event_base_got_exit(global_base));
18712b15cb3dSCy Schubert 	tt_assert(!event_base_got_break(global_base));
18722b15cb3dSCy Schubert 
18732b15cb3dSCy Schubert 	test_timeval_diff_eq(&tv_start, &tv_end, 300);
18742b15cb3dSCy Schubert 
18752b15cb3dSCy Schubert 	test_ok = 1;
18762b15cb3dSCy Schubert end:
18772b15cb3dSCy Schubert 	cleanup_test();
18782b15cb3dSCy Schubert }
18792b15cb3dSCy Schubert 
18802b15cb3dSCy Schubert static void
18812b15cb3dSCy Schubert test_loopexit_multiple(void)
18822b15cb3dSCy Schubert {
18832b15cb3dSCy Schubert 	struct timeval tv, tv_start, tv_end;
18842b15cb3dSCy Schubert 	struct event_base *base;
18852b15cb3dSCy Schubert 
18862b15cb3dSCy Schubert 	setup_test("Loop Multiple exit: ");
18872b15cb3dSCy Schubert 
18882b15cb3dSCy Schubert 	base = event_base_new();
18892b15cb3dSCy Schubert 
18902b15cb3dSCy Schubert 	tv.tv_usec = 200*1000;
18912b15cb3dSCy Schubert 	tv.tv_sec = 0;
18922b15cb3dSCy Schubert 	event_base_loopexit(base, &tv);
18932b15cb3dSCy Schubert 
18942b15cb3dSCy Schubert 	tv.tv_usec = 0;
18952b15cb3dSCy Schubert 	tv.tv_sec = 3;
18962b15cb3dSCy Schubert 	event_base_loopexit(base, &tv);
18972b15cb3dSCy Schubert 
18982b15cb3dSCy Schubert 	evutil_gettimeofday(&tv_start, NULL);
18992b15cb3dSCy Schubert 	event_base_dispatch(base);
19002b15cb3dSCy Schubert 	evutil_gettimeofday(&tv_end, NULL);
19012b15cb3dSCy Schubert 
19022b15cb3dSCy Schubert 	tt_assert(event_base_got_exit(base));
19032b15cb3dSCy Schubert 	tt_assert(!event_base_got_break(base));
19042b15cb3dSCy Schubert 
19052b15cb3dSCy Schubert 	event_base_free(base);
19062b15cb3dSCy Schubert 
19072b15cb3dSCy Schubert 	test_timeval_diff_eq(&tv_start, &tv_end, 200);
19082b15cb3dSCy Schubert 
19092b15cb3dSCy Schubert 	test_ok = 1;
19102b15cb3dSCy Schubert 
19112b15cb3dSCy Schubert end:
19122b15cb3dSCy Schubert 	cleanup_test();
19132b15cb3dSCy Schubert }
19142b15cb3dSCy Schubert 
19152b15cb3dSCy Schubert static void
19162b15cb3dSCy Schubert break_cb(evutil_socket_t fd, short events, void *arg)
19172b15cb3dSCy Schubert {
19182b15cb3dSCy Schubert 	test_ok = 1;
19192b15cb3dSCy Schubert 	event_loopbreak();
19202b15cb3dSCy Schubert }
19212b15cb3dSCy Schubert 
19222b15cb3dSCy Schubert static void
19232b15cb3dSCy Schubert fail_cb(evutil_socket_t fd, short events, void *arg)
19242b15cb3dSCy Schubert {
19252b15cb3dSCy Schubert 	test_ok = 0;
19262b15cb3dSCy Schubert }
19272b15cb3dSCy Schubert 
19282b15cb3dSCy Schubert static void
19292b15cb3dSCy Schubert test_loopbreak(void)
19302b15cb3dSCy Schubert {
19312b15cb3dSCy Schubert 	struct event ev1, ev2;
19322b15cb3dSCy Schubert 	struct timeval tv;
19332b15cb3dSCy Schubert 
19342b15cb3dSCy Schubert 	setup_test("Loop break: ");
19352b15cb3dSCy Schubert 
19362b15cb3dSCy Schubert 	tv.tv_sec = 0;
19372b15cb3dSCy Schubert 	tv.tv_usec = 0;
19382b15cb3dSCy Schubert 	evtimer_set(&ev1, break_cb, NULL);
19392b15cb3dSCy Schubert 	evtimer_add(&ev1, &tv);
19402b15cb3dSCy Schubert 	evtimer_set(&ev2, fail_cb, NULL);
19412b15cb3dSCy Schubert 	evtimer_add(&ev2, &tv);
19422b15cb3dSCy Schubert 
19432b15cb3dSCy Schubert 	event_dispatch();
19442b15cb3dSCy Schubert 
19452b15cb3dSCy Schubert 	tt_assert(!event_base_got_exit(global_base));
19462b15cb3dSCy Schubert 	tt_assert(event_base_got_break(global_base));
19472b15cb3dSCy Schubert 
19482b15cb3dSCy Schubert 	evtimer_del(&ev1);
19492b15cb3dSCy Schubert 	evtimer_del(&ev2);
19502b15cb3dSCy Schubert 
19512b15cb3dSCy Schubert end:
19522b15cb3dSCy Schubert 	cleanup_test();
19532b15cb3dSCy Schubert }
19542b15cb3dSCy Schubert 
19552b15cb3dSCy Schubert static struct event *readd_test_event_last_added = NULL;
19562b15cb3dSCy Schubert static void
19572b15cb3dSCy Schubert re_add_read_cb(evutil_socket_t fd, short event, void *arg)
19582b15cb3dSCy Schubert {
19592b15cb3dSCy Schubert 	char buf[256];
19602b15cb3dSCy Schubert 	struct event *ev_other = arg;
19612b15cb3dSCy Schubert 	ev_ssize_t n_read;
19622b15cb3dSCy Schubert 
19632b15cb3dSCy Schubert 	readd_test_event_last_added = ev_other;
19642b15cb3dSCy Schubert 
19652b15cb3dSCy Schubert 	n_read = read(fd, buf, sizeof(buf));
19662b15cb3dSCy Schubert 
19672b15cb3dSCy Schubert 	if (n_read < 0) {
19682b15cb3dSCy Schubert 		tt_fail_perror("read");
19692b15cb3dSCy Schubert 		event_base_loopbreak(event_get_base(ev_other));
19702b15cb3dSCy Schubert 		return;
19712b15cb3dSCy Schubert 	} else {
19722b15cb3dSCy Schubert 		event_add(ev_other, NULL);
19732b15cb3dSCy Schubert 		++test_ok;
19742b15cb3dSCy Schubert 	}
19752b15cb3dSCy Schubert }
19762b15cb3dSCy Schubert 
19772b15cb3dSCy Schubert static void
19782b15cb3dSCy Schubert test_nonpersist_readd(void)
19792b15cb3dSCy Schubert {
19802b15cb3dSCy Schubert 	struct event ev1, ev2;
19812b15cb3dSCy Schubert 
19822b15cb3dSCy Schubert 	setup_test("Re-add nonpersistent events: ");
19832b15cb3dSCy Schubert 	event_set(&ev1, pair[0], EV_READ, re_add_read_cb, &ev2);
19842b15cb3dSCy Schubert 	event_set(&ev2, pair[1], EV_READ, re_add_read_cb, &ev1);
19852b15cb3dSCy Schubert 
19862b15cb3dSCy Schubert 	if (write(pair[0], "Hello", 5) < 0) {
19872b15cb3dSCy Schubert 		tt_fail_perror("write(pair[0])");
19882b15cb3dSCy Schubert 	}
19892b15cb3dSCy Schubert 
19902b15cb3dSCy Schubert 	if (write(pair[1], "Hello", 5) < 0) {
19912b15cb3dSCy Schubert 		tt_fail_perror("write(pair[1])\n");
19922b15cb3dSCy Schubert 	}
19932b15cb3dSCy Schubert 
19942b15cb3dSCy Schubert 	if (event_add(&ev1, NULL) == -1 ||
19952b15cb3dSCy Schubert 	    event_add(&ev2, NULL) == -1) {
19962b15cb3dSCy Schubert 		test_ok = 0;
19972b15cb3dSCy Schubert 	}
19982b15cb3dSCy Schubert 	if (test_ok != 0)
19992b15cb3dSCy Schubert 		exit(1);
20002b15cb3dSCy Schubert 	event_loop(EVLOOP_ONCE);
20012b15cb3dSCy Schubert 	if (test_ok != 2)
20022b15cb3dSCy Schubert 		exit(1);
20032b15cb3dSCy Schubert 	/* At this point, we executed both callbacks.  Whichever one got
20042b15cb3dSCy Schubert 	 * called first added the second, but the second then immediately got
20052b15cb3dSCy Schubert 	 * deleted before its callback was called.  At this point, though, it
20062b15cb3dSCy Schubert 	 * re-added the first.
20072b15cb3dSCy Schubert 	 */
20082b15cb3dSCy Schubert 	if (!readd_test_event_last_added) {
20092b15cb3dSCy Schubert 		test_ok = 0;
20102b15cb3dSCy Schubert 	} else if (readd_test_event_last_added == &ev1) {
20112b15cb3dSCy Schubert 		if (!event_pending(&ev1, EV_READ, NULL) ||
20122b15cb3dSCy Schubert 		    event_pending(&ev2, EV_READ, NULL))
20132b15cb3dSCy Schubert 			test_ok = 0;
20142b15cb3dSCy Schubert 	} else {
20152b15cb3dSCy Schubert 		if (event_pending(&ev1, EV_READ, NULL) ||
20162b15cb3dSCy Schubert 		    !event_pending(&ev2, EV_READ, NULL))
20172b15cb3dSCy Schubert 			test_ok = 0;
20182b15cb3dSCy Schubert 	}
20192b15cb3dSCy Schubert 
20202b15cb3dSCy Schubert 	event_del(&ev1);
20212b15cb3dSCy Schubert 	event_del(&ev2);
20222b15cb3dSCy Schubert 
20232b15cb3dSCy Schubert 	cleanup_test();
20242b15cb3dSCy Schubert }
20252b15cb3dSCy Schubert 
20262b15cb3dSCy Schubert struct test_pri_event {
20272b15cb3dSCy Schubert 	struct event ev;
20282b15cb3dSCy Schubert 	int count;
20292b15cb3dSCy Schubert };
20302b15cb3dSCy Schubert 
20312b15cb3dSCy Schubert static void
20322b15cb3dSCy Schubert test_priorities_cb(evutil_socket_t fd, short what, void *arg)
20332b15cb3dSCy Schubert {
20342b15cb3dSCy Schubert 	struct test_pri_event *pri = arg;
20352b15cb3dSCy Schubert 	struct timeval tv;
20362b15cb3dSCy Schubert 
20372b15cb3dSCy Schubert 	if (pri->count == 3) {
20382b15cb3dSCy Schubert 		event_loopexit(NULL);
20392b15cb3dSCy Schubert 		return;
20402b15cb3dSCy Schubert 	}
20412b15cb3dSCy Schubert 
20422b15cb3dSCy Schubert 	pri->count++;
20432b15cb3dSCy Schubert 
20442b15cb3dSCy Schubert 	evutil_timerclear(&tv);
20452b15cb3dSCy Schubert 	event_add(&pri->ev, &tv);
20462b15cb3dSCy Schubert }
20472b15cb3dSCy Schubert 
20482b15cb3dSCy Schubert static void
20492b15cb3dSCy Schubert test_priorities_impl(int npriorities)
20502b15cb3dSCy Schubert {
20512b15cb3dSCy Schubert 	struct test_pri_event one, two;
20522b15cb3dSCy Schubert 	struct timeval tv;
20532b15cb3dSCy Schubert 
20542b15cb3dSCy Schubert 	TT_BLATHER(("Testing Priorities %d: ", npriorities));
20552b15cb3dSCy Schubert 
20562b15cb3dSCy Schubert 	event_base_priority_init(global_base, npriorities);
20572b15cb3dSCy Schubert 
20582b15cb3dSCy Schubert 	memset(&one, 0, sizeof(one));
20592b15cb3dSCy Schubert 	memset(&two, 0, sizeof(two));
20602b15cb3dSCy Schubert 
20612b15cb3dSCy Schubert 	timeout_set(&one.ev, test_priorities_cb, &one);
20622b15cb3dSCy Schubert 	if (event_priority_set(&one.ev, 0) == -1) {
20632b15cb3dSCy Schubert 		fprintf(stderr, "%s: failed to set priority", __func__);
20642b15cb3dSCy Schubert 		exit(1);
20652b15cb3dSCy Schubert 	}
20662b15cb3dSCy Schubert 
20672b15cb3dSCy Schubert 	timeout_set(&two.ev, test_priorities_cb, &two);
20682b15cb3dSCy Schubert 	if (event_priority_set(&two.ev, npriorities - 1) == -1) {
20692b15cb3dSCy Schubert 		fprintf(stderr, "%s: failed to set priority", __func__);
20702b15cb3dSCy Schubert 		exit(1);
20712b15cb3dSCy Schubert 	}
20722b15cb3dSCy Schubert 
20732b15cb3dSCy Schubert 	evutil_timerclear(&tv);
20742b15cb3dSCy Schubert 
20752b15cb3dSCy Schubert 	if (event_add(&one.ev, &tv) == -1)
20762b15cb3dSCy Schubert 		exit(1);
20772b15cb3dSCy Schubert 	if (event_add(&two.ev, &tv) == -1)
20782b15cb3dSCy Schubert 		exit(1);
20792b15cb3dSCy Schubert 
20802b15cb3dSCy Schubert 	event_dispatch();
20812b15cb3dSCy Schubert 
20822b15cb3dSCy Schubert 	event_del(&one.ev);
20832b15cb3dSCy Schubert 	event_del(&two.ev);
20842b15cb3dSCy Schubert 
20852b15cb3dSCy Schubert 	if (npriorities == 1) {
20862b15cb3dSCy Schubert 		if (one.count == 3 && two.count == 3)
20872b15cb3dSCy Schubert 			test_ok = 1;
20882b15cb3dSCy Schubert 	} else if (npriorities == 2) {
20892b15cb3dSCy Schubert 		/* Two is called once because event_loopexit is priority 1 */
20902b15cb3dSCy Schubert 		if (one.count == 3 && two.count == 1)
20912b15cb3dSCy Schubert 			test_ok = 1;
20922b15cb3dSCy Schubert 	} else {
20932b15cb3dSCy Schubert 		if (one.count == 3 && two.count == 0)
20942b15cb3dSCy Schubert 			test_ok = 1;
20952b15cb3dSCy Schubert 	}
20962b15cb3dSCy Schubert }
20972b15cb3dSCy Schubert 
20982b15cb3dSCy Schubert static void
20992b15cb3dSCy Schubert test_priorities(void)
21002b15cb3dSCy Schubert {
21012b15cb3dSCy Schubert 	test_priorities_impl(1);
21022b15cb3dSCy Schubert 	if (test_ok)
21032b15cb3dSCy Schubert 		test_priorities_impl(2);
21042b15cb3dSCy Schubert 	if (test_ok)
21052b15cb3dSCy Schubert 		test_priorities_impl(3);
21062b15cb3dSCy Schubert }
21072b15cb3dSCy Schubert 
21082b15cb3dSCy Schubert /* priority-active-inversion: activate a higher-priority event, and make sure
21092b15cb3dSCy Schubert  * it keeps us from running a lower-priority event first. */
21102b15cb3dSCy Schubert static int n_pai_calls = 0;
21112b15cb3dSCy Schubert static struct event pai_events[3];
21122b15cb3dSCy Schubert 
21132b15cb3dSCy Schubert static void
21142b15cb3dSCy Schubert prio_active_inversion_cb(evutil_socket_t fd, short what, void *arg)
21152b15cb3dSCy Schubert {
21162b15cb3dSCy Schubert 	int *call_order = arg;
21172b15cb3dSCy Schubert 	*call_order = n_pai_calls++;
21182b15cb3dSCy Schubert 	if (n_pai_calls == 1) {
21192b15cb3dSCy Schubert 		/* This should activate later, even though it shares a
21202b15cb3dSCy Schubert 		   priority with us. */
21212b15cb3dSCy Schubert 		event_active(&pai_events[1], EV_READ, 1);
21222b15cb3dSCy Schubert 		/* This should activate next, since its priority is higher,
21232b15cb3dSCy Schubert 		   even though we activated it second. */
21242b15cb3dSCy Schubert 		event_active(&pai_events[2], EV_TIMEOUT, 1);
21252b15cb3dSCy Schubert 	}
21262b15cb3dSCy Schubert }
21272b15cb3dSCy Schubert 
21282b15cb3dSCy Schubert static void
21292b15cb3dSCy Schubert test_priority_active_inversion(void *data_)
21302b15cb3dSCy Schubert {
21312b15cb3dSCy Schubert 	struct basic_test_data *data = data_;
21322b15cb3dSCy Schubert 	struct event_base *base = data->base;
21332b15cb3dSCy Schubert 	int call_order[3];
21342b15cb3dSCy Schubert 	int i;
21352b15cb3dSCy Schubert 	tt_int_op(event_base_priority_init(base, 8), ==, 0);
21362b15cb3dSCy Schubert 
21372b15cb3dSCy Schubert 	n_pai_calls = 0;
21382b15cb3dSCy Schubert 	memset(call_order, 0, sizeof(call_order));
21392b15cb3dSCy Schubert 
21402b15cb3dSCy Schubert 	for (i=0;i<3;++i) {
21412b15cb3dSCy Schubert 		event_assign(&pai_events[i], data->base, -1, 0,
21422b15cb3dSCy Schubert 		    prio_active_inversion_cb, &call_order[i]);
21432b15cb3dSCy Schubert 	}
21442b15cb3dSCy Schubert 
21452b15cb3dSCy Schubert 	event_priority_set(&pai_events[0], 4);
21462b15cb3dSCy Schubert 	event_priority_set(&pai_events[1], 4);
21472b15cb3dSCy Schubert 	event_priority_set(&pai_events[2], 0);
21482b15cb3dSCy Schubert 
21492b15cb3dSCy Schubert 	event_active(&pai_events[0], EV_WRITE, 1);
21502b15cb3dSCy Schubert 
21512b15cb3dSCy Schubert 	event_base_dispatch(base);
21522b15cb3dSCy Schubert 	tt_int_op(n_pai_calls, ==, 3);
21532b15cb3dSCy Schubert 	tt_int_op(call_order[0], ==, 0);
21542b15cb3dSCy Schubert 	tt_int_op(call_order[1], ==, 2);
21552b15cb3dSCy Schubert 	tt_int_op(call_order[2], ==, 1);
21562b15cb3dSCy Schubert end:
21572b15cb3dSCy Schubert 	;
21582b15cb3dSCy Schubert }
21592b15cb3dSCy Schubert 
21602b15cb3dSCy Schubert 
21612b15cb3dSCy Schubert static void
21622b15cb3dSCy Schubert test_multiple_cb(evutil_socket_t fd, short event, void *arg)
21632b15cb3dSCy Schubert {
21642b15cb3dSCy Schubert 	if (event & EV_READ)
21652b15cb3dSCy Schubert 		test_ok |= 1;
21662b15cb3dSCy Schubert 	else if (event & EV_WRITE)
21672b15cb3dSCy Schubert 		test_ok |= 2;
21682b15cb3dSCy Schubert }
21692b15cb3dSCy Schubert 
21702b15cb3dSCy Schubert static void
21712b15cb3dSCy Schubert test_multiple_events_for_same_fd(void)
21722b15cb3dSCy Schubert {
21732b15cb3dSCy Schubert    struct event e1, e2;
21742b15cb3dSCy Schubert 
21752b15cb3dSCy Schubert    setup_test("Multiple events for same fd: ");
21762b15cb3dSCy Schubert 
21772b15cb3dSCy Schubert    event_set(&e1, pair[0], EV_READ, test_multiple_cb, NULL);
21782b15cb3dSCy Schubert    event_add(&e1, NULL);
21792b15cb3dSCy Schubert    event_set(&e2, pair[0], EV_WRITE, test_multiple_cb, NULL);
21802b15cb3dSCy Schubert    event_add(&e2, NULL);
21812b15cb3dSCy Schubert    event_loop(EVLOOP_ONCE);
21822b15cb3dSCy Schubert    event_del(&e2);
21832b15cb3dSCy Schubert 
21842b15cb3dSCy Schubert    if (write(pair[1], TEST1, strlen(TEST1)+1) < 0) {
21852b15cb3dSCy Schubert 	   tt_fail_perror("write");
21862b15cb3dSCy Schubert    }
21872b15cb3dSCy Schubert 
21882b15cb3dSCy Schubert    event_loop(EVLOOP_ONCE);
21892b15cb3dSCy Schubert    event_del(&e1);
21902b15cb3dSCy Schubert 
21912b15cb3dSCy Schubert    if (test_ok != 3)
21922b15cb3dSCy Schubert 	   test_ok = 0;
21932b15cb3dSCy Schubert 
21942b15cb3dSCy Schubert    cleanup_test();
21952b15cb3dSCy Schubert }
21962b15cb3dSCy Schubert 
21972b15cb3dSCy Schubert int evtag_decode_int(ev_uint32_t *pnumber, struct evbuffer *evbuf);
21982b15cb3dSCy Schubert int evtag_decode_int64(ev_uint64_t *pnumber, struct evbuffer *evbuf);
21992b15cb3dSCy Schubert int evtag_encode_tag(struct evbuffer *evbuf, ev_uint32_t number);
22002b15cb3dSCy Schubert int evtag_decode_tag(ev_uint32_t *pnumber, struct evbuffer *evbuf);
22012b15cb3dSCy Schubert 
22022b15cb3dSCy Schubert static void
22032b15cb3dSCy Schubert read_once_cb(evutil_socket_t fd, short event, void *arg)
22042b15cb3dSCy Schubert {
22052b15cb3dSCy Schubert 	char buf[256];
22062b15cb3dSCy Schubert 	int len;
22072b15cb3dSCy Schubert 
22082b15cb3dSCy Schubert 	len = read(fd, buf, sizeof(buf));
22092b15cb3dSCy Schubert 
22102b15cb3dSCy Schubert 	if (called) {
22112b15cb3dSCy Schubert 		test_ok = 0;
22122b15cb3dSCy Schubert 	} else if (len) {
22132b15cb3dSCy Schubert 		/* Assumes global pair[0] can be used for writing */
22142b15cb3dSCy Schubert 		if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) {
22152b15cb3dSCy Schubert 			tt_fail_perror("write");
22162b15cb3dSCy Schubert 			test_ok = 0;
22172b15cb3dSCy Schubert 		} else {
22182b15cb3dSCy Schubert 			test_ok = 1;
22192b15cb3dSCy Schubert 		}
22202b15cb3dSCy Schubert 	}
22212b15cb3dSCy Schubert 
22222b15cb3dSCy Schubert 	called++;
22232b15cb3dSCy Schubert }
22242b15cb3dSCy Schubert 
22252b15cb3dSCy Schubert static void
22262b15cb3dSCy Schubert test_want_only_once(void)
22272b15cb3dSCy Schubert {
22282b15cb3dSCy Schubert 	struct event ev;
22292b15cb3dSCy Schubert 	struct timeval tv;
22302b15cb3dSCy Schubert 
22312b15cb3dSCy Schubert 	/* Very simple read test */
22322b15cb3dSCy Schubert 	setup_test("Want read only once: ");
22332b15cb3dSCy Schubert 
22342b15cb3dSCy Schubert 	if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) {
22352b15cb3dSCy Schubert 		tt_fail_perror("write");
22362b15cb3dSCy Schubert 	}
22372b15cb3dSCy Schubert 
22382b15cb3dSCy Schubert 	/* Setup the loop termination */
22392b15cb3dSCy Schubert 	evutil_timerclear(&tv);
22402b15cb3dSCy Schubert 	tv.tv_usec = 300*1000;
22412b15cb3dSCy Schubert 	event_loopexit(&tv);
22422b15cb3dSCy Schubert 
22432b15cb3dSCy Schubert 	event_set(&ev, pair[1], EV_READ, read_once_cb, &ev);
22442b15cb3dSCy Schubert 	if (event_add(&ev, NULL) == -1)
22452b15cb3dSCy Schubert 		exit(1);
22462b15cb3dSCy Schubert 	event_dispatch();
22472b15cb3dSCy Schubert 
22482b15cb3dSCy Schubert 	cleanup_test();
22492b15cb3dSCy Schubert }
22502b15cb3dSCy Schubert 
22512b15cb3dSCy Schubert #define TEST_MAX_INT	6
22522b15cb3dSCy Schubert 
22532b15cb3dSCy Schubert static void
22542b15cb3dSCy Schubert evtag_int_test(void *ptr)
22552b15cb3dSCy Schubert {
22562b15cb3dSCy Schubert 	struct evbuffer *tmp = evbuffer_new();
22572b15cb3dSCy Schubert 	ev_uint32_t integers[TEST_MAX_INT] = {
22582b15cb3dSCy Schubert 		0xaf0, 0x1000, 0x1, 0xdeadbeef, 0x00, 0xbef000
22592b15cb3dSCy Schubert 	};
22602b15cb3dSCy Schubert 	ev_uint32_t integer;
22612b15cb3dSCy Schubert 	ev_uint64_t big_int;
22622b15cb3dSCy Schubert 	int i;
22632b15cb3dSCy Schubert 
22642b15cb3dSCy Schubert 	evtag_init();
22652b15cb3dSCy Schubert 
22662b15cb3dSCy Schubert 	for (i = 0; i < TEST_MAX_INT; i++) {
22672b15cb3dSCy Schubert 		int oldlen, newlen;
22682b15cb3dSCy Schubert 		oldlen = (int)EVBUFFER_LENGTH(tmp);
22692b15cb3dSCy Schubert 		evtag_encode_int(tmp, integers[i]);
22702b15cb3dSCy Schubert 		newlen = (int)EVBUFFER_LENGTH(tmp);
22712b15cb3dSCy Schubert 		TT_BLATHER(("encoded 0x%08x with %d bytes",
22722b15cb3dSCy Schubert 			(unsigned)integers[i], newlen - oldlen));
22732b15cb3dSCy Schubert 		big_int = integers[i];
22742b15cb3dSCy Schubert 		big_int *= 1000000000; /* 1 billion */
22752b15cb3dSCy Schubert 		evtag_encode_int64(tmp, big_int);
22762b15cb3dSCy Schubert 	}
22772b15cb3dSCy Schubert 
22782b15cb3dSCy Schubert 	for (i = 0; i < TEST_MAX_INT; i++) {
22792b15cb3dSCy Schubert 		tt_int_op(evtag_decode_int(&integer, tmp), !=, -1);
22802b15cb3dSCy Schubert 		tt_uint_op(integer, ==, integers[i]);
22812b15cb3dSCy Schubert 		tt_int_op(evtag_decode_int64(&big_int, tmp), !=, -1);
22822b15cb3dSCy Schubert 		tt_assert((big_int / 1000000000) == integers[i]);
22832b15cb3dSCy Schubert 	}
22842b15cb3dSCy Schubert 
22852b15cb3dSCy Schubert 	tt_uint_op(EVBUFFER_LENGTH(tmp), ==, 0);
22862b15cb3dSCy Schubert end:
22872b15cb3dSCy Schubert 	evbuffer_free(tmp);
22882b15cb3dSCy Schubert }
22892b15cb3dSCy Schubert 
22902b15cb3dSCy Schubert static void
22912b15cb3dSCy Schubert evtag_fuzz(void *ptr)
22922b15cb3dSCy Schubert {
22932b15cb3dSCy Schubert 	u_char buffer[4096];
22942b15cb3dSCy Schubert 	struct evbuffer *tmp = evbuffer_new();
22952b15cb3dSCy Schubert 	struct timeval tv;
22962b15cb3dSCy Schubert 	int i, j;
22972b15cb3dSCy Schubert 
22982b15cb3dSCy Schubert 	int not_failed = 0;
22992b15cb3dSCy Schubert 
23002b15cb3dSCy Schubert 	evtag_init();
23012b15cb3dSCy Schubert 
23022b15cb3dSCy Schubert 	for (j = 0; j < 100; j++) {
23032b15cb3dSCy Schubert 		for (i = 0; i < (int)sizeof(buffer); i++)
2304*a25439b6SCy Schubert 			buffer[i] = test_weakrand();
23052b15cb3dSCy Schubert 		evbuffer_drain(tmp, -1);
23062b15cb3dSCy Schubert 		evbuffer_add(tmp, buffer, sizeof(buffer));
23072b15cb3dSCy Schubert 
23082b15cb3dSCy Schubert 		if (evtag_unmarshal_timeval(tmp, 0, &tv) != -1)
23092b15cb3dSCy Schubert 			not_failed++;
23102b15cb3dSCy Schubert 	}
23112b15cb3dSCy Schubert 
23122b15cb3dSCy Schubert 	/* The majority of decodes should fail */
23132b15cb3dSCy Schubert 	tt_int_op(not_failed, <, 10);
23142b15cb3dSCy Schubert 
23152b15cb3dSCy Schubert 	/* Now insert some corruption into the tag length field */
23162b15cb3dSCy Schubert 	evbuffer_drain(tmp, -1);
23172b15cb3dSCy Schubert 	evutil_timerclear(&tv);
23182b15cb3dSCy Schubert 	tv.tv_sec = 1;
23192b15cb3dSCy Schubert 	evtag_marshal_timeval(tmp, 0, &tv);
23202b15cb3dSCy Schubert 	evbuffer_add(tmp, buffer, sizeof(buffer));
23212b15cb3dSCy Schubert 
23222b15cb3dSCy Schubert 	((char *)EVBUFFER_DATA(tmp))[1] = '\xff';
23232b15cb3dSCy Schubert 	if (evtag_unmarshal_timeval(tmp, 0, &tv) != -1) {
23242b15cb3dSCy Schubert 		tt_abort_msg("evtag_unmarshal_timeval should have failed");
23252b15cb3dSCy Schubert 	}
23262b15cb3dSCy Schubert 
23272b15cb3dSCy Schubert end:
23282b15cb3dSCy Schubert 	evbuffer_free(tmp);
23292b15cb3dSCy Schubert }
23302b15cb3dSCy Schubert 
23312b15cb3dSCy Schubert static void
23322b15cb3dSCy Schubert evtag_tag_encoding(void *ptr)
23332b15cb3dSCy Schubert {
23342b15cb3dSCy Schubert 	struct evbuffer *tmp = evbuffer_new();
23352b15cb3dSCy Schubert 	ev_uint32_t integers[TEST_MAX_INT] = {
23362b15cb3dSCy Schubert 		0xaf0, 0x1000, 0x1, 0xdeadbeef, 0x00, 0xbef000
23372b15cb3dSCy Schubert 	};
23382b15cb3dSCy Schubert 	ev_uint32_t integer;
23392b15cb3dSCy Schubert 	int i;
23402b15cb3dSCy Schubert 
23412b15cb3dSCy Schubert 	evtag_init();
23422b15cb3dSCy Schubert 
23432b15cb3dSCy Schubert 	for (i = 0; i < TEST_MAX_INT; i++) {
23442b15cb3dSCy Schubert 		int oldlen, newlen;
23452b15cb3dSCy Schubert 		oldlen = (int)EVBUFFER_LENGTH(tmp);
23462b15cb3dSCy Schubert 		evtag_encode_tag(tmp, integers[i]);
23472b15cb3dSCy Schubert 		newlen = (int)EVBUFFER_LENGTH(tmp);
23482b15cb3dSCy Schubert 		TT_BLATHER(("encoded 0x%08x with %d bytes",
23492b15cb3dSCy Schubert 			(unsigned)integers[i], newlen - oldlen));
23502b15cb3dSCy Schubert 	}
23512b15cb3dSCy Schubert 
23522b15cb3dSCy Schubert 	for (i = 0; i < TEST_MAX_INT; i++) {
23532b15cb3dSCy Schubert 		tt_int_op(evtag_decode_tag(&integer, tmp), !=, -1);
23542b15cb3dSCy Schubert 		tt_uint_op(integer, ==, integers[i]);
23552b15cb3dSCy Schubert 	}
23562b15cb3dSCy Schubert 
23572b15cb3dSCy Schubert 	tt_uint_op(EVBUFFER_LENGTH(tmp), ==, 0);
23582b15cb3dSCy Schubert 
23592b15cb3dSCy Schubert end:
23602b15cb3dSCy Schubert 	evbuffer_free(tmp);
23612b15cb3dSCy Schubert }
23622b15cb3dSCy Schubert 
23632b15cb3dSCy Schubert static void
23642b15cb3dSCy Schubert evtag_test_peek(void *ptr)
23652b15cb3dSCy Schubert {
23662b15cb3dSCy Schubert 	struct evbuffer *tmp = evbuffer_new();
23672b15cb3dSCy Schubert 	ev_uint32_t u32;
23682b15cb3dSCy Schubert 
23692b15cb3dSCy Schubert 	evtag_marshal_int(tmp, 30, 0);
23702b15cb3dSCy Schubert 	evtag_marshal_string(tmp, 40, "Hello world");
23712b15cb3dSCy Schubert 
23722b15cb3dSCy Schubert 	tt_int_op(evtag_peek(tmp, &u32), ==, 1);
23732b15cb3dSCy Schubert 	tt_int_op(u32, ==, 30);
23742b15cb3dSCy Schubert 	tt_int_op(evtag_peek_length(tmp, &u32), ==, 0);
23752b15cb3dSCy Schubert 	tt_int_op(u32, ==, 1+1+1);
23762b15cb3dSCy Schubert 	tt_int_op(evtag_consume(tmp), ==, 0);
23772b15cb3dSCy Schubert 
23782b15cb3dSCy Schubert 	tt_int_op(evtag_peek(tmp, &u32), ==, 1);
23792b15cb3dSCy Schubert 	tt_int_op(u32, ==, 40);
23802b15cb3dSCy Schubert 	tt_int_op(evtag_peek_length(tmp, &u32), ==, 0);
23812b15cb3dSCy Schubert 	tt_int_op(u32, ==, 1+1+11);
23822b15cb3dSCy Schubert 	tt_int_op(evtag_payload_length(tmp, &u32), ==, 0);
23832b15cb3dSCy Schubert 	tt_int_op(u32, ==, 11);
23842b15cb3dSCy Schubert 
23852b15cb3dSCy Schubert end:
23862b15cb3dSCy Schubert 	evbuffer_free(tmp);
23872b15cb3dSCy Schubert }
23882b15cb3dSCy Schubert 
23892b15cb3dSCy Schubert 
23902b15cb3dSCy Schubert static void
23912b15cb3dSCy Schubert test_methods(void *ptr)
23922b15cb3dSCy Schubert {
23932b15cb3dSCy Schubert 	const char **methods = event_get_supported_methods();
23942b15cb3dSCy Schubert 	struct event_config *cfg = NULL;
23952b15cb3dSCy Schubert 	struct event_base *base = NULL;
23962b15cb3dSCy Schubert 	const char *backend;
23972b15cb3dSCy Schubert 	int n_methods = 0;
23982b15cb3dSCy Schubert 
23992b15cb3dSCy Schubert 	tt_assert(methods);
24002b15cb3dSCy Schubert 
24012b15cb3dSCy Schubert 	backend = methods[0];
24022b15cb3dSCy Schubert 	while (*methods != NULL) {
24032b15cb3dSCy Schubert 		TT_BLATHER(("Support method: %s", *methods));
24042b15cb3dSCy Schubert 		++methods;
24052b15cb3dSCy Schubert 		++n_methods;
24062b15cb3dSCy Schubert 	}
24072b15cb3dSCy Schubert 
24082b15cb3dSCy Schubert 	cfg = event_config_new();
24092b15cb3dSCy Schubert 	assert(cfg != NULL);
24102b15cb3dSCy Schubert 
24112b15cb3dSCy Schubert 	tt_int_op(event_config_avoid_method(cfg, backend), ==, 0);
24122b15cb3dSCy Schubert 	event_config_set_flag(cfg, EVENT_BASE_FLAG_IGNORE_ENV);
24132b15cb3dSCy Schubert 
24142b15cb3dSCy Schubert 	base = event_base_new_with_config(cfg);
24152b15cb3dSCy Schubert 	if (n_methods > 1) {
24162b15cb3dSCy Schubert 		tt_assert(base);
24172b15cb3dSCy Schubert 		tt_str_op(backend, !=, event_base_get_method(base));
24182b15cb3dSCy Schubert 	} else {
24192b15cb3dSCy Schubert 		tt_assert(base == NULL);
24202b15cb3dSCy Schubert 	}
24212b15cb3dSCy Schubert 
24222b15cb3dSCy Schubert end:
24232b15cb3dSCy Schubert 	if (base)
24242b15cb3dSCy Schubert 		event_base_free(base);
24252b15cb3dSCy Schubert 	if (cfg)
24262b15cb3dSCy Schubert 		event_config_free(cfg);
24272b15cb3dSCy Schubert }
24282b15cb3dSCy Schubert 
24292b15cb3dSCy Schubert static void
24302b15cb3dSCy Schubert test_version(void *arg)
24312b15cb3dSCy Schubert {
24322b15cb3dSCy Schubert 	const char *vstr;
24332b15cb3dSCy Schubert 	ev_uint32_t vint;
24342b15cb3dSCy Schubert 	int major, minor, patch, n;
24352b15cb3dSCy Schubert 
24362b15cb3dSCy Schubert 	vstr = event_get_version();
24372b15cb3dSCy Schubert 	vint = event_get_version_number();
24382b15cb3dSCy Schubert 
24392b15cb3dSCy Schubert 	tt_assert(vstr);
24402b15cb3dSCy Schubert 	tt_assert(vint);
24412b15cb3dSCy Schubert 
24422b15cb3dSCy Schubert 	tt_str_op(vstr, ==, LIBEVENT_VERSION);
24432b15cb3dSCy Schubert 	tt_int_op(vint, ==, LIBEVENT_VERSION_NUMBER);
24442b15cb3dSCy Schubert 
24452b15cb3dSCy Schubert 	n = sscanf(vstr, "%d.%d.%d", &major, &minor, &patch);
24462b15cb3dSCy Schubert 	tt_assert(3 == n);
24472b15cb3dSCy Schubert 	tt_int_op((vint&0xffffff00), ==, ((major<<24)|(minor<<16)|(patch<<8)));
24482b15cb3dSCy Schubert end:
24492b15cb3dSCy Schubert 	;
24502b15cb3dSCy Schubert }
24512b15cb3dSCy Schubert 
24522b15cb3dSCy Schubert static void
24532b15cb3dSCy Schubert test_base_features(void *arg)
24542b15cb3dSCy Schubert {
24552b15cb3dSCy Schubert 	struct event_base *base = NULL;
24562b15cb3dSCy Schubert 	struct event_config *cfg = NULL;
24572b15cb3dSCy Schubert 
24582b15cb3dSCy Schubert 	cfg = event_config_new();
24592b15cb3dSCy Schubert 
24602b15cb3dSCy Schubert 	tt_assert(0 == event_config_require_features(cfg, EV_FEATURE_ET));
24612b15cb3dSCy Schubert 
24622b15cb3dSCy Schubert 	base = event_base_new_with_config(cfg);
24632b15cb3dSCy Schubert 	if (base) {
24642b15cb3dSCy Schubert 		tt_int_op(EV_FEATURE_ET, ==,
24652b15cb3dSCy Schubert 		    event_base_get_features(base) & EV_FEATURE_ET);
24662b15cb3dSCy Schubert 	} else {
24672b15cb3dSCy Schubert 		base = event_base_new();
24682b15cb3dSCy Schubert 		tt_int_op(0, ==, event_base_get_features(base) & EV_FEATURE_ET);
24692b15cb3dSCy Schubert 	}
24702b15cb3dSCy Schubert 
24712b15cb3dSCy Schubert end:
24722b15cb3dSCy Schubert 	if (base)
24732b15cb3dSCy Schubert 		event_base_free(base);
24742b15cb3dSCy Schubert 	if (cfg)
24752b15cb3dSCy Schubert 		event_config_free(cfg);
24762b15cb3dSCy Schubert }
24772b15cb3dSCy Schubert 
24782b15cb3dSCy Schubert #ifdef EVENT__HAVE_SETENV
24792b15cb3dSCy Schubert #define SETENV_OK
24802b15cb3dSCy Schubert #elif !defined(EVENT__HAVE_SETENV) && defined(EVENT__HAVE_PUTENV)
24812b15cb3dSCy Schubert static void setenv(const char *k, const char *v, int o_)
24822b15cb3dSCy Schubert {
24832b15cb3dSCy Schubert 	char b[256];
24842b15cb3dSCy Schubert 	evutil_snprintf(b, sizeof(b), "%s=%s",k,v);
24852b15cb3dSCy Schubert 	putenv(b);
24862b15cb3dSCy Schubert }
24872b15cb3dSCy Schubert #define SETENV_OK
24882b15cb3dSCy Schubert #endif
24892b15cb3dSCy Schubert 
24902b15cb3dSCy Schubert #ifdef EVENT__HAVE_UNSETENV
24912b15cb3dSCy Schubert #define UNSETENV_OK
24922b15cb3dSCy Schubert #elif !defined(EVENT__HAVE_UNSETENV) && defined(EVENT__HAVE_PUTENV)
24932b15cb3dSCy Schubert static void unsetenv(const char *k)
24942b15cb3dSCy Schubert {
24952b15cb3dSCy Schubert 	char b[256];
24962b15cb3dSCy Schubert 	evutil_snprintf(b, sizeof(b), "%s=",k);
24972b15cb3dSCy Schubert 	putenv(b);
24982b15cb3dSCy Schubert }
24992b15cb3dSCy Schubert #define UNSETENV_OK
25002b15cb3dSCy Schubert #endif
25012b15cb3dSCy Schubert 
25022b15cb3dSCy Schubert #if defined(SETENV_OK) && defined(UNSETENV_OK)
25032b15cb3dSCy Schubert static void
25042b15cb3dSCy Schubert methodname_to_envvar(const char *mname, char *buf, size_t buflen)
25052b15cb3dSCy Schubert {
25062b15cb3dSCy Schubert 	char *cp;
25072b15cb3dSCy Schubert 	evutil_snprintf(buf, buflen, "EVENT_NO%s", mname);
25082b15cb3dSCy Schubert 	for (cp = buf; *cp; ++cp) {
25092b15cb3dSCy Schubert 		*cp = EVUTIL_TOUPPER_(*cp);
25102b15cb3dSCy Schubert 	}
25112b15cb3dSCy Schubert }
25122b15cb3dSCy Schubert #endif
25132b15cb3dSCy Schubert 
25142b15cb3dSCy Schubert static void
25152b15cb3dSCy Schubert test_base_environ(void *arg)
25162b15cb3dSCy Schubert {
25172b15cb3dSCy Schubert 	struct event_base *base = NULL;
25182b15cb3dSCy Schubert 	struct event_config *cfg = NULL;
25192b15cb3dSCy Schubert 
25202b15cb3dSCy Schubert #if defined(SETENV_OK) && defined(UNSETENV_OK)
25212b15cb3dSCy Schubert 	const char **basenames;
25222b15cb3dSCy Schubert 	int i, n_methods=0;
25232b15cb3dSCy Schubert 	char varbuf[128];
25242b15cb3dSCy Schubert 	const char *defaultname, *ignoreenvname;
25252b15cb3dSCy Schubert 
25262b15cb3dSCy Schubert 	/* See if unsetenv works before we rely on it. */
25272b15cb3dSCy Schubert 	setenv("EVENT_NOWAFFLES", "1", 1);
25282b15cb3dSCy Schubert 	unsetenv("EVENT_NOWAFFLES");
25292b15cb3dSCy Schubert 	if (getenv("EVENT_NOWAFFLES") != NULL) {
25302b15cb3dSCy Schubert #ifndef EVENT__HAVE_UNSETENV
25312b15cb3dSCy Schubert 		TT_DECLARE("NOTE", ("Can't fake unsetenv; skipping test"));
25322b15cb3dSCy Schubert #else
25332b15cb3dSCy Schubert 		TT_DECLARE("NOTE", ("unsetenv doesn't work; skipping test"));
25342b15cb3dSCy Schubert #endif
25352b15cb3dSCy Schubert 		tt_skip();
25362b15cb3dSCy Schubert 	}
25372b15cb3dSCy Schubert 
25382b15cb3dSCy Schubert 	basenames = event_get_supported_methods();
25392b15cb3dSCy Schubert 	for (i = 0; basenames[i]; ++i) {
25402b15cb3dSCy Schubert 		methodname_to_envvar(basenames[i], varbuf, sizeof(varbuf));
25412b15cb3dSCy Schubert 		unsetenv(varbuf);
25422b15cb3dSCy Schubert 		++n_methods;
25432b15cb3dSCy Schubert 	}
25442b15cb3dSCy Schubert 
25452b15cb3dSCy Schubert 	base = event_base_new();
25462b15cb3dSCy Schubert 	tt_assert(base);
25472b15cb3dSCy Schubert 
25482b15cb3dSCy Schubert 	defaultname = event_base_get_method(base);
25492b15cb3dSCy Schubert 	TT_BLATHER(("default is <%s>", defaultname));
25502b15cb3dSCy Schubert 	event_base_free(base);
25512b15cb3dSCy Schubert 	base = NULL;
25522b15cb3dSCy Schubert 
25532b15cb3dSCy Schubert 	/* Can we disable the method with EVENT_NOfoo ? */
25542b15cb3dSCy Schubert 	if (!strcmp(defaultname, "epoll (with changelist)")) {
25552b15cb3dSCy Schubert  		setenv("EVENT_NOEPOLL", "1", 1);
25562b15cb3dSCy Schubert 		ignoreenvname = "epoll";
25572b15cb3dSCy Schubert 	} else {
25582b15cb3dSCy Schubert 		methodname_to_envvar(defaultname, varbuf, sizeof(varbuf));
25592b15cb3dSCy Schubert 		setenv(varbuf, "1", 1);
25602b15cb3dSCy Schubert 		ignoreenvname = defaultname;
25612b15cb3dSCy Schubert 	}
25622b15cb3dSCy Schubert 
25632b15cb3dSCy Schubert 	/* Use an empty cfg rather than NULL so a failure doesn't exit() */
25642b15cb3dSCy Schubert 	cfg = event_config_new();
25652b15cb3dSCy Schubert 	base = event_base_new_with_config(cfg);
25662b15cb3dSCy Schubert 	event_config_free(cfg);
25672b15cb3dSCy Schubert 	cfg = NULL;
25682b15cb3dSCy Schubert 	if (n_methods == 1) {
25692b15cb3dSCy Schubert 		tt_assert(!base);
25702b15cb3dSCy Schubert 	} else {
25712b15cb3dSCy Schubert 		tt_assert(base);
25722b15cb3dSCy Schubert 		tt_str_op(defaultname, !=, event_base_get_method(base));
25732b15cb3dSCy Schubert 		event_base_free(base);
25742b15cb3dSCy Schubert 		base = NULL;
25752b15cb3dSCy Schubert 	}
25762b15cb3dSCy Schubert 
25772b15cb3dSCy Schubert 	/* Can we disable looking at the environment with IGNORE_ENV ? */
25782b15cb3dSCy Schubert 	cfg = event_config_new();
25792b15cb3dSCy Schubert 	event_config_set_flag(cfg, EVENT_BASE_FLAG_IGNORE_ENV);
25802b15cb3dSCy Schubert 	base = event_base_new_with_config(cfg);
25812b15cb3dSCy Schubert 	tt_assert(base);
25822b15cb3dSCy Schubert 	tt_str_op(ignoreenvname, ==, event_base_get_method(base));
25832b15cb3dSCy Schubert #else
25842b15cb3dSCy Schubert 	tt_skip();
25852b15cb3dSCy Schubert #endif
25862b15cb3dSCy Schubert 
25872b15cb3dSCy Schubert end:
25882b15cb3dSCy Schubert 	if (base)
25892b15cb3dSCy Schubert 		event_base_free(base);
25902b15cb3dSCy Schubert 	if (cfg)
25912b15cb3dSCy Schubert 		event_config_free(cfg);
25922b15cb3dSCy Schubert }
25932b15cb3dSCy Schubert 
25942b15cb3dSCy Schubert static void
25952b15cb3dSCy Schubert read_called_once_cb(evutil_socket_t fd, short event, void *arg)
25962b15cb3dSCy Schubert {
25972b15cb3dSCy Schubert 	tt_int_op(event, ==, EV_READ);
25982b15cb3dSCy Schubert 	called += 1;
25992b15cb3dSCy Schubert end:
26002b15cb3dSCy Schubert 	;
26012b15cb3dSCy Schubert }
26022b15cb3dSCy Schubert 
26032b15cb3dSCy Schubert static void
26042b15cb3dSCy Schubert timeout_called_once_cb(evutil_socket_t fd, short event, void *arg)
26052b15cb3dSCy Schubert {
26062b15cb3dSCy Schubert 	tt_int_op(event, ==, EV_TIMEOUT);
26072b15cb3dSCy Schubert 	called += 100;
26082b15cb3dSCy Schubert end:
26092b15cb3dSCy Schubert 	;
26102b15cb3dSCy Schubert }
26112b15cb3dSCy Schubert 
26122b15cb3dSCy Schubert static void
26132b15cb3dSCy Schubert immediate_called_twice_cb(evutil_socket_t fd, short event, void *arg)
26142b15cb3dSCy Schubert {
26152b15cb3dSCy Schubert 	tt_int_op(event, ==, EV_TIMEOUT);
26162b15cb3dSCy Schubert 	called += 1000;
26172b15cb3dSCy Schubert end:
26182b15cb3dSCy Schubert 	;
26192b15cb3dSCy Schubert }
26202b15cb3dSCy Schubert 
26212b15cb3dSCy Schubert static void
26222b15cb3dSCy Schubert test_event_once(void *ptr)
26232b15cb3dSCy Schubert {
26242b15cb3dSCy Schubert 	struct basic_test_data *data = ptr;
26252b15cb3dSCy Schubert 	struct timeval tv;
26262b15cb3dSCy Schubert 	int r;
26272b15cb3dSCy Schubert 
26282b15cb3dSCy Schubert 	tv.tv_sec = 0;
26292b15cb3dSCy Schubert 	tv.tv_usec = 50*1000;
26302b15cb3dSCy Schubert 	called = 0;
26312b15cb3dSCy Schubert 	r = event_base_once(data->base, data->pair[0], EV_READ,
26322b15cb3dSCy Schubert 	    read_called_once_cb, NULL, NULL);
26332b15cb3dSCy Schubert 	tt_int_op(r, ==, 0);
26342b15cb3dSCy Schubert 	r = event_base_once(data->base, -1, EV_TIMEOUT,
26352b15cb3dSCy Schubert 	    timeout_called_once_cb, NULL, &tv);
26362b15cb3dSCy Schubert 	tt_int_op(r, ==, 0);
26372b15cb3dSCy Schubert 	r = event_base_once(data->base, -1, 0, NULL, NULL, NULL);
26382b15cb3dSCy Schubert 	tt_int_op(r, <, 0);
26392b15cb3dSCy Schubert 	r = event_base_once(data->base, -1, EV_TIMEOUT,
26402b15cb3dSCy Schubert 	    immediate_called_twice_cb, NULL, NULL);
26412b15cb3dSCy Schubert 	tt_int_op(r, ==, 0);
26422b15cb3dSCy Schubert 	tv.tv_sec = 0;
26432b15cb3dSCy Schubert 	tv.tv_usec = 0;
26442b15cb3dSCy Schubert 	r = event_base_once(data->base, -1, EV_TIMEOUT,
26452b15cb3dSCy Schubert 	    immediate_called_twice_cb, NULL, &tv);
26462b15cb3dSCy Schubert 	tt_int_op(r, ==, 0);
26472b15cb3dSCy Schubert 
26482b15cb3dSCy Schubert 	if (write(data->pair[1], TEST1, strlen(TEST1)+1) < 0) {
26492b15cb3dSCy Schubert 		tt_fail_perror("write");
26502b15cb3dSCy Schubert 	}
26512b15cb3dSCy Schubert 
26522b15cb3dSCy Schubert 	shutdown(data->pair[1], SHUT_WR);
26532b15cb3dSCy Schubert 
26542b15cb3dSCy Schubert 	event_base_dispatch(data->base);
26552b15cb3dSCy Schubert 
26562b15cb3dSCy Schubert 	tt_int_op(called, ==, 2101);
26572b15cb3dSCy Schubert end:
26582b15cb3dSCy Schubert 	;
26592b15cb3dSCy Schubert }
26602b15cb3dSCy Schubert 
26612b15cb3dSCy Schubert static void
26622b15cb3dSCy Schubert test_event_once_never(void *ptr)
26632b15cb3dSCy Schubert {
26642b15cb3dSCy Schubert 	struct basic_test_data *data = ptr;
26652b15cb3dSCy Schubert 	struct timeval tv;
26662b15cb3dSCy Schubert 
26672b15cb3dSCy Schubert 	/* Have one trigger in 10 seconds (don't worry, because) */
26682b15cb3dSCy Schubert 	tv.tv_sec = 10;
26692b15cb3dSCy Schubert 	tv.tv_usec = 0;
26702b15cb3dSCy Schubert 	called = 0;
26712b15cb3dSCy Schubert 	event_base_once(data->base, -1, EV_TIMEOUT,
26722b15cb3dSCy Schubert 	    timeout_called_once_cb, NULL, &tv);
26732b15cb3dSCy Schubert 
26742b15cb3dSCy Schubert 	/* But shut down the base in 75 msec. */
26752b15cb3dSCy Schubert 	tv.tv_sec = 0;
26762b15cb3dSCy Schubert 	tv.tv_usec = 75*1000;
26772b15cb3dSCy Schubert 	event_base_loopexit(data->base, &tv);
26782b15cb3dSCy Schubert 
26792b15cb3dSCy Schubert 	event_base_dispatch(data->base);
26802b15cb3dSCy Schubert 
26812b15cb3dSCy Schubert 	tt_int_op(called, ==, 0);
26822b15cb3dSCy Schubert end:
26832b15cb3dSCy Schubert 	;
26842b15cb3dSCy Schubert }
26852b15cb3dSCy Schubert 
26862b15cb3dSCy Schubert static void
26872b15cb3dSCy Schubert test_event_pending(void *ptr)
26882b15cb3dSCy Schubert {
26892b15cb3dSCy Schubert 	struct basic_test_data *data = ptr;
26902b15cb3dSCy Schubert 	struct event *r=NULL, *w=NULL, *t=NULL;
26912b15cb3dSCy Schubert 	struct timeval tv, now, tv2;
26922b15cb3dSCy Schubert 
26932b15cb3dSCy Schubert 	tv.tv_sec = 0;
26942b15cb3dSCy Schubert 	tv.tv_usec = 500 * 1000;
26952b15cb3dSCy Schubert 	r = event_new(data->base, data->pair[0], EV_READ, simple_read_cb,
26962b15cb3dSCy Schubert 	    NULL);
26972b15cb3dSCy Schubert 	w = event_new(data->base, data->pair[1], EV_WRITE, simple_write_cb,
26982b15cb3dSCy Schubert 	    NULL);
26992b15cb3dSCy Schubert 	t = evtimer_new(data->base, timeout_cb, NULL);
27002b15cb3dSCy Schubert 
27012b15cb3dSCy Schubert 	tt_assert(r);
27022b15cb3dSCy Schubert 	tt_assert(w);
27032b15cb3dSCy Schubert 	tt_assert(t);
27042b15cb3dSCy Schubert 
27052b15cb3dSCy Schubert 	evutil_gettimeofday(&now, NULL);
27062b15cb3dSCy Schubert 	event_add(r, NULL);
27072b15cb3dSCy Schubert 	event_add(t, &tv);
27082b15cb3dSCy Schubert 
27092b15cb3dSCy Schubert 	tt_assert( event_pending(r, EV_READ, NULL));
27102b15cb3dSCy Schubert 	tt_assert(!event_pending(w, EV_WRITE, NULL));
27112b15cb3dSCy Schubert 	tt_assert(!event_pending(r, EV_WRITE, NULL));
27122b15cb3dSCy Schubert 	tt_assert( event_pending(r, EV_READ|EV_WRITE, NULL));
27132b15cb3dSCy Schubert 	tt_assert(!event_pending(r, EV_TIMEOUT, NULL));
27142b15cb3dSCy Schubert 	tt_assert( event_pending(t, EV_TIMEOUT, NULL));
27152b15cb3dSCy Schubert 	tt_assert( event_pending(t, EV_TIMEOUT, &tv2));
27162b15cb3dSCy Schubert 
27172b15cb3dSCy Schubert 	tt_assert(evutil_timercmp(&tv2, &now, >));
27182b15cb3dSCy Schubert 
27192b15cb3dSCy Schubert 	test_timeval_diff_eq(&now, &tv2, 500);
27202b15cb3dSCy Schubert 
27212b15cb3dSCy Schubert end:
27222b15cb3dSCy Schubert 	if (r) {
27232b15cb3dSCy Schubert 		event_del(r);
27242b15cb3dSCy Schubert 		event_free(r);
27252b15cb3dSCy Schubert 	}
27262b15cb3dSCy Schubert 	if (w) {
27272b15cb3dSCy Schubert 		event_del(w);
27282b15cb3dSCy Schubert 		event_free(w);
27292b15cb3dSCy Schubert 	}
27302b15cb3dSCy Schubert 	if (t) {
27312b15cb3dSCy Schubert 		event_del(t);
27322b15cb3dSCy Schubert 		event_free(t);
27332b15cb3dSCy Schubert 	}
27342b15cb3dSCy Schubert }
27352b15cb3dSCy Schubert 
27362b15cb3dSCy Schubert #ifndef _WIN32
27372b15cb3dSCy Schubert /* You can't do this test on windows, since dup2 doesn't work on sockets */
27382b15cb3dSCy Schubert 
27392b15cb3dSCy Schubert static void
27402b15cb3dSCy Schubert dfd_cb(evutil_socket_t fd, short e, void *data)
27412b15cb3dSCy Schubert {
27422b15cb3dSCy Schubert 	*(int*)data = (int)e;
27432b15cb3dSCy Schubert }
27442b15cb3dSCy Schubert 
27452b15cb3dSCy Schubert /* Regression test for our workaround for a fun epoll/linux related bug
27462b15cb3dSCy Schubert  * where fd2 = dup(fd1); add(fd2); close(fd2); dup2(fd1,fd2); add(fd2)
27472b15cb3dSCy Schubert  * will get you an EEXIST */
27482b15cb3dSCy Schubert static void
27492b15cb3dSCy Schubert test_dup_fd(void *arg)
27502b15cb3dSCy Schubert {
27512b15cb3dSCy Schubert 	struct basic_test_data *data = arg;
27522b15cb3dSCy Schubert 	struct event_base *base = data->base;
27532b15cb3dSCy Schubert 	struct event *ev1=NULL, *ev2=NULL;
27542b15cb3dSCy Schubert 	int fd, dfd=-1;
27552b15cb3dSCy Schubert 	int ev1_got, ev2_got;
27562b15cb3dSCy Schubert 
27572b15cb3dSCy Schubert 	tt_int_op(write(data->pair[0], "Hello world",
27582b15cb3dSCy Schubert 		strlen("Hello world")), >, 0);
27592b15cb3dSCy Schubert 	fd = data->pair[1];
27602b15cb3dSCy Schubert 
27612b15cb3dSCy Schubert 	dfd = dup(fd);
27622b15cb3dSCy Schubert 	tt_int_op(dfd, >=, 0);
27632b15cb3dSCy Schubert 
27642b15cb3dSCy Schubert 	ev1 = event_new(base, fd, EV_READ|EV_PERSIST, dfd_cb, &ev1_got);
27652b15cb3dSCy Schubert 	ev2 = event_new(base, dfd, EV_READ|EV_PERSIST, dfd_cb, &ev2_got);
27662b15cb3dSCy Schubert 	ev1_got = ev2_got = 0;
27672b15cb3dSCy Schubert 	event_add(ev1, NULL);
27682b15cb3dSCy Schubert 	event_add(ev2, NULL);
27692b15cb3dSCy Schubert 	event_base_loop(base, EVLOOP_ONCE);
27702b15cb3dSCy Schubert 	tt_int_op(ev1_got, ==, EV_READ);
27712b15cb3dSCy Schubert 	tt_int_op(ev2_got, ==, EV_READ);
27722b15cb3dSCy Schubert 
27732b15cb3dSCy Schubert 	/* Now close and delete dfd then dispatch.  We need to do the
27742b15cb3dSCy Schubert 	 * dispatch here so that when we add it later, we think there
27752b15cb3dSCy Schubert 	 * was an intermediate delete. */
27762b15cb3dSCy Schubert 	close(dfd);
27772b15cb3dSCy Schubert 	event_del(ev2);
27782b15cb3dSCy Schubert 	ev1_got = ev2_got = 0;
27792b15cb3dSCy Schubert 	event_base_loop(base, EVLOOP_ONCE);
27802b15cb3dSCy Schubert 	tt_want_int_op(ev1_got, ==, EV_READ);
27812b15cb3dSCy Schubert 	tt_int_op(ev2_got, ==, 0);
27822b15cb3dSCy Schubert 
27832b15cb3dSCy Schubert 	/* Re-duplicate the fd.  We need to get the same duplicated
27842b15cb3dSCy Schubert 	 * value that we closed to provoke the epoll quirk.  Also, we
27852b15cb3dSCy Schubert 	 * need to change the events to write, or else the old lingering
27862b15cb3dSCy Schubert 	 * read event will make the test pass whether the change was
27872b15cb3dSCy Schubert 	 * successful or not. */
27882b15cb3dSCy Schubert 	tt_int_op(dup2(fd, dfd), ==, dfd);
27892b15cb3dSCy Schubert 	event_free(ev2);
27902b15cb3dSCy Schubert 	ev2 = event_new(base, dfd, EV_WRITE|EV_PERSIST, dfd_cb, &ev2_got);
27912b15cb3dSCy Schubert 	event_add(ev2, NULL);
27922b15cb3dSCy Schubert 	ev1_got = ev2_got = 0;
27932b15cb3dSCy Schubert 	event_base_loop(base, EVLOOP_ONCE);
27942b15cb3dSCy Schubert 	tt_want_int_op(ev1_got, ==, EV_READ);
27952b15cb3dSCy Schubert 	tt_int_op(ev2_got, ==, EV_WRITE);
27962b15cb3dSCy Schubert 
27972b15cb3dSCy Schubert end:
27982b15cb3dSCy Schubert 	if (ev1)
27992b15cb3dSCy Schubert 		event_free(ev1);
28002b15cb3dSCy Schubert 	if (ev2)
28012b15cb3dSCy Schubert 		event_free(ev2);
28022b15cb3dSCy Schubert 	if (dfd >= 0)
28032b15cb3dSCy Schubert 		close(dfd);
28042b15cb3dSCy Schubert }
28052b15cb3dSCy Schubert #endif
28062b15cb3dSCy Schubert 
28072b15cb3dSCy Schubert #ifdef EVENT__DISABLE_MM_REPLACEMENT
28082b15cb3dSCy Schubert static void
28092b15cb3dSCy Schubert test_mm_functions(void *arg)
28102b15cb3dSCy Schubert {
28112b15cb3dSCy Schubert 	tinytest_set_test_skipped_();
28122b15cb3dSCy Schubert }
28132b15cb3dSCy Schubert #else
28142b15cb3dSCy Schubert static int
28152b15cb3dSCy Schubert check_dummy_mem_ok(void *mem_)
28162b15cb3dSCy Schubert {
28172b15cb3dSCy Schubert 	char *mem = mem_;
28182b15cb3dSCy Schubert 	mem -= 16;
28192b15cb3dSCy Schubert 	return !memcmp(mem, "{[<guardedram>]}", 16);
28202b15cb3dSCy Schubert }
28212b15cb3dSCy Schubert 
28222b15cb3dSCy Schubert static void *
28232b15cb3dSCy Schubert dummy_malloc(size_t len)
28242b15cb3dSCy Schubert {
28252b15cb3dSCy Schubert 	char *mem = malloc(len+16);
28262b15cb3dSCy Schubert 	memcpy(mem, "{[<guardedram>]}", 16);
28272b15cb3dSCy Schubert 	return mem+16;
28282b15cb3dSCy Schubert }
28292b15cb3dSCy Schubert 
28302b15cb3dSCy Schubert static void *
28312b15cb3dSCy Schubert dummy_realloc(void *mem_, size_t len)
28322b15cb3dSCy Schubert {
28332b15cb3dSCy Schubert 	char *mem = mem_;
28342b15cb3dSCy Schubert 	if (!mem)
28352b15cb3dSCy Schubert 		return dummy_malloc(len);
28362b15cb3dSCy Schubert 	tt_want(check_dummy_mem_ok(mem_));
28372b15cb3dSCy Schubert 	mem -= 16;
28382b15cb3dSCy Schubert 	mem = realloc(mem, len+16);
28392b15cb3dSCy Schubert 	return mem+16;
28402b15cb3dSCy Schubert }
28412b15cb3dSCy Schubert 
28422b15cb3dSCy Schubert static void
28432b15cb3dSCy Schubert dummy_free(void *mem_)
28442b15cb3dSCy Schubert {
28452b15cb3dSCy Schubert 	char *mem = mem_;
28462b15cb3dSCy Schubert 	tt_want(check_dummy_mem_ok(mem_));
28472b15cb3dSCy Schubert 	mem -= 16;
28482b15cb3dSCy Schubert 	free(mem);
28492b15cb3dSCy Schubert }
28502b15cb3dSCy Schubert 
28512b15cb3dSCy Schubert static void
28522b15cb3dSCy Schubert test_mm_functions(void *arg)
28532b15cb3dSCy Schubert {
28542b15cb3dSCy Schubert 	struct event_base *b = NULL;
28552b15cb3dSCy Schubert 	struct event_config *cfg = NULL;
28562b15cb3dSCy Schubert 	event_set_mem_functions(dummy_malloc, dummy_realloc, dummy_free);
28572b15cb3dSCy Schubert 	cfg = event_config_new();
28582b15cb3dSCy Schubert 	event_config_avoid_method(cfg, "Nonesuch");
28592b15cb3dSCy Schubert 	b = event_base_new_with_config(cfg);
28602b15cb3dSCy Schubert 	tt_assert(b);
28612b15cb3dSCy Schubert 	tt_assert(check_dummy_mem_ok(b));
28622b15cb3dSCy Schubert end:
28632b15cb3dSCy Schubert 	if (cfg)
28642b15cb3dSCy Schubert 		event_config_free(cfg);
28652b15cb3dSCy Schubert 	if (b)
28662b15cb3dSCy Schubert 		event_base_free(b);
28672b15cb3dSCy Schubert }
28682b15cb3dSCy Schubert #endif
28692b15cb3dSCy Schubert 
28702b15cb3dSCy Schubert static void
28712b15cb3dSCy Schubert many_event_cb(evutil_socket_t fd, short event, void *arg)
28722b15cb3dSCy Schubert {
28732b15cb3dSCy Schubert 	int *calledp = arg;
28742b15cb3dSCy Schubert 	*calledp += 1;
28752b15cb3dSCy Schubert }
28762b15cb3dSCy Schubert 
28772b15cb3dSCy Schubert static void
28782b15cb3dSCy Schubert test_many_events(void *arg)
28792b15cb3dSCy Schubert {
28802b15cb3dSCy Schubert 	/* Try 70 events that should all be ready at once.  This will
28812b15cb3dSCy Schubert 	 * exercise the "resize" code on most of the backends, and will make
28822b15cb3dSCy Schubert 	 * sure that we can get past the 64-handle limit of some windows
28832b15cb3dSCy Schubert 	 * functions. */
28842b15cb3dSCy Schubert #define MANY 70
28852b15cb3dSCy Schubert 
28862b15cb3dSCy Schubert 	struct basic_test_data *data = arg;
28872b15cb3dSCy Schubert 	struct event_base *base = data->base;
28882b15cb3dSCy Schubert 	int one_at_a_time = data->setup_data != NULL;
28892b15cb3dSCy Schubert 	evutil_socket_t sock[MANY];
28902b15cb3dSCy Schubert 	struct event *ev[MANY];
28912b15cb3dSCy Schubert 	int called[MANY];
28922b15cb3dSCy Schubert 	int i;
28932b15cb3dSCy Schubert 	int loopflags = EVLOOP_NONBLOCK, evflags=0;
28942b15cb3dSCy Schubert 	if (one_at_a_time) {
28952b15cb3dSCy Schubert 		loopflags |= EVLOOP_ONCE;
28962b15cb3dSCy Schubert 		evflags = EV_PERSIST;
28972b15cb3dSCy Schubert 	}
28982b15cb3dSCy Schubert 
28992b15cb3dSCy Schubert 	memset(sock, 0xff, sizeof(sock));
29002b15cb3dSCy Schubert 	memset(ev, 0, sizeof(ev));
29012b15cb3dSCy Schubert 	memset(called, 0, sizeof(called));
29022b15cb3dSCy Schubert 
29032b15cb3dSCy Schubert 	for (i = 0; i < MANY; ++i) {
29042b15cb3dSCy Schubert 		/* We need an event that will hit the backend, and that will
29052b15cb3dSCy Schubert 		 * be ready immediately.  "Send a datagram" is an easy
29062b15cb3dSCy Schubert 		 * instance of that. */
29072b15cb3dSCy Schubert 		sock[i] = socket(AF_INET, SOCK_DGRAM, 0);
29082b15cb3dSCy Schubert 		tt_assert(sock[i] >= 0);
29092b15cb3dSCy Schubert 		called[i] = 0;
29102b15cb3dSCy Schubert 		ev[i] = event_new(base, sock[i], EV_WRITE|evflags,
29112b15cb3dSCy Schubert 		    many_event_cb, &called[i]);
29122b15cb3dSCy Schubert 		event_add(ev[i], NULL);
29132b15cb3dSCy Schubert 		if (one_at_a_time)
29142b15cb3dSCy Schubert 			event_base_loop(base, EVLOOP_NONBLOCK|EVLOOP_ONCE);
29152b15cb3dSCy Schubert 	}
29162b15cb3dSCy Schubert 
29172b15cb3dSCy Schubert 	event_base_loop(base, loopflags);
29182b15cb3dSCy Schubert 
29192b15cb3dSCy Schubert 	for (i = 0; i < MANY; ++i) {
29202b15cb3dSCy Schubert 		if (one_at_a_time)
29212b15cb3dSCy Schubert 			tt_int_op(called[i], ==, MANY - i + 1);
29222b15cb3dSCy Schubert 		else
29232b15cb3dSCy Schubert 			tt_int_op(called[i], ==, 1);
29242b15cb3dSCy Schubert 	}
29252b15cb3dSCy Schubert 
29262b15cb3dSCy Schubert end:
29272b15cb3dSCy Schubert 	for (i = 0; i < MANY; ++i) {
29282b15cb3dSCy Schubert 		if (ev[i])
29292b15cb3dSCy Schubert 			event_free(ev[i]);
29302b15cb3dSCy Schubert 		if (sock[i] >= 0)
29312b15cb3dSCy Schubert 			evutil_closesocket(sock[i]);
29322b15cb3dSCy Schubert 	}
29332b15cb3dSCy Schubert #undef MANY
29342b15cb3dSCy Schubert }
29352b15cb3dSCy Schubert 
29362b15cb3dSCy Schubert static void
29372b15cb3dSCy Schubert test_struct_event_size(void *arg)
29382b15cb3dSCy Schubert {
29392b15cb3dSCy Schubert 	tt_int_op(event_get_struct_event_size(), <=, sizeof(struct event));
29402b15cb3dSCy Schubert end:
29412b15cb3dSCy Schubert 	;
29422b15cb3dSCy Schubert }
29432b15cb3dSCy Schubert 
29442b15cb3dSCy Schubert static void
29452b15cb3dSCy Schubert test_get_assignment(void *arg)
29462b15cb3dSCy Schubert {
29472b15cb3dSCy Schubert 	struct basic_test_data *data = arg;
29482b15cb3dSCy Schubert 	struct event_base *base = data->base;
29492b15cb3dSCy Schubert 	struct event *ev1 = NULL;
29502b15cb3dSCy Schubert 	const char *str = "foo";
29512b15cb3dSCy Schubert 
29522b15cb3dSCy Schubert 	struct event_base *b;
29532b15cb3dSCy Schubert 	evutil_socket_t s;
29542b15cb3dSCy Schubert 	short what;
29552b15cb3dSCy Schubert 	event_callback_fn cb;
29562b15cb3dSCy Schubert 	void *cb_arg;
29572b15cb3dSCy Schubert 
29582b15cb3dSCy Schubert 	ev1 = event_new(base, data->pair[1], EV_READ, dummy_read_cb, (void*)str);
29592b15cb3dSCy Schubert 	event_get_assignment(ev1, &b, &s, &what, &cb, &cb_arg);
29602b15cb3dSCy Schubert 
29612b15cb3dSCy Schubert 	tt_ptr_op(b, ==, base);
29622b15cb3dSCy Schubert 	tt_int_op(s, ==, data->pair[1]);
29632b15cb3dSCy Schubert 	tt_int_op(what, ==, EV_READ);
29642b15cb3dSCy Schubert 	tt_ptr_op(cb, ==, dummy_read_cb);
29652b15cb3dSCy Schubert 	tt_ptr_op(cb_arg, ==, str);
29662b15cb3dSCy Schubert 
29672b15cb3dSCy Schubert 	/* Now make sure this doesn't crash. */
29682b15cb3dSCy Schubert 	event_get_assignment(ev1, NULL, NULL, NULL, NULL, NULL);
29692b15cb3dSCy Schubert 
29702b15cb3dSCy Schubert end:
29712b15cb3dSCy Schubert 	if (ev1)
29722b15cb3dSCy Schubert 		event_free(ev1);
29732b15cb3dSCy Schubert }
29742b15cb3dSCy Schubert 
29752b15cb3dSCy Schubert struct foreach_helper {
29762b15cb3dSCy Schubert 	int count;
29772b15cb3dSCy Schubert 	const struct event *ev;
29782b15cb3dSCy Schubert };
29792b15cb3dSCy Schubert 
29802b15cb3dSCy Schubert static int
29812b15cb3dSCy Schubert foreach_count_cb(const struct event_base *base, const struct event *ev, void *arg)
29822b15cb3dSCy Schubert {
29832b15cb3dSCy Schubert 	struct foreach_helper *h = event_get_callback_arg(ev);
29842b15cb3dSCy Schubert 	struct timeval *tv = arg;
29852b15cb3dSCy Schubert 	if (event_get_callback(ev) != timeout_cb)
29862b15cb3dSCy Schubert 		return 0;
29872b15cb3dSCy Schubert 	tt_ptr_op(event_get_base(ev), ==, base);
29882b15cb3dSCy Schubert 	tt_int_op(tv->tv_sec, ==, 10);
29892b15cb3dSCy Schubert 	h->ev = ev;
29902b15cb3dSCy Schubert 	h->count++;
29912b15cb3dSCy Schubert 	return 0;
29922b15cb3dSCy Schubert end:
29932b15cb3dSCy Schubert 	return -1;
29942b15cb3dSCy Schubert }
29952b15cb3dSCy Schubert 
29962b15cb3dSCy Schubert static int
29972b15cb3dSCy Schubert foreach_find_cb(const struct event_base *base, const struct event *ev, void *arg)
29982b15cb3dSCy Schubert {
29992b15cb3dSCy Schubert 	const struct event **ev_out = arg;
30002b15cb3dSCy Schubert 	struct foreach_helper *h = event_get_callback_arg(ev);
30012b15cb3dSCy Schubert 	if (event_get_callback(ev) != timeout_cb)
30022b15cb3dSCy Schubert 		return 0;
30032b15cb3dSCy Schubert 	if (h->count == 99) {
30042b15cb3dSCy Schubert 		*ev_out = ev;
30052b15cb3dSCy Schubert 		return 101;
30062b15cb3dSCy Schubert 	}
30072b15cb3dSCy Schubert 	return 0;
30082b15cb3dSCy Schubert }
30092b15cb3dSCy Schubert 
30102b15cb3dSCy Schubert static void
30112b15cb3dSCy Schubert test_event_foreach(void *arg)
30122b15cb3dSCy Schubert {
30132b15cb3dSCy Schubert 	struct basic_test_data *data = arg;
30142b15cb3dSCy Schubert 	struct event_base *base = data->base;
30152b15cb3dSCy Schubert 	struct event *ev[5];
30162b15cb3dSCy Schubert 	struct foreach_helper visited[5];
30172b15cb3dSCy Schubert 	int i;
30182b15cb3dSCy Schubert 	struct timeval ten_sec = {10,0};
30192b15cb3dSCy Schubert 	const struct event *ev_found = NULL;
30202b15cb3dSCy Schubert 
30212b15cb3dSCy Schubert 	for (i = 0; i < 5; ++i) {
30222b15cb3dSCy Schubert 		visited[i].count = 0;
30232b15cb3dSCy Schubert 		visited[i].ev = NULL;
30242b15cb3dSCy Schubert 		ev[i] = event_new(base, -1, 0, timeout_cb, &visited[i]);
30252b15cb3dSCy Schubert 	}
30262b15cb3dSCy Schubert 
30272b15cb3dSCy Schubert 	tt_int_op(-1, ==, event_base_foreach_event(NULL, foreach_count_cb, NULL));
30282b15cb3dSCy Schubert 	tt_int_op(-1, ==, event_base_foreach_event(base, NULL, NULL));
30292b15cb3dSCy Schubert 
30302b15cb3dSCy Schubert 	event_add(ev[0], &ten_sec);
30312b15cb3dSCy Schubert 	event_add(ev[1], &ten_sec);
30322b15cb3dSCy Schubert 	event_active(ev[1], EV_TIMEOUT, 1);
30332b15cb3dSCy Schubert 	event_active(ev[2], EV_TIMEOUT, 1);
30342b15cb3dSCy Schubert 	event_add(ev[3], &ten_sec);
30352b15cb3dSCy Schubert 	/* Don't touch ev[4]. */
30362b15cb3dSCy Schubert 
30372b15cb3dSCy Schubert 	tt_int_op(0, ==, event_base_foreach_event(base, foreach_count_cb,
30382b15cb3dSCy Schubert 		&ten_sec));
30392b15cb3dSCy Schubert 	tt_int_op(1, ==, visited[0].count);
30402b15cb3dSCy Schubert 	tt_int_op(1, ==, visited[1].count);
30412b15cb3dSCy Schubert 	tt_int_op(1, ==, visited[2].count);
30422b15cb3dSCy Schubert 	tt_int_op(1, ==, visited[3].count);
30432b15cb3dSCy Schubert 	tt_ptr_op(ev[0], ==, visited[0].ev);
30442b15cb3dSCy Schubert 	tt_ptr_op(ev[1], ==, visited[1].ev);
30452b15cb3dSCy Schubert 	tt_ptr_op(ev[2], ==, visited[2].ev);
30462b15cb3dSCy Schubert 	tt_ptr_op(ev[3], ==, visited[3].ev);
30472b15cb3dSCy Schubert 
30482b15cb3dSCy Schubert 	visited[2].count = 99;
30492b15cb3dSCy Schubert 	tt_int_op(101, ==, event_base_foreach_event(base, foreach_find_cb,
30502b15cb3dSCy Schubert 		&ev_found));
30512b15cb3dSCy Schubert 	tt_ptr_op(ev_found, ==, ev[2]);
30522b15cb3dSCy Schubert 
30532b15cb3dSCy Schubert end:
30542b15cb3dSCy Schubert 	for (i=0; i<5; ++i) {
30552b15cb3dSCy Schubert 		event_free(ev[i]);
30562b15cb3dSCy Schubert 	}
30572b15cb3dSCy Schubert }
30582b15cb3dSCy Schubert 
30592b15cb3dSCy Schubert static struct event_base *cached_time_base = NULL;
30602b15cb3dSCy Schubert static int cached_time_reset = 0;
30612b15cb3dSCy Schubert static int cached_time_sleep = 0;
30622b15cb3dSCy Schubert static void
30632b15cb3dSCy Schubert cache_time_cb(evutil_socket_t fd, short what, void *arg)
30642b15cb3dSCy Schubert {
30652b15cb3dSCy Schubert 	struct timeval *tv = arg;
30662b15cb3dSCy Schubert 	tt_int_op(0, ==, event_base_gettimeofday_cached(cached_time_base, tv));
30672b15cb3dSCy Schubert 	if (cached_time_sleep) {
30682b15cb3dSCy Schubert 		struct timeval delay = { 0, 30*1000 };
30692b15cb3dSCy Schubert 		evutil_usleep_(&delay);
30702b15cb3dSCy Schubert 	}
30712b15cb3dSCy Schubert 	if (cached_time_reset) {
30722b15cb3dSCy Schubert 		event_base_update_cache_time(cached_time_base);
30732b15cb3dSCy Schubert 	}
30742b15cb3dSCy Schubert end:
30752b15cb3dSCy Schubert 	;
30762b15cb3dSCy Schubert }
30772b15cb3dSCy Schubert 
30782b15cb3dSCy Schubert static void
30792b15cb3dSCy Schubert test_gettimeofday_cached(void *arg)
30802b15cb3dSCy Schubert {
30812b15cb3dSCy Schubert 	struct basic_test_data *data = arg;
30822b15cb3dSCy Schubert 	struct event_config *cfg = NULL;
30832b15cb3dSCy Schubert 	struct event_base *base = NULL;
30842b15cb3dSCy Schubert 	struct timeval tv1, tv2, tv3, now;
30852b15cb3dSCy Schubert 	struct event *ev1=NULL, *ev2=NULL, *ev3=NULL;
30862b15cb3dSCy Schubert 	int cached_time_disable = strstr(data->setup_data, "disable") != NULL;
30872b15cb3dSCy Schubert 
30882b15cb3dSCy Schubert 	cfg = event_config_new();
30892b15cb3dSCy Schubert 	if (cached_time_disable) {
30902b15cb3dSCy Schubert 		event_config_set_flag(cfg, EVENT_BASE_FLAG_NO_CACHE_TIME);
30912b15cb3dSCy Schubert 	}
30922b15cb3dSCy Schubert 	cached_time_base = base = event_base_new_with_config(cfg);
30932b15cb3dSCy Schubert 	tt_assert(base);
30942b15cb3dSCy Schubert 
30952b15cb3dSCy Schubert 	/* Try gettimeofday_cached outside of an event loop. */
30962b15cb3dSCy Schubert 	evutil_gettimeofday(&now, NULL);
30972b15cb3dSCy Schubert 	tt_int_op(0, ==, event_base_gettimeofday_cached(NULL, &tv1));
30982b15cb3dSCy Schubert 	tt_int_op(0, ==, event_base_gettimeofday_cached(base, &tv2));
30992b15cb3dSCy Schubert 	tt_int_op(timeval_msec_diff(&tv1, &tv2), <, 10);
31002b15cb3dSCy Schubert 	tt_int_op(timeval_msec_diff(&tv1, &now), <, 10);
31012b15cb3dSCy Schubert 
31022b15cb3dSCy Schubert 	cached_time_reset = strstr(data->setup_data, "reset") != NULL;
31032b15cb3dSCy Schubert 	cached_time_sleep = strstr(data->setup_data, "sleep") != NULL;
31042b15cb3dSCy Schubert 
31052b15cb3dSCy Schubert 	ev1 = event_new(base, -1, 0, cache_time_cb, &tv1);
31062b15cb3dSCy Schubert 	ev2 = event_new(base, -1, 0, cache_time_cb, &tv2);
31072b15cb3dSCy Schubert 	ev3 = event_new(base, -1, 0, cache_time_cb, &tv3);
31082b15cb3dSCy Schubert 
31092b15cb3dSCy Schubert 	event_active(ev1, EV_TIMEOUT, 1);
31102b15cb3dSCy Schubert 	event_active(ev2, EV_TIMEOUT, 1);
31112b15cb3dSCy Schubert 	event_active(ev3, EV_TIMEOUT, 1);
31122b15cb3dSCy Schubert 
31132b15cb3dSCy Schubert 	event_base_dispatch(base);
31142b15cb3dSCy Schubert 
31152b15cb3dSCy Schubert 	if (cached_time_reset && cached_time_sleep) {
31162b15cb3dSCy Schubert 		tt_int_op(labs(timeval_msec_diff(&tv1,&tv2)), >, 10);
31172b15cb3dSCy Schubert 		tt_int_op(labs(timeval_msec_diff(&tv2,&tv3)), >, 10);
31182b15cb3dSCy Schubert 	} else if (cached_time_disable && cached_time_sleep) {
31192b15cb3dSCy Schubert 		tt_int_op(labs(timeval_msec_diff(&tv1,&tv2)), >, 10);
31202b15cb3dSCy Schubert 		tt_int_op(labs(timeval_msec_diff(&tv2,&tv3)), >, 10);
31212b15cb3dSCy Schubert 	} else if (! cached_time_disable) {
31222b15cb3dSCy Schubert 		tt_assert(evutil_timercmp(&tv1, &tv2, ==));
31232b15cb3dSCy Schubert 		tt_assert(evutil_timercmp(&tv2, &tv3, ==));
31242b15cb3dSCy Schubert 	}
31252b15cb3dSCy Schubert 
31262b15cb3dSCy Schubert end:
31272b15cb3dSCy Schubert 	if (ev1)
31282b15cb3dSCy Schubert 		event_free(ev1);
31292b15cb3dSCy Schubert 	if (ev2)
31302b15cb3dSCy Schubert 		event_free(ev2);
31312b15cb3dSCy Schubert 	if (ev3)
31322b15cb3dSCy Schubert 		event_free(ev3);
31332b15cb3dSCy Schubert 	if (base)
31342b15cb3dSCy Schubert 		event_base_free(base);
31352b15cb3dSCy Schubert 	if (cfg)
31362b15cb3dSCy Schubert 		event_config_free(cfg);
31372b15cb3dSCy Schubert }
31382b15cb3dSCy Schubert 
31392b15cb3dSCy Schubert static void
31402b15cb3dSCy Schubert tabf_cb(evutil_socket_t fd, short what, void *arg)
31412b15cb3dSCy Schubert {
31422b15cb3dSCy Schubert 	int *ptr = arg;
31432b15cb3dSCy Schubert 	*ptr = what;
31442b15cb3dSCy Schubert 	*ptr += 0x10000;
31452b15cb3dSCy Schubert }
31462b15cb3dSCy Schubert 
31472b15cb3dSCy Schubert static void
31482b15cb3dSCy Schubert test_active_by_fd(void *arg)
31492b15cb3dSCy Schubert {
31502b15cb3dSCy Schubert 	struct basic_test_data *data = arg;
31512b15cb3dSCy Schubert 	struct event_base *base = data->base;
31522b15cb3dSCy Schubert 	struct event *ev1 = NULL, *ev2 = NULL, *ev3 = NULL, *ev4 = NULL;
31532b15cb3dSCy Schubert 	int e1,e2,e3,e4;
31542b15cb3dSCy Schubert #ifndef _WIN32
31552b15cb3dSCy Schubert 	struct event *evsig = NULL;
31562b15cb3dSCy Schubert 	int es;
31572b15cb3dSCy Schubert #endif
31582b15cb3dSCy Schubert 	struct timeval tenmin = { 600, 0 };
31592b15cb3dSCy Schubert 
31602b15cb3dSCy Schubert 	/* Ensure no crash on nonexistent FD. */
31612b15cb3dSCy Schubert 	event_base_active_by_fd(base, 1000, EV_READ);
31622b15cb3dSCy Schubert 
31632b15cb3dSCy Schubert 	/* Ensure no crash on bogus FD. */
31642b15cb3dSCy Schubert 	event_base_active_by_fd(base, -1, EV_READ);
31652b15cb3dSCy Schubert 
31662b15cb3dSCy Schubert 	/* Ensure no crash on nonexistent/bogus signal. */
31672b15cb3dSCy Schubert 	event_base_active_by_signal(base, 1000);
31682b15cb3dSCy Schubert 	event_base_active_by_signal(base, -1);
31692b15cb3dSCy Schubert 
31702b15cb3dSCy Schubert 	event_base_assert_ok_(base);
31712b15cb3dSCy Schubert 
31722b15cb3dSCy Schubert 	e1 = e2 = e3 = e4 = 0;
31732b15cb3dSCy Schubert 	ev1 = event_new(base, data->pair[0], EV_READ, tabf_cb, &e1);
31742b15cb3dSCy Schubert 	ev2 = event_new(base, data->pair[0], EV_WRITE, tabf_cb, &e2);
31752b15cb3dSCy Schubert 	ev3 = event_new(base, data->pair[1], EV_READ, tabf_cb, &e3);
31762b15cb3dSCy Schubert 	ev4 = event_new(base, data->pair[1], EV_READ, tabf_cb, &e4);
31772b15cb3dSCy Schubert 	tt_assert(ev1);
31782b15cb3dSCy Schubert 	tt_assert(ev2);
31792b15cb3dSCy Schubert 	tt_assert(ev3);
31802b15cb3dSCy Schubert 	tt_assert(ev4);
31812b15cb3dSCy Schubert #ifndef _WIN32
31822b15cb3dSCy Schubert 	evsig = event_new(base, SIGHUP, EV_SIGNAL, tabf_cb, &es);
31832b15cb3dSCy Schubert 	tt_assert(evsig);
31842b15cb3dSCy Schubert 	event_add(evsig, &tenmin);
31852b15cb3dSCy Schubert #endif
31862b15cb3dSCy Schubert 
31872b15cb3dSCy Schubert 	event_add(ev1, &tenmin);
31882b15cb3dSCy Schubert 	event_add(ev2, NULL);
31892b15cb3dSCy Schubert 	event_add(ev3, NULL);
31902b15cb3dSCy Schubert 	event_add(ev4, &tenmin);
31912b15cb3dSCy Schubert 
31922b15cb3dSCy Schubert 
31932b15cb3dSCy Schubert 	event_base_assert_ok_(base);
31942b15cb3dSCy Schubert 
31952b15cb3dSCy Schubert 	/* Trigger 2, 3, 4 */
31962b15cb3dSCy Schubert 	event_base_active_by_fd(base, data->pair[0], EV_WRITE);
31972b15cb3dSCy Schubert 	event_base_active_by_fd(base, data->pair[1], EV_READ);
31982b15cb3dSCy Schubert #ifndef _WIN32
31992b15cb3dSCy Schubert 	event_base_active_by_signal(base, SIGHUP);
32002b15cb3dSCy Schubert #endif
32012b15cb3dSCy Schubert 
32022b15cb3dSCy Schubert 	event_base_assert_ok_(base);
32032b15cb3dSCy Schubert 
32042b15cb3dSCy Schubert 	event_base_loop(base, EVLOOP_ONCE);
32052b15cb3dSCy Schubert 
32062b15cb3dSCy Schubert 	tt_int_op(e1, ==, 0);
32072b15cb3dSCy Schubert 	tt_int_op(e2, ==, EV_WRITE | 0x10000);
32082b15cb3dSCy Schubert 	tt_int_op(e3, ==, EV_READ | 0x10000);
32092b15cb3dSCy Schubert 	/* Mask out EV_WRITE here, since it could be genuinely writeable. */
32102b15cb3dSCy Schubert 	tt_int_op((e4 & ~EV_WRITE), ==, EV_READ | 0x10000);
32112b15cb3dSCy Schubert #ifndef _WIN32
32122b15cb3dSCy Schubert 	tt_int_op(es, ==, EV_SIGNAL | 0x10000);
32132b15cb3dSCy Schubert #endif
32142b15cb3dSCy Schubert 
32152b15cb3dSCy Schubert end:
32162b15cb3dSCy Schubert 	if (ev1)
32172b15cb3dSCy Schubert 		event_free(ev1);
32182b15cb3dSCy Schubert 	if (ev2)
32192b15cb3dSCy Schubert 		event_free(ev2);
32202b15cb3dSCy Schubert 	if (ev3)
32212b15cb3dSCy Schubert 		event_free(ev3);
32222b15cb3dSCy Schubert 	if (ev4)
32232b15cb3dSCy Schubert 		event_free(ev4);
32242b15cb3dSCy Schubert #ifndef _WIN32
32252b15cb3dSCy Schubert 	if (evsig)
32262b15cb3dSCy Schubert 		event_free(evsig);
32272b15cb3dSCy Schubert #endif
32282b15cb3dSCy Schubert }
32292b15cb3dSCy Schubert 
32302b15cb3dSCy Schubert struct testcase_t main_testcases[] = {
32312b15cb3dSCy Schubert 	/* Some converted-over tests */
32322b15cb3dSCy Schubert 	{ "methods", test_methods, TT_FORK, NULL, NULL },
32332b15cb3dSCy Schubert 	{ "version", test_version, 0, NULL, NULL },
32342b15cb3dSCy Schubert 	BASIC(base_features, TT_FORK|TT_NO_LOGS),
32352b15cb3dSCy Schubert 	{ "base_environ", test_base_environ, TT_FORK, NULL, NULL },
32362b15cb3dSCy Schubert 
32372b15cb3dSCy Schubert 	BASIC(event_base_new, TT_FORK|TT_NEED_SOCKETPAIR),
32382b15cb3dSCy Schubert 	BASIC(free_active_base, TT_FORK|TT_NEED_SOCKETPAIR),
32392b15cb3dSCy Schubert 
32402b15cb3dSCy Schubert 	BASIC(manipulate_active_events, TT_FORK|TT_NEED_BASE),
32412b15cb3dSCy Schubert 	BASIC(event_new_selfarg, TT_FORK|TT_NEED_BASE),
32422b15cb3dSCy Schubert 	BASIC(event_assign_selfarg, TT_FORK|TT_NEED_BASE),
32432b15cb3dSCy Schubert 	BASIC(event_base_get_num_events, TT_FORK|TT_NEED_BASE),
32442b15cb3dSCy Schubert 	BASIC(event_base_get_max_events, TT_FORK|TT_NEED_BASE),
32452b15cb3dSCy Schubert 
32462b15cb3dSCy Schubert 	BASIC(bad_assign, TT_FORK|TT_NEED_BASE|TT_NO_LOGS),
32472b15cb3dSCy Schubert 	BASIC(bad_reentrant, TT_FORK|TT_NEED_BASE|TT_NO_LOGS),
32482b15cb3dSCy Schubert 	BASIC(active_later, TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR),
32492b15cb3dSCy Schubert 	BASIC(event_remove_timeout, TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR),
32502b15cb3dSCy Schubert 
32512b15cb3dSCy Schubert 	/* These are still using the old API */
32522b15cb3dSCy Schubert 	LEGACY(persistent_timeout, TT_FORK|TT_NEED_BASE),
32532b15cb3dSCy Schubert 	{ "persistent_timeout_jump", test_persistent_timeout_jump, TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
32542b15cb3dSCy Schubert 	{ "persistent_active_timeout", test_persistent_active_timeout,
32552b15cb3dSCy Schubert 	  TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
32562b15cb3dSCy Schubert 	LEGACY(priorities, TT_FORK|TT_NEED_BASE),
32572b15cb3dSCy Schubert 	BASIC(priority_active_inversion, TT_FORK|TT_NEED_BASE),
32582b15cb3dSCy Schubert 	{ "common_timeout", test_common_timeout, TT_FORK|TT_NEED_BASE,
32592b15cb3dSCy Schubert 	  &basic_setup, NULL },
32602b15cb3dSCy Schubert 
32612b15cb3dSCy Schubert 	/* These legacy tests may not all need all of these flags. */
32622b15cb3dSCy Schubert 	LEGACY(simpleread, TT_ISOLATED),
32632b15cb3dSCy Schubert 	LEGACY(simpleread_multiple, TT_ISOLATED),
32642b15cb3dSCy Schubert 	LEGACY(simplewrite, TT_ISOLATED),
32652b15cb3dSCy Schubert 	{ "simpleclose", test_simpleclose, TT_FORK, &basic_setup,
32662b15cb3dSCy Schubert 	  NULL },
32672b15cb3dSCy Schubert 	LEGACY(multiple, TT_ISOLATED),
32682b15cb3dSCy Schubert 	LEGACY(persistent, TT_ISOLATED),
32692b15cb3dSCy Schubert 	LEGACY(combined, TT_ISOLATED),
32702b15cb3dSCy Schubert 	LEGACY(simpletimeout, TT_ISOLATED),
32712b15cb3dSCy Schubert 	LEGACY(loopbreak, TT_ISOLATED),
32722b15cb3dSCy Schubert 	LEGACY(loopexit, TT_ISOLATED),
32732b15cb3dSCy Schubert 	LEGACY(loopexit_multiple, TT_ISOLATED),
32742b15cb3dSCy Schubert 	LEGACY(nonpersist_readd, TT_ISOLATED),
32752b15cb3dSCy Schubert 	LEGACY(multiple_events_for_same_fd, TT_ISOLATED),
32762b15cb3dSCy Schubert 	LEGACY(want_only_once, TT_ISOLATED),
32772b15cb3dSCy Schubert 	{ "event_once", test_event_once, TT_ISOLATED, &basic_setup, NULL },
32782b15cb3dSCy Schubert 	{ "event_once_never", test_event_once_never, TT_ISOLATED, &basic_setup, NULL },
32792b15cb3dSCy Schubert 	{ "event_pending", test_event_pending, TT_ISOLATED, &basic_setup,
32802b15cb3dSCy Schubert 	  NULL },
32812b15cb3dSCy Schubert #ifndef _WIN32
32822b15cb3dSCy Schubert 	{ "dup_fd", test_dup_fd, TT_ISOLATED, &basic_setup, NULL },
32832b15cb3dSCy Schubert #endif
32842b15cb3dSCy Schubert 	{ "mm_functions", test_mm_functions, TT_FORK, NULL, NULL },
32852b15cb3dSCy Schubert 	{ "many_events", test_many_events, TT_ISOLATED, &basic_setup, NULL },
32862b15cb3dSCy Schubert 	{ "many_events_slow_add", test_many_events, TT_ISOLATED, &basic_setup, (void*)1 },
32872b15cb3dSCy Schubert 
32882b15cb3dSCy Schubert 	{ "struct_event_size", test_struct_event_size, 0, NULL, NULL },
32892b15cb3dSCy Schubert 	BASIC(get_assignment, TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR),
32902b15cb3dSCy Schubert 
32912b15cb3dSCy Schubert 	BASIC(event_foreach, TT_FORK|TT_NEED_BASE),
32922b15cb3dSCy Schubert 	{ "gettimeofday_cached", test_gettimeofday_cached, TT_FORK, &basic_setup, (void*)"" },
32932b15cb3dSCy Schubert 	{ "gettimeofday_cached_sleep", test_gettimeofday_cached, TT_FORK, &basic_setup, (void*)"sleep" },
32942b15cb3dSCy Schubert 	{ "gettimeofday_cached_reset", test_gettimeofday_cached, TT_FORK, &basic_setup, (void*)"sleep reset" },
32952b15cb3dSCy Schubert 	{ "gettimeofday_cached_disabled", test_gettimeofday_cached, TT_FORK, &basic_setup, (void*)"sleep disable" },
32962b15cb3dSCy Schubert 	{ "gettimeofday_cached_disabled_nosleep", test_gettimeofday_cached, TT_FORK, &basic_setup, (void*)"disable" },
32972b15cb3dSCy Schubert 
32982b15cb3dSCy Schubert 	BASIC(active_by_fd, TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR),
32992b15cb3dSCy Schubert 
33002b15cb3dSCy Schubert #ifndef _WIN32
33012b15cb3dSCy Schubert 	LEGACY(fork, TT_ISOLATED),
33022b15cb3dSCy Schubert #endif
33032b15cb3dSCy Schubert 	END_OF_TESTCASES
33042b15cb3dSCy Schubert };
33052b15cb3dSCy Schubert 
33062b15cb3dSCy Schubert struct testcase_t evtag_testcases[] = {
33072b15cb3dSCy Schubert 	{ "int", evtag_int_test, TT_FORK, NULL, NULL },
33082b15cb3dSCy Schubert 	{ "fuzz", evtag_fuzz, TT_FORK, NULL, NULL },
33092b15cb3dSCy Schubert 	{ "encoding", evtag_tag_encoding, TT_FORK, NULL, NULL },
33102b15cb3dSCy Schubert 	{ "peek", evtag_test_peek, 0, NULL, NULL },
33112b15cb3dSCy Schubert 
33122b15cb3dSCy Schubert 	END_OF_TESTCASES
33132b15cb3dSCy Schubert };
33142b15cb3dSCy Schubert 
33152b15cb3dSCy Schubert struct testcase_t signal_testcases[] = {
33162b15cb3dSCy Schubert #ifndef _WIN32
3317*a25439b6SCy Schubert 	LEGACY(simplestsignal, TT_ISOLATED),
33182b15cb3dSCy Schubert 	LEGACY(simplesignal, TT_ISOLATED),
33192b15cb3dSCy Schubert 	LEGACY(multiplesignal, TT_ISOLATED),
33202b15cb3dSCy Schubert 	LEGACY(immediatesignal, TT_ISOLATED),
33212b15cb3dSCy Schubert 	LEGACY(signal_dealloc, TT_ISOLATED),
33222b15cb3dSCy Schubert 	LEGACY(signal_pipeloss, TT_ISOLATED),
33232b15cb3dSCy Schubert 	LEGACY(signal_switchbase, TT_ISOLATED|TT_NO_LOGS),
33242b15cb3dSCy Schubert 	LEGACY(signal_restore, TT_ISOLATED),
33252b15cb3dSCy Schubert 	LEGACY(signal_assert, TT_ISOLATED),
33262b15cb3dSCy Schubert 	LEGACY(signal_while_processing, TT_ISOLATED),
33272b15cb3dSCy Schubert #endif
33282b15cb3dSCy Schubert 	END_OF_TESTCASES
33292b15cb3dSCy Schubert };
33302b15cb3dSCy Schubert 
3331