xref: /freebsd/contrib/libevent/test/regress.c (revision c43e99fd14c915adcb7173dd49c31e803ceadfe0)
1*c43e99fdSEd Maste /*
2*c43e99fdSEd Maste  * Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu>
3*c43e99fdSEd Maste  * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
4*c43e99fdSEd Maste  *
5*c43e99fdSEd Maste  * Redistribution and use in source and binary forms, with or without
6*c43e99fdSEd Maste  * modification, are permitted provided that the following conditions
7*c43e99fdSEd Maste  * are met:
8*c43e99fdSEd Maste  * 1. Redistributions of source code must retain the above copyright
9*c43e99fdSEd Maste  *    notice, this list of conditions and the following disclaimer.
10*c43e99fdSEd Maste  * 2. Redistributions in binary form must reproduce the above copyright
11*c43e99fdSEd Maste  *    notice, this list of conditions and the following disclaimer in the
12*c43e99fdSEd Maste  *    documentation and/or other materials provided with the distribution.
13*c43e99fdSEd Maste  * 3. The name of the author may not be used to endorse or promote products
14*c43e99fdSEd Maste  *    derived from this software without specific prior written permission.
15*c43e99fdSEd Maste  *
16*c43e99fdSEd Maste  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17*c43e99fdSEd Maste  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18*c43e99fdSEd Maste  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19*c43e99fdSEd Maste  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20*c43e99fdSEd Maste  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21*c43e99fdSEd Maste  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22*c43e99fdSEd Maste  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23*c43e99fdSEd Maste  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24*c43e99fdSEd Maste  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25*c43e99fdSEd Maste  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*c43e99fdSEd Maste  */
27*c43e99fdSEd Maste #include "util-internal.h"
28*c43e99fdSEd Maste 
29*c43e99fdSEd Maste #ifdef _WIN32
30*c43e99fdSEd Maste #include <winsock2.h>
31*c43e99fdSEd Maste #include <windows.h>
32*c43e99fdSEd Maste #endif
33*c43e99fdSEd Maste 
34*c43e99fdSEd Maste #ifdef EVENT__HAVE_PTHREADS
35*c43e99fdSEd Maste #include <pthread.h>
36*c43e99fdSEd Maste #endif
37*c43e99fdSEd Maste 
38*c43e99fdSEd Maste #include "event2/event-config.h"
39*c43e99fdSEd Maste 
40*c43e99fdSEd Maste #include <sys/types.h>
41*c43e99fdSEd Maste #include <sys/stat.h>
42*c43e99fdSEd Maste #ifdef EVENT__HAVE_SYS_TIME_H
43*c43e99fdSEd Maste #include <sys/time.h>
44*c43e99fdSEd Maste #endif
45*c43e99fdSEd Maste #include <sys/queue.h>
46*c43e99fdSEd Maste #ifndef _WIN32
47*c43e99fdSEd Maste #include <sys/socket.h>
48*c43e99fdSEd Maste #include <sys/wait.h>
49*c43e99fdSEd Maste #include <signal.h>
50*c43e99fdSEd Maste #include <unistd.h>
51*c43e99fdSEd Maste #include <netdb.h>
52*c43e99fdSEd Maste #endif
53*c43e99fdSEd Maste #include <fcntl.h>
54*c43e99fdSEd Maste #include <signal.h>
55*c43e99fdSEd Maste #include <stdlib.h>
56*c43e99fdSEd Maste #include <stdio.h>
57*c43e99fdSEd Maste #include <string.h>
58*c43e99fdSEd Maste #include <errno.h>
59*c43e99fdSEd Maste #include <assert.h>
60*c43e99fdSEd Maste #include <ctype.h>
61*c43e99fdSEd Maste 
62*c43e99fdSEd Maste #include "event2/event.h"
63*c43e99fdSEd Maste #include "event2/event_struct.h"
64*c43e99fdSEd Maste #include "event2/event_compat.h"
65*c43e99fdSEd Maste #include "event2/tag.h"
66*c43e99fdSEd Maste #include "event2/buffer.h"
67*c43e99fdSEd Maste #include "event2/buffer_compat.h"
68*c43e99fdSEd Maste #include "event2/util.h"
69*c43e99fdSEd Maste #include "event-internal.h"
70*c43e99fdSEd Maste #include "evthread-internal.h"
71*c43e99fdSEd Maste #include "log-internal.h"
72*c43e99fdSEd Maste #include "time-internal.h"
73*c43e99fdSEd Maste 
74*c43e99fdSEd Maste #include "regress.h"
75*c43e99fdSEd Maste 
76*c43e99fdSEd Maste #ifndef _WIN32
77*c43e99fdSEd Maste #include "regress.gen.h"
78*c43e99fdSEd Maste #endif
79*c43e99fdSEd Maste 
80*c43e99fdSEd Maste evutil_socket_t pair[2];
81*c43e99fdSEd Maste int test_ok;
82*c43e99fdSEd Maste int called;
83*c43e99fdSEd Maste struct event_base *global_base;
84*c43e99fdSEd Maste 
85*c43e99fdSEd Maste static char wbuf[4096];
86*c43e99fdSEd Maste static char rbuf[4096];
87*c43e99fdSEd Maste static int woff;
88*c43e99fdSEd Maste static int roff;
89*c43e99fdSEd Maste static int usepersist;
90*c43e99fdSEd Maste static struct timeval tset;
91*c43e99fdSEd Maste static struct timeval tcalled;
92*c43e99fdSEd Maste 
93*c43e99fdSEd Maste 
94*c43e99fdSEd Maste #define TEST1	"this is a test"
95*c43e99fdSEd Maste 
96*c43e99fdSEd Maste #ifdef _WIN32
97*c43e99fdSEd Maste #define write(fd,buf,len) send((fd),(buf),(int)(len),0)
98*c43e99fdSEd Maste #define read(fd,buf,len) recv((fd),(buf),(int)(len),0)
99*c43e99fdSEd Maste #endif
100*c43e99fdSEd Maste 
101*c43e99fdSEd Maste struct basic_cb_args
102*c43e99fdSEd Maste {
103*c43e99fdSEd Maste 	struct event_base *eb;
104*c43e99fdSEd Maste 	struct event *ev;
105*c43e99fdSEd Maste 	unsigned int callcount;
106*c43e99fdSEd Maste };
107*c43e99fdSEd Maste 
108*c43e99fdSEd Maste static void
109*c43e99fdSEd Maste simple_read_cb(evutil_socket_t fd, short event, void *arg)
110*c43e99fdSEd Maste {
111*c43e99fdSEd Maste 	char buf[256];
112*c43e99fdSEd Maste 	int len;
113*c43e99fdSEd Maste 
114*c43e99fdSEd Maste 	len = read(fd, buf, sizeof(buf));
115*c43e99fdSEd Maste 
116*c43e99fdSEd Maste 	if (len) {
117*c43e99fdSEd Maste 		if (!called) {
118*c43e99fdSEd Maste 			if (event_add(arg, NULL) == -1)
119*c43e99fdSEd Maste 				exit(1);
120*c43e99fdSEd Maste 		}
121*c43e99fdSEd Maste 	} else if (called == 1)
122*c43e99fdSEd Maste 		test_ok = 1;
123*c43e99fdSEd Maste 
124*c43e99fdSEd Maste 	called++;
125*c43e99fdSEd Maste }
126*c43e99fdSEd Maste 
127*c43e99fdSEd Maste static void
128*c43e99fdSEd Maste basic_read_cb(evutil_socket_t fd, short event, void *data)
129*c43e99fdSEd Maste {
130*c43e99fdSEd Maste 	char buf[256];
131*c43e99fdSEd Maste 	int len;
132*c43e99fdSEd Maste 	struct basic_cb_args *arg = data;
133*c43e99fdSEd Maste 
134*c43e99fdSEd Maste 	len = read(fd, buf, sizeof(buf));
135*c43e99fdSEd Maste 
136*c43e99fdSEd Maste 	if (len < 0) {
137*c43e99fdSEd Maste 		tt_fail_perror("read (callback)");
138*c43e99fdSEd Maste 	} else {
139*c43e99fdSEd Maste 		switch (arg->callcount++) {
140*c43e99fdSEd Maste 		case 0:	 /* first call: expect to read data; cycle */
141*c43e99fdSEd Maste 			if (len > 0)
142*c43e99fdSEd Maste 				return;
143*c43e99fdSEd Maste 
144*c43e99fdSEd Maste 			tt_fail_msg("EOF before data read");
145*c43e99fdSEd Maste 			break;
146*c43e99fdSEd Maste 
147*c43e99fdSEd Maste 		case 1:	 /* second call: expect EOF; stop */
148*c43e99fdSEd Maste 			if (len > 0)
149*c43e99fdSEd Maste 				tt_fail_msg("not all data read on first cycle");
150*c43e99fdSEd Maste 			break;
151*c43e99fdSEd Maste 
152*c43e99fdSEd Maste 		default:  /* third call: should not happen */
153*c43e99fdSEd Maste 			tt_fail_msg("too many cycles");
154*c43e99fdSEd Maste 		}
155*c43e99fdSEd Maste 	}
156*c43e99fdSEd Maste 
157*c43e99fdSEd Maste 	event_del(arg->ev);
158*c43e99fdSEd Maste 	event_base_loopexit(arg->eb, NULL);
159*c43e99fdSEd Maste }
160*c43e99fdSEd Maste 
161*c43e99fdSEd Maste static void
162*c43e99fdSEd Maste dummy_read_cb(evutil_socket_t fd, short event, void *arg)
163*c43e99fdSEd Maste {
164*c43e99fdSEd Maste }
165*c43e99fdSEd Maste 
166*c43e99fdSEd Maste static void
167*c43e99fdSEd Maste simple_write_cb(evutil_socket_t fd, short event, void *arg)
168*c43e99fdSEd Maste {
169*c43e99fdSEd Maste 	int len;
170*c43e99fdSEd Maste 
171*c43e99fdSEd Maste 	len = write(fd, TEST1, strlen(TEST1) + 1);
172*c43e99fdSEd Maste 	if (len == -1)
173*c43e99fdSEd Maste 		test_ok = 0;
174*c43e99fdSEd Maste 	else
175*c43e99fdSEd Maste 		test_ok = 1;
176*c43e99fdSEd Maste }
177*c43e99fdSEd Maste 
178*c43e99fdSEd Maste static void
179*c43e99fdSEd Maste multiple_write_cb(evutil_socket_t fd, short event, void *arg)
180*c43e99fdSEd Maste {
181*c43e99fdSEd Maste 	struct event *ev = arg;
182*c43e99fdSEd Maste 	int len;
183*c43e99fdSEd Maste 
184*c43e99fdSEd Maste 	len = 128;
185*c43e99fdSEd Maste 	if (woff + len >= (int)sizeof(wbuf))
186*c43e99fdSEd Maste 		len = sizeof(wbuf) - woff;
187*c43e99fdSEd Maste 
188*c43e99fdSEd Maste 	len = write(fd, wbuf + woff, len);
189*c43e99fdSEd Maste 	if (len == -1) {
190*c43e99fdSEd Maste 		fprintf(stderr, "%s: write\n", __func__);
191*c43e99fdSEd Maste 		if (usepersist)
192*c43e99fdSEd Maste 			event_del(ev);
193*c43e99fdSEd Maste 		return;
194*c43e99fdSEd Maste 	}
195*c43e99fdSEd Maste 
196*c43e99fdSEd Maste 	woff += len;
197*c43e99fdSEd Maste 
198*c43e99fdSEd Maste 	if (woff >= (int)sizeof(wbuf)) {
199*c43e99fdSEd Maste 		shutdown(fd, EVUTIL_SHUT_WR);
200*c43e99fdSEd Maste 		if (usepersist)
201*c43e99fdSEd Maste 			event_del(ev);
202*c43e99fdSEd Maste 		return;
203*c43e99fdSEd Maste 	}
204*c43e99fdSEd Maste 
205*c43e99fdSEd Maste 	if (!usepersist) {
206*c43e99fdSEd Maste 		if (event_add(ev, NULL) == -1)
207*c43e99fdSEd Maste 			exit(1);
208*c43e99fdSEd Maste 	}
209*c43e99fdSEd Maste }
210*c43e99fdSEd Maste 
211*c43e99fdSEd Maste static void
212*c43e99fdSEd Maste multiple_read_cb(evutil_socket_t fd, short event, void *arg)
213*c43e99fdSEd Maste {
214*c43e99fdSEd Maste 	struct event *ev = arg;
215*c43e99fdSEd Maste 	int len;
216*c43e99fdSEd Maste 
217*c43e99fdSEd Maste 	len = read(fd, rbuf + roff, sizeof(rbuf) - roff);
218*c43e99fdSEd Maste 	if (len == -1)
219*c43e99fdSEd Maste 		fprintf(stderr, "%s: read\n", __func__);
220*c43e99fdSEd Maste 	if (len <= 0) {
221*c43e99fdSEd Maste 		if (usepersist)
222*c43e99fdSEd Maste 			event_del(ev);
223*c43e99fdSEd Maste 		return;
224*c43e99fdSEd Maste 	}
225*c43e99fdSEd Maste 
226*c43e99fdSEd Maste 	roff += len;
227*c43e99fdSEd Maste 	if (!usepersist) {
228*c43e99fdSEd Maste 		if (event_add(ev, NULL) == -1)
229*c43e99fdSEd Maste 			exit(1);
230*c43e99fdSEd Maste 	}
231*c43e99fdSEd Maste }
232*c43e99fdSEd Maste 
233*c43e99fdSEd Maste static void
234*c43e99fdSEd Maste timeout_cb(evutil_socket_t fd, short event, void *arg)
235*c43e99fdSEd Maste {
236*c43e99fdSEd Maste 	evutil_gettimeofday(&tcalled, NULL);
237*c43e99fdSEd Maste }
238*c43e99fdSEd Maste 
239*c43e99fdSEd Maste struct both {
240*c43e99fdSEd Maste 	struct event ev;
241*c43e99fdSEd Maste 	int nread;
242*c43e99fdSEd Maste };
243*c43e99fdSEd Maste 
244*c43e99fdSEd Maste static void
245*c43e99fdSEd Maste combined_read_cb(evutil_socket_t fd, short event, void *arg)
246*c43e99fdSEd Maste {
247*c43e99fdSEd Maste 	struct both *both = arg;
248*c43e99fdSEd Maste 	char buf[128];
249*c43e99fdSEd Maste 	int len;
250*c43e99fdSEd Maste 
251*c43e99fdSEd Maste 	len = read(fd, buf, sizeof(buf));
252*c43e99fdSEd Maste 	if (len == -1)
253*c43e99fdSEd Maste 		fprintf(stderr, "%s: read\n", __func__);
254*c43e99fdSEd Maste 	if (len <= 0)
255*c43e99fdSEd Maste 		return;
256*c43e99fdSEd Maste 
257*c43e99fdSEd Maste 	both->nread += len;
258*c43e99fdSEd Maste 	if (event_add(&both->ev, NULL) == -1)
259*c43e99fdSEd Maste 		exit(1);
260*c43e99fdSEd Maste }
261*c43e99fdSEd Maste 
262*c43e99fdSEd Maste static void
263*c43e99fdSEd Maste combined_write_cb(evutil_socket_t fd, short event, void *arg)
264*c43e99fdSEd Maste {
265*c43e99fdSEd Maste 	struct both *both = arg;
266*c43e99fdSEd Maste 	char buf[128];
267*c43e99fdSEd Maste 	int len;
268*c43e99fdSEd Maste 
269*c43e99fdSEd Maste 	len = sizeof(buf);
270*c43e99fdSEd Maste 	if (len > both->nread)
271*c43e99fdSEd Maste 		len = both->nread;
272*c43e99fdSEd Maste 
273*c43e99fdSEd Maste 	memset(buf, 'q', len);
274*c43e99fdSEd Maste 
275*c43e99fdSEd Maste 	len = write(fd, buf, len);
276*c43e99fdSEd Maste 	if (len == -1)
277*c43e99fdSEd Maste 		fprintf(stderr, "%s: write\n", __func__);
278*c43e99fdSEd Maste 	if (len <= 0) {
279*c43e99fdSEd Maste 		shutdown(fd, EVUTIL_SHUT_WR);
280*c43e99fdSEd Maste 		return;
281*c43e99fdSEd Maste 	}
282*c43e99fdSEd Maste 
283*c43e99fdSEd Maste 	both->nread -= len;
284*c43e99fdSEd Maste 	if (event_add(&both->ev, NULL) == -1)
285*c43e99fdSEd Maste 		exit(1);
286*c43e99fdSEd Maste }
287*c43e99fdSEd Maste 
288*c43e99fdSEd Maste /* These macros used to replicate the work of the legacy test wrapper code */
289*c43e99fdSEd Maste #define setup_test(x) do {						\
290*c43e99fdSEd Maste 	if (!in_legacy_test_wrapper) {					\
291*c43e99fdSEd Maste 		TT_FAIL(("Legacy test %s not wrapped properly", x));	\
292*c43e99fdSEd Maste 		return;							\
293*c43e99fdSEd Maste 	}								\
294*c43e99fdSEd Maste 	} while (0)
295*c43e99fdSEd Maste #define cleanup_test() setup_test("cleanup")
296*c43e99fdSEd Maste 
297*c43e99fdSEd Maste static void
298*c43e99fdSEd Maste test_simpleread(void)
299*c43e99fdSEd Maste {
300*c43e99fdSEd Maste 	struct event ev;
301*c43e99fdSEd Maste 
302*c43e99fdSEd Maste 	/* Very simple read test */
303*c43e99fdSEd Maste 	setup_test("Simple read: ");
304*c43e99fdSEd Maste 
305*c43e99fdSEd Maste 	if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) {
306*c43e99fdSEd Maste 		tt_fail_perror("write");
307*c43e99fdSEd Maste 	}
308*c43e99fdSEd Maste 
309*c43e99fdSEd Maste 	shutdown(pair[0], EVUTIL_SHUT_WR);
310*c43e99fdSEd Maste 
311*c43e99fdSEd Maste 	event_set(&ev, pair[1], EV_READ, simple_read_cb, &ev);
312*c43e99fdSEd Maste 	if (event_add(&ev, NULL) == -1)
313*c43e99fdSEd Maste 		exit(1);
314*c43e99fdSEd Maste 	event_dispatch();
315*c43e99fdSEd Maste 
316*c43e99fdSEd Maste 	cleanup_test();
317*c43e99fdSEd Maste }
318*c43e99fdSEd Maste 
319*c43e99fdSEd Maste static void
320*c43e99fdSEd Maste test_simplewrite(void)
321*c43e99fdSEd Maste {
322*c43e99fdSEd Maste 	struct event ev;
323*c43e99fdSEd Maste 
324*c43e99fdSEd Maste 	/* Very simple write test */
325*c43e99fdSEd Maste 	setup_test("Simple write: ");
326*c43e99fdSEd Maste 
327*c43e99fdSEd Maste 	event_set(&ev, pair[0], EV_WRITE, simple_write_cb, &ev);
328*c43e99fdSEd Maste 	if (event_add(&ev, NULL) == -1)
329*c43e99fdSEd Maste 		exit(1);
330*c43e99fdSEd Maste 	event_dispatch();
331*c43e99fdSEd Maste 
332*c43e99fdSEd Maste 	cleanup_test();
333*c43e99fdSEd Maste }
334*c43e99fdSEd Maste 
335*c43e99fdSEd Maste static void
336*c43e99fdSEd Maste simpleread_multiple_cb(evutil_socket_t fd, short event, void *arg)
337*c43e99fdSEd Maste {
338*c43e99fdSEd Maste 	if (++called == 2)
339*c43e99fdSEd Maste 		test_ok = 1;
340*c43e99fdSEd Maste }
341*c43e99fdSEd Maste 
342*c43e99fdSEd Maste static void
343*c43e99fdSEd Maste test_simpleread_multiple(void)
344*c43e99fdSEd Maste {
345*c43e99fdSEd Maste 	struct event one, two;
346*c43e99fdSEd Maste 
347*c43e99fdSEd Maste 	/* Very simple read test */
348*c43e99fdSEd Maste 	setup_test("Simple read to multiple evens: ");
349*c43e99fdSEd Maste 
350*c43e99fdSEd Maste 	if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) {
351*c43e99fdSEd Maste 		tt_fail_perror("write");
352*c43e99fdSEd Maste 	}
353*c43e99fdSEd Maste 
354*c43e99fdSEd Maste 	shutdown(pair[0], EVUTIL_SHUT_WR);
355*c43e99fdSEd Maste 
356*c43e99fdSEd Maste 	event_set(&one, pair[1], EV_READ, simpleread_multiple_cb, NULL);
357*c43e99fdSEd Maste 	if (event_add(&one, NULL) == -1)
358*c43e99fdSEd Maste 		exit(1);
359*c43e99fdSEd Maste 	event_set(&two, pair[1], EV_READ, simpleread_multiple_cb, NULL);
360*c43e99fdSEd Maste 	if (event_add(&two, NULL) == -1)
361*c43e99fdSEd Maste 		exit(1);
362*c43e99fdSEd Maste 	event_dispatch();
363*c43e99fdSEd Maste 
364*c43e99fdSEd Maste 	cleanup_test();
365*c43e99fdSEd Maste }
366*c43e99fdSEd Maste 
367*c43e99fdSEd Maste static int have_closed = 0;
368*c43e99fdSEd Maste static int premature_event = 0;
369*c43e99fdSEd Maste static void
370*c43e99fdSEd Maste simpleclose_close_fd_cb(evutil_socket_t s, short what, void *ptr)
371*c43e99fdSEd Maste {
372*c43e99fdSEd Maste 	evutil_socket_t **fds = ptr;
373*c43e99fdSEd Maste 	TT_BLATHER(("Closing"));
374*c43e99fdSEd Maste 	evutil_closesocket(*fds[0]);
375*c43e99fdSEd Maste 	evutil_closesocket(*fds[1]);
376*c43e99fdSEd Maste 	*fds[0] = -1;
377*c43e99fdSEd Maste 	*fds[1] = -1;
378*c43e99fdSEd Maste 	have_closed = 1;
379*c43e99fdSEd Maste }
380*c43e99fdSEd Maste 
381*c43e99fdSEd Maste static void
382*c43e99fdSEd Maste record_event_cb(evutil_socket_t s, short what, void *ptr)
383*c43e99fdSEd Maste {
384*c43e99fdSEd Maste 	short *whatp = ptr;
385*c43e99fdSEd Maste 	if (!have_closed)
386*c43e99fdSEd Maste 		premature_event = 1;
387*c43e99fdSEd Maste 	*whatp = what;
388*c43e99fdSEd Maste 	TT_BLATHER(("Recorded %d on socket %d", (int)what, (int)s));
389*c43e99fdSEd Maste }
390*c43e99fdSEd Maste 
391*c43e99fdSEd Maste static void
392*c43e99fdSEd Maste test_simpleclose(void *ptr)
393*c43e99fdSEd Maste {
394*c43e99fdSEd Maste 	/* Test that a close of FD is detected as a read and as a write. */
395*c43e99fdSEd Maste 	struct event_base *base = event_base_new();
396*c43e99fdSEd Maste 	evutil_socket_t pair1[2]={-1,-1}, pair2[2] = {-1, -1};
397*c43e99fdSEd Maste 	evutil_socket_t *to_close[2];
398*c43e99fdSEd Maste 	struct event *rev=NULL, *wev=NULL, *closeev=NULL;
399*c43e99fdSEd Maste 	struct timeval tv;
400*c43e99fdSEd Maste 	short got_read_on_close = 0, got_write_on_close = 0;
401*c43e99fdSEd Maste 	char buf[1024];
402*c43e99fdSEd Maste 	memset(buf, 99, sizeof(buf));
403*c43e99fdSEd Maste #ifdef _WIN32
404*c43e99fdSEd Maste #define LOCAL_SOCKETPAIR_AF AF_INET
405*c43e99fdSEd Maste #else
406*c43e99fdSEd Maste #define LOCAL_SOCKETPAIR_AF AF_UNIX
407*c43e99fdSEd Maste #endif
408*c43e99fdSEd Maste 	if (evutil_socketpair(LOCAL_SOCKETPAIR_AF, SOCK_STREAM, 0, pair1)<0)
409*c43e99fdSEd Maste 		TT_DIE(("socketpair: %s", strerror(errno)));
410*c43e99fdSEd Maste 	if (evutil_socketpair(LOCAL_SOCKETPAIR_AF, SOCK_STREAM, 0, pair2)<0)
411*c43e99fdSEd Maste 		TT_DIE(("socketpair: %s", strerror(errno)));
412*c43e99fdSEd Maste 	if (evutil_make_socket_nonblocking(pair1[1]) < 0)
413*c43e99fdSEd Maste 		TT_DIE(("make_socket_nonblocking"));
414*c43e99fdSEd Maste 	if (evutil_make_socket_nonblocking(pair2[1]) < 0)
415*c43e99fdSEd Maste 		TT_DIE(("make_socket_nonblocking"));
416*c43e99fdSEd Maste 
417*c43e99fdSEd Maste 	/** Stuff pair2[1] full of data, until write fails */
418*c43e99fdSEd Maste 	while (1) {
419*c43e99fdSEd Maste 		int r = write(pair2[1], buf, sizeof(buf));
420*c43e99fdSEd Maste 		if (r<0) {
421*c43e99fdSEd Maste 			int err = evutil_socket_geterror(pair2[1]);
422*c43e99fdSEd Maste 			if (! EVUTIL_ERR_RW_RETRIABLE(err))
423*c43e99fdSEd Maste 				TT_DIE(("write failed strangely: %s",
424*c43e99fdSEd Maste 					evutil_socket_error_to_string(err)));
425*c43e99fdSEd Maste 			break;
426*c43e99fdSEd Maste 		}
427*c43e99fdSEd Maste 	}
428*c43e99fdSEd Maste 	to_close[0] = &pair1[0];
429*c43e99fdSEd Maste 	to_close[1] = &pair2[0];
430*c43e99fdSEd Maste 
431*c43e99fdSEd Maste 	closeev = event_new(base, -1, EV_TIMEOUT, simpleclose_close_fd_cb,
432*c43e99fdSEd Maste 	    to_close);
433*c43e99fdSEd Maste 	rev = event_new(base, pair1[1], EV_READ, record_event_cb,
434*c43e99fdSEd Maste 	    &got_read_on_close);
435*c43e99fdSEd Maste 	TT_BLATHER(("Waiting for read on %d", (int)pair1[1]));
436*c43e99fdSEd Maste 	wev = event_new(base, pair2[1], EV_WRITE, record_event_cb,
437*c43e99fdSEd Maste 	    &got_write_on_close);
438*c43e99fdSEd Maste 	TT_BLATHER(("Waiting for write on %d", (int)pair2[1]));
439*c43e99fdSEd Maste 	tv.tv_sec = 0;
440*c43e99fdSEd Maste 	tv.tv_usec = 100*1000; /* Close pair1[0] after a little while, and make
441*c43e99fdSEd Maste 			       * sure we get a read event. */
442*c43e99fdSEd Maste 	event_add(closeev, &tv);
443*c43e99fdSEd Maste 	event_add(rev, NULL);
444*c43e99fdSEd Maste 	event_add(wev, NULL);
445*c43e99fdSEd Maste 	/* Don't let the test go on too long. */
446*c43e99fdSEd Maste 	tv.tv_sec = 0;
447*c43e99fdSEd Maste 	tv.tv_usec = 200*1000;
448*c43e99fdSEd Maste 	event_base_loopexit(base, &tv);
449*c43e99fdSEd Maste 	event_base_loop(base, 0);
450*c43e99fdSEd Maste 
451*c43e99fdSEd Maste 	tt_int_op(got_read_on_close, ==, EV_READ);
452*c43e99fdSEd Maste 	tt_int_op(got_write_on_close, ==, EV_WRITE);
453*c43e99fdSEd Maste 	tt_int_op(premature_event, ==, 0);
454*c43e99fdSEd Maste 
455*c43e99fdSEd Maste end:
456*c43e99fdSEd Maste 	if (pair1[0] >= 0)
457*c43e99fdSEd Maste 		evutil_closesocket(pair1[0]);
458*c43e99fdSEd Maste 	if (pair1[1] >= 0)
459*c43e99fdSEd Maste 		evutil_closesocket(pair1[1]);
460*c43e99fdSEd Maste 	if (pair2[0] >= 0)
461*c43e99fdSEd Maste 		evutil_closesocket(pair2[0]);
462*c43e99fdSEd Maste 	if (pair2[1] >= 0)
463*c43e99fdSEd Maste 		evutil_closesocket(pair2[1]);
464*c43e99fdSEd Maste 	if (rev)
465*c43e99fdSEd Maste 		event_free(rev);
466*c43e99fdSEd Maste 	if (wev)
467*c43e99fdSEd Maste 		event_free(wev);
468*c43e99fdSEd Maste 	if (closeev)
469*c43e99fdSEd Maste 		event_free(closeev);
470*c43e99fdSEd Maste 	if (base)
471*c43e99fdSEd Maste 		event_base_free(base);
472*c43e99fdSEd Maste }
473*c43e99fdSEd Maste 
474*c43e99fdSEd Maste 
475*c43e99fdSEd Maste static void
476*c43e99fdSEd Maste test_multiple(void)
477*c43e99fdSEd Maste {
478*c43e99fdSEd Maste 	struct event ev, ev2;
479*c43e99fdSEd Maste 	int i;
480*c43e99fdSEd Maste 
481*c43e99fdSEd Maste 	/* Multiple read and write test */
482*c43e99fdSEd Maste 	setup_test("Multiple read/write: ");
483*c43e99fdSEd Maste 	memset(rbuf, 0, sizeof(rbuf));
484*c43e99fdSEd Maste 	for (i = 0; i < (int)sizeof(wbuf); i++)
485*c43e99fdSEd Maste 		wbuf[i] = i;
486*c43e99fdSEd Maste 
487*c43e99fdSEd Maste 	roff = woff = 0;
488*c43e99fdSEd Maste 	usepersist = 0;
489*c43e99fdSEd Maste 
490*c43e99fdSEd Maste 	event_set(&ev, pair[0], EV_WRITE, multiple_write_cb, &ev);
491*c43e99fdSEd Maste 	if (event_add(&ev, NULL) == -1)
492*c43e99fdSEd Maste 		exit(1);
493*c43e99fdSEd Maste 	event_set(&ev2, pair[1], EV_READ, multiple_read_cb, &ev2);
494*c43e99fdSEd Maste 	if (event_add(&ev2, NULL) == -1)
495*c43e99fdSEd Maste 		exit(1);
496*c43e99fdSEd Maste 	event_dispatch();
497*c43e99fdSEd Maste 
498*c43e99fdSEd Maste 	if (roff == woff)
499*c43e99fdSEd Maste 		test_ok = memcmp(rbuf, wbuf, sizeof(wbuf)) == 0;
500*c43e99fdSEd Maste 
501*c43e99fdSEd Maste 	cleanup_test();
502*c43e99fdSEd Maste }
503*c43e99fdSEd Maste 
504*c43e99fdSEd Maste static void
505*c43e99fdSEd Maste test_persistent(void)
506*c43e99fdSEd Maste {
507*c43e99fdSEd Maste 	struct event ev, ev2;
508*c43e99fdSEd Maste 	int i;
509*c43e99fdSEd Maste 
510*c43e99fdSEd Maste 	/* Multiple read and write test with persist */
511*c43e99fdSEd Maste 	setup_test("Persist read/write: ");
512*c43e99fdSEd Maste 	memset(rbuf, 0, sizeof(rbuf));
513*c43e99fdSEd Maste 	for (i = 0; i < (int)sizeof(wbuf); i++)
514*c43e99fdSEd Maste 		wbuf[i] = i;
515*c43e99fdSEd Maste 
516*c43e99fdSEd Maste 	roff = woff = 0;
517*c43e99fdSEd Maste 	usepersist = 1;
518*c43e99fdSEd Maste 
519*c43e99fdSEd Maste 	event_set(&ev, pair[0], EV_WRITE|EV_PERSIST, multiple_write_cb, &ev);
520*c43e99fdSEd Maste 	if (event_add(&ev, NULL) == -1)
521*c43e99fdSEd Maste 		exit(1);
522*c43e99fdSEd Maste 	event_set(&ev2, pair[1], EV_READ|EV_PERSIST, multiple_read_cb, &ev2);
523*c43e99fdSEd Maste 	if (event_add(&ev2, NULL) == -1)
524*c43e99fdSEd Maste 		exit(1);
525*c43e99fdSEd Maste 	event_dispatch();
526*c43e99fdSEd Maste 
527*c43e99fdSEd Maste 	if (roff == woff)
528*c43e99fdSEd Maste 		test_ok = memcmp(rbuf, wbuf, sizeof(wbuf)) == 0;
529*c43e99fdSEd Maste 
530*c43e99fdSEd Maste 	cleanup_test();
531*c43e99fdSEd Maste }
532*c43e99fdSEd Maste 
533*c43e99fdSEd Maste static void
534*c43e99fdSEd Maste test_combined(void)
535*c43e99fdSEd Maste {
536*c43e99fdSEd Maste 	struct both r1, r2, w1, w2;
537*c43e99fdSEd Maste 
538*c43e99fdSEd Maste 	setup_test("Combined read/write: ");
539*c43e99fdSEd Maste 	memset(&r1, 0, sizeof(r1));
540*c43e99fdSEd Maste 	memset(&r2, 0, sizeof(r2));
541*c43e99fdSEd Maste 	memset(&w1, 0, sizeof(w1));
542*c43e99fdSEd Maste 	memset(&w2, 0, sizeof(w2));
543*c43e99fdSEd Maste 
544*c43e99fdSEd Maste 	w1.nread = 4096;
545*c43e99fdSEd Maste 	w2.nread = 8192;
546*c43e99fdSEd Maste 
547*c43e99fdSEd Maste 	event_set(&r1.ev, pair[0], EV_READ, combined_read_cb, &r1);
548*c43e99fdSEd Maste 	event_set(&w1.ev, pair[0], EV_WRITE, combined_write_cb, &w1);
549*c43e99fdSEd Maste 	event_set(&r2.ev, pair[1], EV_READ, combined_read_cb, &r2);
550*c43e99fdSEd Maste 	event_set(&w2.ev, pair[1], EV_WRITE, combined_write_cb, &w2);
551*c43e99fdSEd Maste 	tt_assert(event_add(&r1.ev, NULL) != -1);
552*c43e99fdSEd Maste 	tt_assert(!event_add(&w1.ev, NULL));
553*c43e99fdSEd Maste 	tt_assert(!event_add(&r2.ev, NULL));
554*c43e99fdSEd Maste 	tt_assert(!event_add(&w2.ev, NULL));
555*c43e99fdSEd Maste 	event_dispatch();
556*c43e99fdSEd Maste 
557*c43e99fdSEd Maste 	if (r1.nread == 8192 && r2.nread == 4096)
558*c43e99fdSEd Maste 		test_ok = 1;
559*c43e99fdSEd Maste 
560*c43e99fdSEd Maste end:
561*c43e99fdSEd Maste 	cleanup_test();
562*c43e99fdSEd Maste }
563*c43e99fdSEd Maste 
564*c43e99fdSEd Maste static void
565*c43e99fdSEd Maste test_simpletimeout(void)
566*c43e99fdSEd Maste {
567*c43e99fdSEd Maste 	struct timeval tv;
568*c43e99fdSEd Maste 	struct event ev;
569*c43e99fdSEd Maste 
570*c43e99fdSEd Maste 	setup_test("Simple timeout: ");
571*c43e99fdSEd Maste 
572*c43e99fdSEd Maste 	tv.tv_usec = 200*1000;
573*c43e99fdSEd Maste 	tv.tv_sec = 0;
574*c43e99fdSEd Maste 	evutil_timerclear(&tcalled);
575*c43e99fdSEd Maste 	evtimer_set(&ev, timeout_cb, NULL);
576*c43e99fdSEd Maste 	evtimer_add(&ev, &tv);
577*c43e99fdSEd Maste 
578*c43e99fdSEd Maste 	evutil_gettimeofday(&tset, NULL);
579*c43e99fdSEd Maste 	event_dispatch();
580*c43e99fdSEd Maste 	test_timeval_diff_eq(&tset, &tcalled, 200);
581*c43e99fdSEd Maste 
582*c43e99fdSEd Maste 	test_ok = 1;
583*c43e99fdSEd Maste end:
584*c43e99fdSEd Maste 	cleanup_test();
585*c43e99fdSEd Maste }
586*c43e99fdSEd Maste 
587*c43e99fdSEd Maste static void
588*c43e99fdSEd Maste periodic_timeout_cb(evutil_socket_t fd, short event, void *arg)
589*c43e99fdSEd Maste {
590*c43e99fdSEd Maste 	int *count = arg;
591*c43e99fdSEd Maste 
592*c43e99fdSEd Maste 	(*count)++;
593*c43e99fdSEd Maste 	if (*count == 6) {
594*c43e99fdSEd Maste 		/* call loopexit only once - on slow machines(?), it is
595*c43e99fdSEd Maste 		 * apparently possible for this to get called twice. */
596*c43e99fdSEd Maste 		test_ok = 1;
597*c43e99fdSEd Maste 		event_base_loopexit(global_base, NULL);
598*c43e99fdSEd Maste 	}
599*c43e99fdSEd Maste }
600*c43e99fdSEd Maste 
601*c43e99fdSEd Maste static void
602*c43e99fdSEd Maste test_persistent_timeout(void)
603*c43e99fdSEd Maste {
604*c43e99fdSEd Maste 	struct timeval tv;
605*c43e99fdSEd Maste 	struct event ev;
606*c43e99fdSEd Maste 	int count = 0;
607*c43e99fdSEd Maste 
608*c43e99fdSEd Maste 	evutil_timerclear(&tv);
609*c43e99fdSEd Maste 	tv.tv_usec = 10000;
610*c43e99fdSEd Maste 
611*c43e99fdSEd Maste 	event_assign(&ev, global_base, -1, EV_TIMEOUT|EV_PERSIST,
612*c43e99fdSEd Maste 	    periodic_timeout_cb, &count);
613*c43e99fdSEd Maste 	event_add(&ev, &tv);
614*c43e99fdSEd Maste 
615*c43e99fdSEd Maste 	event_dispatch();
616*c43e99fdSEd Maste 
617*c43e99fdSEd Maste 	event_del(&ev);
618*c43e99fdSEd Maste }
619*c43e99fdSEd Maste 
620*c43e99fdSEd Maste static void
621*c43e99fdSEd Maste test_persistent_timeout_jump(void *ptr)
622*c43e99fdSEd Maste {
623*c43e99fdSEd Maste 	struct basic_test_data *data = ptr;
624*c43e99fdSEd Maste 	struct event ev;
625*c43e99fdSEd Maste 	int count = 0;
626*c43e99fdSEd Maste 	struct timeval msec100 = { 0, 100 * 1000 };
627*c43e99fdSEd Maste 	struct timeval msec50 = { 0, 50 * 1000 };
628*c43e99fdSEd Maste 	struct timeval msec300 = { 0, 300 * 1000 };
629*c43e99fdSEd Maste 
630*c43e99fdSEd Maste 	event_assign(&ev, data->base, -1, EV_PERSIST, periodic_timeout_cb, &count);
631*c43e99fdSEd Maste 	event_add(&ev, &msec100);
632*c43e99fdSEd Maste 	/* Wait for a bit */
633*c43e99fdSEd Maste 	evutil_usleep_(&msec300);
634*c43e99fdSEd Maste 	event_base_loopexit(data->base, &msec50);
635*c43e99fdSEd Maste 	event_base_dispatch(data->base);
636*c43e99fdSEd Maste 	tt_int_op(count, ==, 1);
637*c43e99fdSEd Maste 
638*c43e99fdSEd Maste end:
639*c43e99fdSEd Maste 	event_del(&ev);
640*c43e99fdSEd Maste }
641*c43e99fdSEd Maste 
642*c43e99fdSEd Maste struct persist_active_timeout_called {
643*c43e99fdSEd Maste 	int n;
644*c43e99fdSEd Maste 	short events[16];
645*c43e99fdSEd Maste 	struct timeval tvs[16];
646*c43e99fdSEd Maste };
647*c43e99fdSEd Maste 
648*c43e99fdSEd Maste static void
649*c43e99fdSEd Maste activate_cb(evutil_socket_t fd, short event, void *arg)
650*c43e99fdSEd Maste {
651*c43e99fdSEd Maste 	struct event *ev = arg;
652*c43e99fdSEd Maste 	event_active(ev, EV_READ, 1);
653*c43e99fdSEd Maste }
654*c43e99fdSEd Maste 
655*c43e99fdSEd Maste static void
656*c43e99fdSEd Maste persist_active_timeout_cb(evutil_socket_t fd, short event, void *arg)
657*c43e99fdSEd Maste {
658*c43e99fdSEd Maste 	struct persist_active_timeout_called *c = arg;
659*c43e99fdSEd Maste 	if (c->n < 15) {
660*c43e99fdSEd Maste 		c->events[c->n] = event;
661*c43e99fdSEd Maste 		evutil_gettimeofday(&c->tvs[c->n], NULL);
662*c43e99fdSEd Maste 		++c->n;
663*c43e99fdSEd Maste 	}
664*c43e99fdSEd Maste }
665*c43e99fdSEd Maste 
666*c43e99fdSEd Maste static void
667*c43e99fdSEd Maste test_persistent_active_timeout(void *ptr)
668*c43e99fdSEd Maste {
669*c43e99fdSEd Maste 	struct timeval tv, tv2, tv_exit, start;
670*c43e99fdSEd Maste 	struct event ev;
671*c43e99fdSEd Maste 	struct persist_active_timeout_called res;
672*c43e99fdSEd Maste 
673*c43e99fdSEd Maste 	struct basic_test_data *data = ptr;
674*c43e99fdSEd Maste 	struct event_base *base = data->base;
675*c43e99fdSEd Maste 
676*c43e99fdSEd Maste 	memset(&res, 0, sizeof(res));
677*c43e99fdSEd Maste 
678*c43e99fdSEd Maste 	tv.tv_sec = 0;
679*c43e99fdSEd Maste 	tv.tv_usec = 200 * 1000;
680*c43e99fdSEd Maste 	event_assign(&ev, base, -1, EV_TIMEOUT|EV_PERSIST,
681*c43e99fdSEd Maste 	    persist_active_timeout_cb, &res);
682*c43e99fdSEd Maste 	event_add(&ev, &tv);
683*c43e99fdSEd Maste 
684*c43e99fdSEd Maste 	tv2.tv_sec = 0;
685*c43e99fdSEd Maste 	tv2.tv_usec = 100 * 1000;
686*c43e99fdSEd Maste 	event_base_once(base, -1, EV_TIMEOUT, activate_cb, &ev, &tv2);
687*c43e99fdSEd Maste 
688*c43e99fdSEd Maste 	tv_exit.tv_sec = 0;
689*c43e99fdSEd Maste 	tv_exit.tv_usec = 600 * 1000;
690*c43e99fdSEd Maste 	event_base_loopexit(base, &tv_exit);
691*c43e99fdSEd Maste 
692*c43e99fdSEd Maste 	event_base_assert_ok_(base);
693*c43e99fdSEd Maste 	evutil_gettimeofday(&start, NULL);
694*c43e99fdSEd Maste 
695*c43e99fdSEd Maste 	event_base_dispatch(base);
696*c43e99fdSEd Maste 	event_base_assert_ok_(base);
697*c43e99fdSEd Maste 
698*c43e99fdSEd Maste 	tt_int_op(res.n, ==, 3);
699*c43e99fdSEd Maste 	tt_int_op(res.events[0], ==, EV_READ);
700*c43e99fdSEd Maste 	tt_int_op(res.events[1], ==, EV_TIMEOUT);
701*c43e99fdSEd Maste 	tt_int_op(res.events[2], ==, EV_TIMEOUT);
702*c43e99fdSEd Maste 	test_timeval_diff_eq(&start, &res.tvs[0], 100);
703*c43e99fdSEd Maste 	test_timeval_diff_eq(&start, &res.tvs[1], 300);
704*c43e99fdSEd Maste 	test_timeval_diff_eq(&start, &res.tvs[2], 500);
705*c43e99fdSEd Maste end:
706*c43e99fdSEd Maste 	event_del(&ev);
707*c43e99fdSEd Maste }
708*c43e99fdSEd Maste 
709*c43e99fdSEd Maste struct common_timeout_info {
710*c43e99fdSEd Maste 	struct event ev;
711*c43e99fdSEd Maste 	struct timeval called_at;
712*c43e99fdSEd Maste 	int which;
713*c43e99fdSEd Maste 	int count;
714*c43e99fdSEd Maste };
715*c43e99fdSEd Maste 
716*c43e99fdSEd Maste static void
717*c43e99fdSEd Maste common_timeout_cb(evutil_socket_t fd, short event, void *arg)
718*c43e99fdSEd Maste {
719*c43e99fdSEd Maste 	struct common_timeout_info *ti = arg;
720*c43e99fdSEd Maste 	++ti->count;
721*c43e99fdSEd Maste 	evutil_gettimeofday(&ti->called_at, NULL);
722*c43e99fdSEd Maste 	if (ti->count >= 4)
723*c43e99fdSEd Maste 		event_del(&ti->ev);
724*c43e99fdSEd Maste }
725*c43e99fdSEd Maste 
726*c43e99fdSEd Maste static void
727*c43e99fdSEd Maste test_common_timeout(void *ptr)
728*c43e99fdSEd Maste {
729*c43e99fdSEd Maste 	struct basic_test_data *data = ptr;
730*c43e99fdSEd Maste 
731*c43e99fdSEd Maste 	struct event_base *base = data->base;
732*c43e99fdSEd Maste 	int i;
733*c43e99fdSEd Maste 	struct common_timeout_info info[100];
734*c43e99fdSEd Maste 
735*c43e99fdSEd Maste 	struct timeval start;
736*c43e99fdSEd Maste 	struct timeval tmp_100_ms = { 0, 100*1000 };
737*c43e99fdSEd Maste 	struct timeval tmp_200_ms = { 0, 200*1000 };
738*c43e99fdSEd Maste 	struct timeval tmp_5_sec = { 5, 0 };
739*c43e99fdSEd Maste 	struct timeval tmp_5M_usec = { 0, 5*1000*1000 };
740*c43e99fdSEd Maste 
741*c43e99fdSEd Maste 	const struct timeval *ms_100, *ms_200, *sec_5;
742*c43e99fdSEd Maste 
743*c43e99fdSEd Maste 	ms_100 = event_base_init_common_timeout(base, &tmp_100_ms);
744*c43e99fdSEd Maste 	ms_200 = event_base_init_common_timeout(base, &tmp_200_ms);
745*c43e99fdSEd Maste 	sec_5 = event_base_init_common_timeout(base, &tmp_5_sec);
746*c43e99fdSEd Maste 	tt_assert(ms_100);
747*c43e99fdSEd Maste 	tt_assert(ms_200);
748*c43e99fdSEd Maste 	tt_assert(sec_5);
749*c43e99fdSEd Maste 	tt_ptr_op(event_base_init_common_timeout(base, &tmp_200_ms),
750*c43e99fdSEd Maste 	    ==, ms_200);
751*c43e99fdSEd Maste 	tt_ptr_op(event_base_init_common_timeout(base, ms_200), ==, ms_200);
752*c43e99fdSEd Maste 	tt_ptr_op(event_base_init_common_timeout(base, &tmp_5M_usec), ==, sec_5);
753*c43e99fdSEd Maste 	tt_int_op(ms_100->tv_sec, ==, 0);
754*c43e99fdSEd Maste 	tt_int_op(ms_200->tv_sec, ==, 0);
755*c43e99fdSEd Maste 	tt_int_op(sec_5->tv_sec, ==, 5);
756*c43e99fdSEd Maste 	tt_int_op(ms_100->tv_usec, ==, 100000|0x50000000);
757*c43e99fdSEd Maste 	tt_int_op(ms_200->tv_usec, ==, 200000|0x50100000);
758*c43e99fdSEd Maste 	tt_int_op(sec_5->tv_usec, ==, 0|0x50200000);
759*c43e99fdSEd Maste 
760*c43e99fdSEd Maste 	memset(info, 0, sizeof(info));
761*c43e99fdSEd Maste 
762*c43e99fdSEd Maste 	for (i=0; i<100; ++i) {
763*c43e99fdSEd Maste 		info[i].which = i;
764*c43e99fdSEd Maste 		event_assign(&info[i].ev, base, -1, EV_TIMEOUT|EV_PERSIST,
765*c43e99fdSEd Maste 		    common_timeout_cb, &info[i]);
766*c43e99fdSEd Maste 		if (i % 2) {
767*c43e99fdSEd Maste 			if ((i%20)==1) {
768*c43e99fdSEd Maste 				/* Glass-box test: Make sure we survive the
769*c43e99fdSEd Maste 				 * transition to non-common timeouts. It's
770*c43e99fdSEd Maste 				 * a little tricky. */
771*c43e99fdSEd Maste 				event_add(&info[i].ev, ms_200);
772*c43e99fdSEd Maste 				event_add(&info[i].ev, &tmp_100_ms);
773*c43e99fdSEd Maste 			} else if ((i%20)==3) {
774*c43e99fdSEd Maste 				/* Check heap-to-common too. */
775*c43e99fdSEd Maste 				event_add(&info[i].ev, &tmp_200_ms);
776*c43e99fdSEd Maste 				event_add(&info[i].ev, ms_100);
777*c43e99fdSEd Maste 			} else if ((i%20)==5) {
778*c43e99fdSEd Maste 				/* Also check common-to-common. */
779*c43e99fdSEd Maste 				event_add(&info[i].ev, ms_200);
780*c43e99fdSEd Maste 				event_add(&info[i].ev, ms_100);
781*c43e99fdSEd Maste 			} else {
782*c43e99fdSEd Maste 				event_add(&info[i].ev, ms_100);
783*c43e99fdSEd Maste 			}
784*c43e99fdSEd Maste 		} else {
785*c43e99fdSEd Maste 			event_add(&info[i].ev, ms_200);
786*c43e99fdSEd Maste 		}
787*c43e99fdSEd Maste 	}
788*c43e99fdSEd Maste 
789*c43e99fdSEd Maste 	event_base_assert_ok_(base);
790*c43e99fdSEd Maste 	evutil_gettimeofday(&start, NULL);
791*c43e99fdSEd Maste 	event_base_dispatch(base);
792*c43e99fdSEd Maste 
793*c43e99fdSEd Maste 	event_base_assert_ok_(base);
794*c43e99fdSEd Maste 
795*c43e99fdSEd Maste 	for (i=0; i<10; ++i) {
796*c43e99fdSEd Maste 		tt_int_op(info[i].count, ==, 4);
797*c43e99fdSEd Maste 		if (i % 2) {
798*c43e99fdSEd Maste 			test_timeval_diff_eq(&start, &info[i].called_at, 400);
799*c43e99fdSEd Maste 		} else {
800*c43e99fdSEd Maste 			test_timeval_diff_eq(&start, &info[i].called_at, 800);
801*c43e99fdSEd Maste 		}
802*c43e99fdSEd Maste 	}
803*c43e99fdSEd Maste 
804*c43e99fdSEd Maste 	/* Make sure we can free the base with some events in. */
805*c43e99fdSEd Maste 	for (i=0; i<100; ++i) {
806*c43e99fdSEd Maste 		if (i % 2) {
807*c43e99fdSEd Maste 			event_add(&info[i].ev, ms_100);
808*c43e99fdSEd Maste 		} else {
809*c43e99fdSEd Maste 			event_add(&info[i].ev, ms_200);
810*c43e99fdSEd Maste 		}
811*c43e99fdSEd Maste 	}
812*c43e99fdSEd Maste 
813*c43e99fdSEd Maste end:
814*c43e99fdSEd Maste 	event_base_free(data->base); /* need to do this here before info is
815*c43e99fdSEd Maste 				      * out-of-scope */
816*c43e99fdSEd Maste 	data->base = NULL;
817*c43e99fdSEd Maste }
818*c43e99fdSEd Maste 
819*c43e99fdSEd Maste #ifndef _WIN32
820*c43e99fdSEd Maste 
821*c43e99fdSEd Maste #define current_base event_global_current_base_
822*c43e99fdSEd Maste extern struct event_base *current_base;
823*c43e99fdSEd Maste 
824*c43e99fdSEd Maste static void
825*c43e99fdSEd Maste fork_signal_cb(evutil_socket_t fd, short events, void *arg)
826*c43e99fdSEd Maste {
827*c43e99fdSEd Maste 	event_del(arg);
828*c43e99fdSEd Maste }
829*c43e99fdSEd Maste 
830*c43e99fdSEd Maste int child_pair[2] = { -1, -1 };
831*c43e99fdSEd Maste static void
832*c43e99fdSEd Maste simple_child_read_cb(evutil_socket_t fd, short event, void *arg)
833*c43e99fdSEd Maste {
834*c43e99fdSEd Maste 	char buf[256];
835*c43e99fdSEd Maste 	int len;
836*c43e99fdSEd Maste 
837*c43e99fdSEd Maste 	len = read(fd, buf, sizeof(buf));
838*c43e99fdSEd Maste 	if (write(child_pair[0], "", 1) < 0)
839*c43e99fdSEd Maste 		tt_fail_perror("write");
840*c43e99fdSEd Maste 
841*c43e99fdSEd Maste 	if (len) {
842*c43e99fdSEd Maste 		if (!called) {
843*c43e99fdSEd Maste 			if (event_add(arg, NULL) == -1)
844*c43e99fdSEd Maste 				exit(1);
845*c43e99fdSEd Maste 		}
846*c43e99fdSEd Maste 	} else if (called == 1)
847*c43e99fdSEd Maste 		test_ok = 1;
848*c43e99fdSEd Maste 
849*c43e99fdSEd Maste 	called++;
850*c43e99fdSEd Maste }
851*c43e99fdSEd Maste static void
852*c43e99fdSEd Maste test_fork(void)
853*c43e99fdSEd Maste {
854*c43e99fdSEd Maste 	char c;
855*c43e99fdSEd Maste 	int status;
856*c43e99fdSEd Maste 	struct event ev, sig_ev, usr_ev, existing_ev;
857*c43e99fdSEd Maste 	pid_t pid;
858*c43e99fdSEd Maste 	int wait_flags = 0;
859*c43e99fdSEd Maste 
860*c43e99fdSEd Maste #ifdef EVENT__HAVE_WAITPID_WITH_WNOWAIT
861*c43e99fdSEd Maste 	wait_flags |= WNOWAIT;
862*c43e99fdSEd Maste #endif
863*c43e99fdSEd Maste 
864*c43e99fdSEd Maste 	setup_test("After fork: ");
865*c43e99fdSEd Maste 
866*c43e99fdSEd Maste 	{
867*c43e99fdSEd Maste 		if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, child_pair) == -1) {
868*c43e99fdSEd Maste 			fprintf(stderr, "%s: socketpair\n", __func__);
869*c43e99fdSEd Maste 			exit(1);
870*c43e99fdSEd Maste 		}
871*c43e99fdSEd Maste 
872*c43e99fdSEd Maste 		if (evutil_make_socket_nonblocking(child_pair[0]) == -1) {
873*c43e99fdSEd Maste 			fprintf(stderr, "fcntl(O_NONBLOCK)");
874*c43e99fdSEd Maste 			exit(1);
875*c43e99fdSEd Maste 		}
876*c43e99fdSEd Maste 	}
877*c43e99fdSEd Maste 
878*c43e99fdSEd Maste 	tt_assert(current_base);
879*c43e99fdSEd Maste 	evthread_make_base_notifiable(current_base);
880*c43e99fdSEd Maste 
881*c43e99fdSEd Maste 	if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) {
882*c43e99fdSEd Maste 		tt_fail_perror("write");
883*c43e99fdSEd Maste 	}
884*c43e99fdSEd Maste 
885*c43e99fdSEd Maste 	event_set(&ev, pair[1], EV_READ, simple_child_read_cb, &ev);
886*c43e99fdSEd Maste 	if (event_add(&ev, NULL) == -1)
887*c43e99fdSEd Maste 		exit(1);
888*c43e99fdSEd Maste 
889*c43e99fdSEd Maste 	evsignal_set(&sig_ev, SIGCHLD, fork_signal_cb, &sig_ev);
890*c43e99fdSEd Maste 	evsignal_add(&sig_ev, NULL);
891*c43e99fdSEd Maste 
892*c43e99fdSEd Maste 	evsignal_set(&existing_ev, SIGUSR2, fork_signal_cb, &existing_ev);
893*c43e99fdSEd Maste 	evsignal_add(&existing_ev, NULL);
894*c43e99fdSEd Maste 
895*c43e99fdSEd Maste 	event_base_assert_ok_(current_base);
896*c43e99fdSEd Maste 	TT_BLATHER(("Before fork"));
897*c43e99fdSEd Maste 	if ((pid = regress_fork()) == 0) {
898*c43e99fdSEd Maste 		/* in the child */
899*c43e99fdSEd Maste 		TT_BLATHER(("In child, before reinit"));
900*c43e99fdSEd Maste 		event_base_assert_ok_(current_base);
901*c43e99fdSEd Maste 		if (event_reinit(current_base) == -1) {
902*c43e99fdSEd Maste 			fprintf(stdout, "FAILED (reinit)\n");
903*c43e99fdSEd Maste 			exit(1);
904*c43e99fdSEd Maste 		}
905*c43e99fdSEd Maste 		TT_BLATHER(("After reinit"));
906*c43e99fdSEd Maste 		event_base_assert_ok_(current_base);
907*c43e99fdSEd Maste 		TT_BLATHER(("After assert-ok"));
908*c43e99fdSEd Maste 
909*c43e99fdSEd Maste 		evsignal_del(&sig_ev);
910*c43e99fdSEd Maste 
911*c43e99fdSEd Maste 		evsignal_set(&usr_ev, SIGUSR1, fork_signal_cb, &usr_ev);
912*c43e99fdSEd Maste 		evsignal_add(&usr_ev, NULL);
913*c43e99fdSEd Maste 		raise(SIGUSR1);
914*c43e99fdSEd Maste 		raise(SIGUSR2);
915*c43e99fdSEd Maste 
916*c43e99fdSEd Maste 		called = 0;
917*c43e99fdSEd Maste 
918*c43e99fdSEd Maste 		event_dispatch();
919*c43e99fdSEd Maste 
920*c43e99fdSEd Maste 		event_base_free(current_base);
921*c43e99fdSEd Maste 
922*c43e99fdSEd Maste 		/* we do not send an EOF; simple_read_cb requires an EOF
923*c43e99fdSEd Maste 		 * to set test_ok.  we just verify that the callback was
924*c43e99fdSEd Maste 		 * called. */
925*c43e99fdSEd Maste 		exit(test_ok != 0 || called != 2 ? -2 : 76);
926*c43e99fdSEd Maste 	}
927*c43e99fdSEd Maste 
928*c43e99fdSEd Maste 	/** wait until client read first message */
929*c43e99fdSEd Maste 	if (read(child_pair[1], &c, 1) < 0) {
930*c43e99fdSEd Maste 		tt_fail_perror("read");
931*c43e99fdSEd Maste 	}
932*c43e99fdSEd Maste 	if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) {
933*c43e99fdSEd Maste 		tt_fail_perror("write");
934*c43e99fdSEd Maste 	}
935*c43e99fdSEd Maste 
936*c43e99fdSEd Maste 	TT_BLATHER(("Before waitpid"));
937*c43e99fdSEd Maste 	if (waitpid(pid, &status, wait_flags) == -1) {
938*c43e99fdSEd Maste 		perror("waitpid");
939*c43e99fdSEd Maste 		exit(1);
940*c43e99fdSEd Maste 	}
941*c43e99fdSEd Maste 	TT_BLATHER(("After waitpid"));
942*c43e99fdSEd Maste 
943*c43e99fdSEd Maste 	if (WEXITSTATUS(status) != 76) {
944*c43e99fdSEd Maste 		fprintf(stdout, "FAILED (exit): %d\n", WEXITSTATUS(status));
945*c43e99fdSEd Maste 		exit(1);
946*c43e99fdSEd Maste 	}
947*c43e99fdSEd Maste 
948*c43e99fdSEd Maste 	/* test that the current event loop still works */
949*c43e99fdSEd Maste 	if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) {
950*c43e99fdSEd Maste 		fprintf(stderr, "%s: write\n", __func__);
951*c43e99fdSEd Maste 	}
952*c43e99fdSEd Maste 
953*c43e99fdSEd Maste 	shutdown(pair[0], EVUTIL_SHUT_WR);
954*c43e99fdSEd Maste 
955*c43e99fdSEd Maste 	evsignal_set(&usr_ev, SIGUSR1, fork_signal_cb, &usr_ev);
956*c43e99fdSEd Maste 	evsignal_add(&usr_ev, NULL);
957*c43e99fdSEd Maste 	raise(SIGUSR1);
958*c43e99fdSEd Maste 	raise(SIGUSR2);
959*c43e99fdSEd Maste 
960*c43e99fdSEd Maste 	event_dispatch();
961*c43e99fdSEd Maste 
962*c43e99fdSEd Maste 	evsignal_del(&sig_ev);
963*c43e99fdSEd Maste 	tt_int_op(test_ok, ==, 1);
964*c43e99fdSEd Maste 
965*c43e99fdSEd Maste 	end:
966*c43e99fdSEd Maste 	cleanup_test();
967*c43e99fdSEd Maste 	if (child_pair[0] != -1)
968*c43e99fdSEd Maste 		evutil_closesocket(child_pair[0]);
969*c43e99fdSEd Maste 	if (child_pair[1] != -1)
970*c43e99fdSEd Maste 		evutil_closesocket(child_pair[1]);
971*c43e99fdSEd Maste }
972*c43e99fdSEd Maste 
973*c43e99fdSEd Maste #ifdef EVENT__HAVE_PTHREADS
974*c43e99fdSEd Maste static void* del_wait_thread(void *arg)
975*c43e99fdSEd Maste {
976*c43e99fdSEd Maste 	struct timeval tv_start, tv_end;
977*c43e99fdSEd Maste 
978*c43e99fdSEd Maste 	evutil_gettimeofday(&tv_start, NULL);
979*c43e99fdSEd Maste 	event_dispatch();
980*c43e99fdSEd Maste 	evutil_gettimeofday(&tv_end, NULL);
981*c43e99fdSEd Maste 
982*c43e99fdSEd Maste 	test_timeval_diff_eq(&tv_start, &tv_end, 300);
983*c43e99fdSEd Maste 
984*c43e99fdSEd Maste 	end:
985*c43e99fdSEd Maste 	return NULL;
986*c43e99fdSEd Maste }
987*c43e99fdSEd Maste 
988*c43e99fdSEd Maste static void
989*c43e99fdSEd Maste del_wait_cb(evutil_socket_t fd, short event, void *arg)
990*c43e99fdSEd Maste {
991*c43e99fdSEd Maste 	struct timeval delay = { 0, 300*1000 };
992*c43e99fdSEd Maste 	TT_BLATHER(("Sleeping"));
993*c43e99fdSEd Maste 	evutil_usleep_(&delay);
994*c43e99fdSEd Maste 	test_ok = 1;
995*c43e99fdSEd Maste }
996*c43e99fdSEd Maste 
997*c43e99fdSEd Maste static void
998*c43e99fdSEd Maste test_del_wait(void)
999*c43e99fdSEd Maste {
1000*c43e99fdSEd Maste 	struct event ev;
1001*c43e99fdSEd Maste 	pthread_t thread;
1002*c43e99fdSEd Maste 
1003*c43e99fdSEd Maste 	setup_test("event_del will wait: ");
1004*c43e99fdSEd Maste 
1005*c43e99fdSEd Maste 	event_set(&ev, pair[1], EV_READ, del_wait_cb, &ev);
1006*c43e99fdSEd Maste 	event_add(&ev, NULL);
1007*c43e99fdSEd Maste 
1008*c43e99fdSEd Maste 	pthread_create(&thread, NULL, del_wait_thread, NULL);
1009*c43e99fdSEd Maste 
1010*c43e99fdSEd Maste 	if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) {
1011*c43e99fdSEd Maste 		tt_fail_perror("write");
1012*c43e99fdSEd Maste 	}
1013*c43e99fdSEd Maste 
1014*c43e99fdSEd Maste 	{
1015*c43e99fdSEd Maste 		struct timeval delay = { 0, 30*1000 };
1016*c43e99fdSEd Maste 		evutil_usleep_(&delay);
1017*c43e99fdSEd Maste 	}
1018*c43e99fdSEd Maste 
1019*c43e99fdSEd Maste 	{
1020*c43e99fdSEd Maste 		struct timeval tv_start, tv_end;
1021*c43e99fdSEd Maste 		evutil_gettimeofday(&tv_start, NULL);
1022*c43e99fdSEd Maste 		event_del(&ev);
1023*c43e99fdSEd Maste 		evutil_gettimeofday(&tv_end, NULL);
1024*c43e99fdSEd Maste 		test_timeval_diff_eq(&tv_start, &tv_end, 270);
1025*c43e99fdSEd Maste 	}
1026*c43e99fdSEd Maste 
1027*c43e99fdSEd Maste 	pthread_join(thread, NULL);
1028*c43e99fdSEd Maste 
1029*c43e99fdSEd Maste 	end:
1030*c43e99fdSEd Maste 	;
1031*c43e99fdSEd Maste }
1032*c43e99fdSEd Maste #endif
1033*c43e99fdSEd Maste 
1034*c43e99fdSEd Maste static void
1035*c43e99fdSEd Maste signal_cb_sa(int sig)
1036*c43e99fdSEd Maste {
1037*c43e99fdSEd Maste 	test_ok = 2;
1038*c43e99fdSEd Maste }
1039*c43e99fdSEd Maste 
1040*c43e99fdSEd Maste static void
1041*c43e99fdSEd Maste signal_cb(evutil_socket_t fd, short event, void *arg)
1042*c43e99fdSEd Maste {
1043*c43e99fdSEd Maste 	struct event *ev = arg;
1044*c43e99fdSEd Maste 
1045*c43e99fdSEd Maste 	evsignal_del(ev);
1046*c43e99fdSEd Maste 	test_ok = 1;
1047*c43e99fdSEd Maste }
1048*c43e99fdSEd Maste 
1049*c43e99fdSEd Maste static void
1050*c43e99fdSEd Maste test_simplesignal_impl(int find_reorder)
1051*c43e99fdSEd Maste {
1052*c43e99fdSEd Maste 	struct event ev;
1053*c43e99fdSEd Maste 	struct itimerval itv;
1054*c43e99fdSEd Maste 
1055*c43e99fdSEd Maste 	evsignal_set(&ev, SIGALRM, signal_cb, &ev);
1056*c43e99fdSEd Maste 	evsignal_add(&ev, NULL);
1057*c43e99fdSEd Maste 	/* find bugs in which operations are re-ordered */
1058*c43e99fdSEd Maste 	if (find_reorder) {
1059*c43e99fdSEd Maste 		evsignal_del(&ev);
1060*c43e99fdSEd Maste 		evsignal_add(&ev, NULL);
1061*c43e99fdSEd Maste 	}
1062*c43e99fdSEd Maste 
1063*c43e99fdSEd Maste 	memset(&itv, 0, sizeof(itv));
1064*c43e99fdSEd Maste 	itv.it_value.tv_sec = 0;
1065*c43e99fdSEd Maste 	itv.it_value.tv_usec = 100000;
1066*c43e99fdSEd Maste 	if (setitimer(ITIMER_REAL, &itv, NULL) == -1)
1067*c43e99fdSEd Maste 		goto skip_simplesignal;
1068*c43e99fdSEd Maste 
1069*c43e99fdSEd Maste 	event_dispatch();
1070*c43e99fdSEd Maste  skip_simplesignal:
1071*c43e99fdSEd Maste 	if (evsignal_del(&ev) == -1)
1072*c43e99fdSEd Maste 		test_ok = 0;
1073*c43e99fdSEd Maste 
1074*c43e99fdSEd Maste 	cleanup_test();
1075*c43e99fdSEd Maste }
1076*c43e99fdSEd Maste 
1077*c43e99fdSEd Maste static void
1078*c43e99fdSEd Maste test_simplestsignal(void)
1079*c43e99fdSEd Maste {
1080*c43e99fdSEd Maste 	setup_test("Simplest one signal: ");
1081*c43e99fdSEd Maste 	test_simplesignal_impl(0);
1082*c43e99fdSEd Maste }
1083*c43e99fdSEd Maste 
1084*c43e99fdSEd Maste static void
1085*c43e99fdSEd Maste test_simplesignal(void)
1086*c43e99fdSEd Maste {
1087*c43e99fdSEd Maste 	setup_test("Simple signal: ");
1088*c43e99fdSEd Maste 	test_simplesignal_impl(1);
1089*c43e99fdSEd Maste }
1090*c43e99fdSEd Maste 
1091*c43e99fdSEd Maste static void
1092*c43e99fdSEd Maste test_multiplesignal(void)
1093*c43e99fdSEd Maste {
1094*c43e99fdSEd Maste 	struct event ev_one, ev_two;
1095*c43e99fdSEd Maste 	struct itimerval itv;
1096*c43e99fdSEd Maste 
1097*c43e99fdSEd Maste 	setup_test("Multiple signal: ");
1098*c43e99fdSEd Maste 
1099*c43e99fdSEd Maste 	evsignal_set(&ev_one, SIGALRM, signal_cb, &ev_one);
1100*c43e99fdSEd Maste 	evsignal_add(&ev_one, NULL);
1101*c43e99fdSEd Maste 
1102*c43e99fdSEd Maste 	evsignal_set(&ev_two, SIGALRM, signal_cb, &ev_two);
1103*c43e99fdSEd Maste 	evsignal_add(&ev_two, NULL);
1104*c43e99fdSEd Maste 
1105*c43e99fdSEd Maste 	memset(&itv, 0, sizeof(itv));
1106*c43e99fdSEd Maste 	itv.it_value.tv_sec = 0;
1107*c43e99fdSEd Maste 	itv.it_value.tv_usec = 100000;
1108*c43e99fdSEd Maste 	if (setitimer(ITIMER_REAL, &itv, NULL) == -1)
1109*c43e99fdSEd Maste 		goto skip_simplesignal;
1110*c43e99fdSEd Maste 
1111*c43e99fdSEd Maste 	event_dispatch();
1112*c43e99fdSEd Maste 
1113*c43e99fdSEd Maste  skip_simplesignal:
1114*c43e99fdSEd Maste 	if (evsignal_del(&ev_one) == -1)
1115*c43e99fdSEd Maste 		test_ok = 0;
1116*c43e99fdSEd Maste 	if (evsignal_del(&ev_two) == -1)
1117*c43e99fdSEd Maste 		test_ok = 0;
1118*c43e99fdSEd Maste 
1119*c43e99fdSEd Maste 	cleanup_test();
1120*c43e99fdSEd Maste }
1121*c43e99fdSEd Maste 
1122*c43e99fdSEd Maste static void
1123*c43e99fdSEd Maste test_immediatesignal(void)
1124*c43e99fdSEd Maste {
1125*c43e99fdSEd Maste 	struct event ev;
1126*c43e99fdSEd Maste 
1127*c43e99fdSEd Maste 	test_ok = 0;
1128*c43e99fdSEd Maste 	evsignal_set(&ev, SIGUSR1, signal_cb, &ev);
1129*c43e99fdSEd Maste 	evsignal_add(&ev, NULL);
1130*c43e99fdSEd Maste 	raise(SIGUSR1);
1131*c43e99fdSEd Maste 	event_loop(EVLOOP_NONBLOCK);
1132*c43e99fdSEd Maste 	evsignal_del(&ev);
1133*c43e99fdSEd Maste 	cleanup_test();
1134*c43e99fdSEd Maste }
1135*c43e99fdSEd Maste 
1136*c43e99fdSEd Maste static void
1137*c43e99fdSEd Maste test_signal_dealloc(void)
1138*c43e99fdSEd Maste {
1139*c43e99fdSEd Maste 	/* make sure that evsignal_event is event_del'ed and pipe closed */
1140*c43e99fdSEd Maste 	struct event ev;
1141*c43e99fdSEd Maste 	struct event_base *base = event_init();
1142*c43e99fdSEd Maste 	evsignal_set(&ev, SIGUSR1, signal_cb, &ev);
1143*c43e99fdSEd Maste 	evsignal_add(&ev, NULL);
1144*c43e99fdSEd Maste 	evsignal_del(&ev);
1145*c43e99fdSEd Maste 	event_base_free(base);
1146*c43e99fdSEd Maste 	/* If we got here without asserting, we're fine. */
1147*c43e99fdSEd Maste 	test_ok = 1;
1148*c43e99fdSEd Maste 	cleanup_test();
1149*c43e99fdSEd Maste }
1150*c43e99fdSEd Maste 
1151*c43e99fdSEd Maste static void
1152*c43e99fdSEd Maste test_signal_pipeloss(void)
1153*c43e99fdSEd Maste {
1154*c43e99fdSEd Maste 	/* make sure that the base1 pipe is closed correctly. */
1155*c43e99fdSEd Maste 	struct event_base *base1, *base2;
1156*c43e99fdSEd Maste 	int pipe1;
1157*c43e99fdSEd Maste 	test_ok = 0;
1158*c43e99fdSEd Maste 	base1 = event_init();
1159*c43e99fdSEd Maste 	pipe1 = base1->sig.ev_signal_pair[0];
1160*c43e99fdSEd Maste 	base2 = event_init();
1161*c43e99fdSEd Maste 	event_base_free(base2);
1162*c43e99fdSEd Maste 	event_base_free(base1);
1163*c43e99fdSEd Maste 	if (close(pipe1) != -1 || errno!=EBADF) {
1164*c43e99fdSEd Maste 		/* fd must be closed, so second close gives -1, EBADF */
1165*c43e99fdSEd Maste 		printf("signal pipe not closed. ");
1166*c43e99fdSEd Maste 		test_ok = 0;
1167*c43e99fdSEd Maste 	} else {
1168*c43e99fdSEd Maste 		test_ok = 1;
1169*c43e99fdSEd Maste 	}
1170*c43e99fdSEd Maste 	cleanup_test();
1171*c43e99fdSEd Maste }
1172*c43e99fdSEd Maste 
1173*c43e99fdSEd Maste /*
1174*c43e99fdSEd Maste  * make two bases to catch signals, use both of them.  this only works
1175*c43e99fdSEd Maste  * for event mechanisms that use our signal pipe trick.	 kqueue handles
1176*c43e99fdSEd Maste  * signals internally, and all interested kqueues get all the signals.
1177*c43e99fdSEd Maste  */
1178*c43e99fdSEd Maste static void
1179*c43e99fdSEd Maste test_signal_switchbase(void)
1180*c43e99fdSEd Maste {
1181*c43e99fdSEd Maste 	struct event ev1, ev2;
1182*c43e99fdSEd Maste 	struct event_base *base1, *base2;
1183*c43e99fdSEd Maste 	int is_kqueue;
1184*c43e99fdSEd Maste 	test_ok = 0;
1185*c43e99fdSEd Maste 	base1 = event_init();
1186*c43e99fdSEd Maste 	base2 = event_init();
1187*c43e99fdSEd Maste 	is_kqueue = !strcmp(event_get_method(),"kqueue");
1188*c43e99fdSEd Maste 	evsignal_set(&ev1, SIGUSR1, signal_cb, &ev1);
1189*c43e99fdSEd Maste 	evsignal_set(&ev2, SIGUSR1, signal_cb, &ev2);
1190*c43e99fdSEd Maste 	if (event_base_set(base1, &ev1) ||
1191*c43e99fdSEd Maste 	    event_base_set(base2, &ev2) ||
1192*c43e99fdSEd Maste 	    event_add(&ev1, NULL) ||
1193*c43e99fdSEd Maste 	    event_add(&ev2, NULL)) {
1194*c43e99fdSEd Maste 		fprintf(stderr, "%s: cannot set base, add\n", __func__);
1195*c43e99fdSEd Maste 		exit(1);
1196*c43e99fdSEd Maste 	}
1197*c43e99fdSEd Maste 
1198*c43e99fdSEd Maste 	tt_ptr_op(event_get_base(&ev1), ==, base1);
1199*c43e99fdSEd Maste 	tt_ptr_op(event_get_base(&ev2), ==, base2);
1200*c43e99fdSEd Maste 
1201*c43e99fdSEd Maste 	test_ok = 0;
1202*c43e99fdSEd Maste 	/* can handle signal before loop is called */
1203*c43e99fdSEd Maste 	raise(SIGUSR1);
1204*c43e99fdSEd Maste 	event_base_loop(base2, EVLOOP_NONBLOCK);
1205*c43e99fdSEd Maste 	if (is_kqueue) {
1206*c43e99fdSEd Maste 		if (!test_ok)
1207*c43e99fdSEd Maste 			goto end;
1208*c43e99fdSEd Maste 		test_ok = 0;
1209*c43e99fdSEd Maste 	}
1210*c43e99fdSEd Maste 	event_base_loop(base1, EVLOOP_NONBLOCK);
1211*c43e99fdSEd Maste 	if (test_ok && !is_kqueue) {
1212*c43e99fdSEd Maste 		test_ok = 0;
1213*c43e99fdSEd Maste 
1214*c43e99fdSEd Maste 		/* set base1 to handle signals */
1215*c43e99fdSEd Maste 		event_base_loop(base1, EVLOOP_NONBLOCK);
1216*c43e99fdSEd Maste 		raise(SIGUSR1);
1217*c43e99fdSEd Maste 		event_base_loop(base1, EVLOOP_NONBLOCK);
1218*c43e99fdSEd Maste 		event_base_loop(base2, EVLOOP_NONBLOCK);
1219*c43e99fdSEd Maste 	}
1220*c43e99fdSEd Maste end:
1221*c43e99fdSEd Maste 	event_base_free(base1);
1222*c43e99fdSEd Maste 	event_base_free(base2);
1223*c43e99fdSEd Maste 	cleanup_test();
1224*c43e99fdSEd Maste }
1225*c43e99fdSEd Maste 
1226*c43e99fdSEd Maste /*
1227*c43e99fdSEd Maste  * assert that a signal event removed from the event queue really is
1228*c43e99fdSEd Maste  * removed - with no possibility of it's parent handler being fired.
1229*c43e99fdSEd Maste  */
1230*c43e99fdSEd Maste static void
1231*c43e99fdSEd Maste test_signal_assert(void)
1232*c43e99fdSEd Maste {
1233*c43e99fdSEd Maste 	struct event ev;
1234*c43e99fdSEd Maste 	struct event_base *base = event_init();
1235*c43e99fdSEd Maste 	test_ok = 0;
1236*c43e99fdSEd Maste 	/* use SIGCONT so we don't kill ourselves when we signal to nowhere */
1237*c43e99fdSEd Maste 	evsignal_set(&ev, SIGCONT, signal_cb, &ev);
1238*c43e99fdSEd Maste 	evsignal_add(&ev, NULL);
1239*c43e99fdSEd Maste 	/*
1240*c43e99fdSEd Maste 	 * if evsignal_del() fails to reset the handler, it's current handler
1241*c43e99fdSEd Maste 	 * will still point to evsig_handler().
1242*c43e99fdSEd Maste 	 */
1243*c43e99fdSEd Maste 	evsignal_del(&ev);
1244*c43e99fdSEd Maste 
1245*c43e99fdSEd Maste 	raise(SIGCONT);
1246*c43e99fdSEd Maste #if 0
1247*c43e99fdSEd Maste 	/* only way to verify we were in evsig_handler() */
1248*c43e99fdSEd Maste 	/* XXXX Now there's no longer a good way. */
1249*c43e99fdSEd Maste 	if (base->sig.evsig_caught)
1250*c43e99fdSEd Maste 		test_ok = 0;
1251*c43e99fdSEd Maste 	else
1252*c43e99fdSEd Maste 		test_ok = 1;
1253*c43e99fdSEd Maste #else
1254*c43e99fdSEd Maste 	test_ok = 1;
1255*c43e99fdSEd Maste #endif
1256*c43e99fdSEd Maste 
1257*c43e99fdSEd Maste 	event_base_free(base);
1258*c43e99fdSEd Maste 	cleanup_test();
1259*c43e99fdSEd Maste 	return;
1260*c43e99fdSEd Maste }
1261*c43e99fdSEd Maste 
1262*c43e99fdSEd Maste /*
1263*c43e99fdSEd Maste  * assert that we restore our previous signal handler properly.
1264*c43e99fdSEd Maste  */
1265*c43e99fdSEd Maste static void
1266*c43e99fdSEd Maste test_signal_restore(void)
1267*c43e99fdSEd Maste {
1268*c43e99fdSEd Maste 	struct event ev;
1269*c43e99fdSEd Maste 	struct event_base *base = event_init();
1270*c43e99fdSEd Maste #ifdef EVENT__HAVE_SIGACTION
1271*c43e99fdSEd Maste 	struct sigaction sa;
1272*c43e99fdSEd Maste #endif
1273*c43e99fdSEd Maste 
1274*c43e99fdSEd Maste 	test_ok = 0;
1275*c43e99fdSEd Maste #ifdef EVENT__HAVE_SIGACTION
1276*c43e99fdSEd Maste 	sa.sa_handler = signal_cb_sa;
1277*c43e99fdSEd Maste 	sa.sa_flags = 0x0;
1278*c43e99fdSEd Maste 	sigemptyset(&sa.sa_mask);
1279*c43e99fdSEd Maste 	if (sigaction(SIGUSR1, &sa, NULL) == -1)
1280*c43e99fdSEd Maste 		goto out;
1281*c43e99fdSEd Maste #else
1282*c43e99fdSEd Maste 	if (signal(SIGUSR1, signal_cb_sa) == SIG_ERR)
1283*c43e99fdSEd Maste 		goto out;
1284*c43e99fdSEd Maste #endif
1285*c43e99fdSEd Maste 	evsignal_set(&ev, SIGUSR1, signal_cb, &ev);
1286*c43e99fdSEd Maste 	evsignal_add(&ev, NULL);
1287*c43e99fdSEd Maste 	evsignal_del(&ev);
1288*c43e99fdSEd Maste 
1289*c43e99fdSEd Maste 	raise(SIGUSR1);
1290*c43e99fdSEd Maste 	/* 1 == signal_cb, 2 == signal_cb_sa, we want our previous handler */
1291*c43e99fdSEd Maste 	if (test_ok != 2)
1292*c43e99fdSEd Maste 		test_ok = 0;
1293*c43e99fdSEd Maste out:
1294*c43e99fdSEd Maste 	event_base_free(base);
1295*c43e99fdSEd Maste 	cleanup_test();
1296*c43e99fdSEd Maste 	return;
1297*c43e99fdSEd Maste }
1298*c43e99fdSEd Maste 
1299*c43e99fdSEd Maste static void
1300*c43e99fdSEd Maste signal_cb_swp(int sig, short event, void *arg)
1301*c43e99fdSEd Maste {
1302*c43e99fdSEd Maste 	called++;
1303*c43e99fdSEd Maste 	if (called < 5)
1304*c43e99fdSEd Maste 		raise(sig);
1305*c43e99fdSEd Maste 	else
1306*c43e99fdSEd Maste 		event_loopexit(NULL);
1307*c43e99fdSEd Maste }
1308*c43e99fdSEd Maste static void
1309*c43e99fdSEd Maste timeout_cb_swp(evutil_socket_t fd, short event, void *arg)
1310*c43e99fdSEd Maste {
1311*c43e99fdSEd Maste 	if (called == -1) {
1312*c43e99fdSEd Maste 		struct timeval tv = {5, 0};
1313*c43e99fdSEd Maste 
1314*c43e99fdSEd Maste 		called = 0;
1315*c43e99fdSEd Maste 		evtimer_add((struct event *)arg, &tv);
1316*c43e99fdSEd Maste 		raise(SIGUSR1);
1317*c43e99fdSEd Maste 		return;
1318*c43e99fdSEd Maste 	}
1319*c43e99fdSEd Maste 	test_ok = 0;
1320*c43e99fdSEd Maste 	event_loopexit(NULL);
1321*c43e99fdSEd Maste }
1322*c43e99fdSEd Maste 
1323*c43e99fdSEd Maste static void
1324*c43e99fdSEd Maste test_signal_while_processing(void)
1325*c43e99fdSEd Maste {
1326*c43e99fdSEd Maste 	struct event_base *base = event_init();
1327*c43e99fdSEd Maste 	struct event ev, ev_timer;
1328*c43e99fdSEd Maste 	struct timeval tv = {0, 0};
1329*c43e99fdSEd Maste 
1330*c43e99fdSEd Maste 	setup_test("Receiving a signal while processing other signal: ");
1331*c43e99fdSEd Maste 
1332*c43e99fdSEd Maste 	called = -1;
1333*c43e99fdSEd Maste 	test_ok = 1;
1334*c43e99fdSEd Maste 	signal_set(&ev, SIGUSR1, signal_cb_swp, NULL);
1335*c43e99fdSEd Maste 	signal_add(&ev, NULL);
1336*c43e99fdSEd Maste 	evtimer_set(&ev_timer, timeout_cb_swp, &ev_timer);
1337*c43e99fdSEd Maste 	evtimer_add(&ev_timer, &tv);
1338*c43e99fdSEd Maste 	event_dispatch();
1339*c43e99fdSEd Maste 
1340*c43e99fdSEd Maste 	event_base_free(base);
1341*c43e99fdSEd Maste 	cleanup_test();
1342*c43e99fdSEd Maste 	return;
1343*c43e99fdSEd Maste }
1344*c43e99fdSEd Maste #endif
1345*c43e99fdSEd Maste 
1346*c43e99fdSEd Maste static void
1347*c43e99fdSEd Maste test_free_active_base(void *ptr)
1348*c43e99fdSEd Maste {
1349*c43e99fdSEd Maste 	struct basic_test_data *data = ptr;
1350*c43e99fdSEd Maste 	struct event_base *base1;
1351*c43e99fdSEd Maste 	struct event ev1;
1352*c43e99fdSEd Maste 
1353*c43e99fdSEd Maste 	base1 = event_init();
1354*c43e99fdSEd Maste 	if (base1) {
1355*c43e99fdSEd Maste 		event_assign(&ev1, base1, data->pair[1], EV_READ,
1356*c43e99fdSEd Maste 			     dummy_read_cb, NULL);
1357*c43e99fdSEd Maste 		event_add(&ev1, NULL);
1358*c43e99fdSEd Maste 		event_base_free(base1);	 /* should not crash */
1359*c43e99fdSEd Maste 	} else {
1360*c43e99fdSEd Maste 		tt_fail_msg("failed to create event_base for test");
1361*c43e99fdSEd Maste 	}
1362*c43e99fdSEd Maste 
1363*c43e99fdSEd Maste 	base1 = event_init();
1364*c43e99fdSEd Maste 	tt_assert(base1);
1365*c43e99fdSEd Maste 	event_assign(&ev1, base1, 0, 0, dummy_read_cb, NULL);
1366*c43e99fdSEd Maste 	event_active(&ev1, EV_READ, 1);
1367*c43e99fdSEd Maste 	event_base_free(base1);
1368*c43e99fdSEd Maste end:
1369*c43e99fdSEd Maste 	;
1370*c43e99fdSEd Maste }
1371*c43e99fdSEd Maste 
1372*c43e99fdSEd Maste static void
1373*c43e99fdSEd Maste test_manipulate_active_events(void *ptr)
1374*c43e99fdSEd Maste {
1375*c43e99fdSEd Maste 	struct basic_test_data *data = ptr;
1376*c43e99fdSEd Maste 	struct event_base *base = data->base;
1377*c43e99fdSEd Maste 	struct event ev1;
1378*c43e99fdSEd Maste 
1379*c43e99fdSEd Maste 	event_assign(&ev1, base, -1, EV_TIMEOUT, dummy_read_cb, NULL);
1380*c43e99fdSEd Maste 
1381*c43e99fdSEd Maste 	/* Make sure an active event is pending. */
1382*c43e99fdSEd Maste 	event_active(&ev1, EV_READ, 1);
1383*c43e99fdSEd Maste 	tt_int_op(event_pending(&ev1, EV_READ|EV_TIMEOUT|EV_WRITE, NULL),
1384*c43e99fdSEd Maste 	    ==, EV_READ);
1385*c43e99fdSEd Maste 
1386*c43e99fdSEd Maste 	/* Make sure that activating an event twice works. */
1387*c43e99fdSEd Maste 	event_active(&ev1, EV_WRITE, 1);
1388*c43e99fdSEd Maste 	tt_int_op(event_pending(&ev1, EV_READ|EV_TIMEOUT|EV_WRITE, NULL),
1389*c43e99fdSEd Maste 	    ==, EV_READ|EV_WRITE);
1390*c43e99fdSEd Maste 
1391*c43e99fdSEd Maste end:
1392*c43e99fdSEd Maste 	event_del(&ev1);
1393*c43e99fdSEd Maste }
1394*c43e99fdSEd Maste 
1395*c43e99fdSEd Maste static void
1396*c43e99fdSEd Maste event_selfarg_cb(evutil_socket_t fd, short event, void *arg)
1397*c43e99fdSEd Maste {
1398*c43e99fdSEd Maste 	struct event *ev = arg;
1399*c43e99fdSEd Maste 	struct event_base *base = event_get_base(ev);
1400*c43e99fdSEd Maste 	event_base_assert_ok_(base);
1401*c43e99fdSEd Maste 	event_base_loopexit(base, NULL);
1402*c43e99fdSEd Maste 	tt_want(ev == event_base_get_running_event(base));
1403*c43e99fdSEd Maste }
1404*c43e99fdSEd Maste 
1405*c43e99fdSEd Maste static void
1406*c43e99fdSEd Maste test_event_new_selfarg(void *ptr)
1407*c43e99fdSEd Maste {
1408*c43e99fdSEd Maste 	struct basic_test_data *data = ptr;
1409*c43e99fdSEd Maste 	struct event_base *base = data->base;
1410*c43e99fdSEd Maste 	struct event *ev = event_new(base, -1, EV_READ, event_selfarg_cb,
1411*c43e99fdSEd Maste                                      event_self_cbarg());
1412*c43e99fdSEd Maste 
1413*c43e99fdSEd Maste 	event_active(ev, EV_READ, 1);
1414*c43e99fdSEd Maste 	event_base_dispatch(base);
1415*c43e99fdSEd Maste 
1416*c43e99fdSEd Maste 	event_free(ev);
1417*c43e99fdSEd Maste }
1418*c43e99fdSEd Maste 
1419*c43e99fdSEd Maste static void
1420*c43e99fdSEd Maste test_event_assign_selfarg(void *ptr)
1421*c43e99fdSEd Maste {
1422*c43e99fdSEd Maste 	struct basic_test_data *data = ptr;
1423*c43e99fdSEd Maste 	struct event_base *base = data->base;
1424*c43e99fdSEd Maste 	struct event ev;
1425*c43e99fdSEd Maste 
1426*c43e99fdSEd Maste 	event_assign(&ev, base, -1, EV_READ, event_selfarg_cb,
1427*c43e99fdSEd Maste                      event_self_cbarg());
1428*c43e99fdSEd Maste 	event_active(&ev, EV_READ, 1);
1429*c43e99fdSEd Maste 	event_base_dispatch(base);
1430*c43e99fdSEd Maste }
1431*c43e99fdSEd Maste 
1432*c43e99fdSEd Maste static void
1433*c43e99fdSEd Maste test_event_base_get_num_events(void *ptr)
1434*c43e99fdSEd Maste {
1435*c43e99fdSEd Maste 	struct basic_test_data *data = ptr;
1436*c43e99fdSEd Maste 	struct event_base *base = data->base;
1437*c43e99fdSEd Maste 	struct event ev;
1438*c43e99fdSEd Maste 	int event_count_active;
1439*c43e99fdSEd Maste 	int event_count_virtual;
1440*c43e99fdSEd Maste 	int event_count_added;
1441*c43e99fdSEd Maste 	int event_count_active_virtual;
1442*c43e99fdSEd Maste 	int event_count_active_added;
1443*c43e99fdSEd Maste 	int event_count_virtual_added;
1444*c43e99fdSEd Maste 	int event_count_active_added_virtual;
1445*c43e99fdSEd Maste 
1446*c43e99fdSEd Maste 	struct timeval qsec = {0, 100000};
1447*c43e99fdSEd Maste 
1448*c43e99fdSEd Maste 	event_assign(&ev, base, -1, EV_READ, event_selfarg_cb,
1449*c43e99fdSEd Maste 	    event_self_cbarg());
1450*c43e99fdSEd Maste 
1451*c43e99fdSEd Maste 	event_add(&ev, &qsec);
1452*c43e99fdSEd Maste 	event_count_active = event_base_get_num_events(base,
1453*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ACTIVE);
1454*c43e99fdSEd Maste 	event_count_virtual = event_base_get_num_events(base,
1455*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_VIRTUAL);
1456*c43e99fdSEd Maste 	event_count_added = event_base_get_num_events(base,
1457*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ADDED);
1458*c43e99fdSEd Maste 	event_count_active_virtual = event_base_get_num_events(base,
1459*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ACTIVE|EVENT_BASE_COUNT_VIRTUAL);
1460*c43e99fdSEd Maste 	event_count_active_added = event_base_get_num_events(base,
1461*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ACTIVE|EVENT_BASE_COUNT_ADDED);
1462*c43e99fdSEd Maste 	event_count_virtual_added = event_base_get_num_events(base,
1463*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_VIRTUAL|EVENT_BASE_COUNT_ADDED);
1464*c43e99fdSEd Maste 	event_count_active_added_virtual = event_base_get_num_events(base,
1465*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ACTIVE|
1466*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ADDED|
1467*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_VIRTUAL);
1468*c43e99fdSEd Maste 	tt_int_op(event_count_active, ==, 0);
1469*c43e99fdSEd Maste 	tt_int_op(event_count_virtual, ==, 0);
1470*c43e99fdSEd Maste 	/* libevent itself adds a timeout event, so the event_count is 2 here */
1471*c43e99fdSEd Maste 	tt_int_op(event_count_added, ==, 2);
1472*c43e99fdSEd Maste 	tt_int_op(event_count_active_virtual, ==, 0);
1473*c43e99fdSEd Maste 	tt_int_op(event_count_active_added, ==, 2);
1474*c43e99fdSEd Maste 	tt_int_op(event_count_virtual_added, ==, 2);
1475*c43e99fdSEd Maste 	tt_int_op(event_count_active_added_virtual, ==, 2);
1476*c43e99fdSEd Maste 
1477*c43e99fdSEd Maste 	event_active(&ev, EV_READ, 1);
1478*c43e99fdSEd Maste 	event_count_active = event_base_get_num_events(base,
1479*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ACTIVE);
1480*c43e99fdSEd Maste 	event_count_virtual = event_base_get_num_events(base,
1481*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_VIRTUAL);
1482*c43e99fdSEd Maste 	event_count_added = event_base_get_num_events(base,
1483*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ADDED);
1484*c43e99fdSEd Maste 	event_count_active_virtual = event_base_get_num_events(base,
1485*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ACTIVE|EVENT_BASE_COUNT_VIRTUAL);
1486*c43e99fdSEd Maste 	event_count_active_added = event_base_get_num_events(base,
1487*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ACTIVE|EVENT_BASE_COUNT_ADDED);
1488*c43e99fdSEd Maste 	event_count_virtual_added = event_base_get_num_events(base,
1489*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_VIRTUAL|EVENT_BASE_COUNT_ADDED);
1490*c43e99fdSEd Maste 	event_count_active_added_virtual = event_base_get_num_events(base,
1491*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ACTIVE|
1492*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ADDED|
1493*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_VIRTUAL);
1494*c43e99fdSEd Maste 	tt_int_op(event_count_active, ==, 1);
1495*c43e99fdSEd Maste 	tt_int_op(event_count_virtual, ==, 0);
1496*c43e99fdSEd Maste 	tt_int_op(event_count_added, ==, 3);
1497*c43e99fdSEd Maste 	tt_int_op(event_count_active_virtual, ==, 1);
1498*c43e99fdSEd Maste 	tt_int_op(event_count_active_added, ==, 4);
1499*c43e99fdSEd Maste 	tt_int_op(event_count_virtual_added, ==, 3);
1500*c43e99fdSEd Maste 	tt_int_op(event_count_active_added_virtual, ==, 4);
1501*c43e99fdSEd Maste 
1502*c43e99fdSEd Maste        event_base_loop(base, 0);
1503*c43e99fdSEd Maste        event_count_active = event_base_get_num_events(base,
1504*c43e99fdSEd Maste 	   EVENT_BASE_COUNT_ACTIVE);
1505*c43e99fdSEd Maste        event_count_virtual = event_base_get_num_events(base,
1506*c43e99fdSEd Maste 	   EVENT_BASE_COUNT_VIRTUAL);
1507*c43e99fdSEd Maste        event_count_added = event_base_get_num_events(base,
1508*c43e99fdSEd Maste 	   EVENT_BASE_COUNT_ADDED);
1509*c43e99fdSEd Maste        event_count_active_virtual = event_base_get_num_events(base,
1510*c43e99fdSEd Maste 	   EVENT_BASE_COUNT_ACTIVE|EVENT_BASE_COUNT_VIRTUAL);
1511*c43e99fdSEd Maste        event_count_active_added = event_base_get_num_events(base,
1512*c43e99fdSEd Maste 	   EVENT_BASE_COUNT_ACTIVE|EVENT_BASE_COUNT_ADDED);
1513*c43e99fdSEd Maste        event_count_virtual_added = event_base_get_num_events(base,
1514*c43e99fdSEd Maste 	   EVENT_BASE_COUNT_VIRTUAL|EVENT_BASE_COUNT_ADDED);
1515*c43e99fdSEd Maste        event_count_active_added_virtual = event_base_get_num_events(base,
1516*c43e99fdSEd Maste 	   EVENT_BASE_COUNT_ACTIVE|
1517*c43e99fdSEd Maste 	   EVENT_BASE_COUNT_ADDED|
1518*c43e99fdSEd Maste 	   EVENT_BASE_COUNT_VIRTUAL);
1519*c43e99fdSEd Maste        tt_int_op(event_count_active, ==, 0);
1520*c43e99fdSEd Maste        tt_int_op(event_count_virtual, ==, 0);
1521*c43e99fdSEd Maste        tt_int_op(event_count_added, ==, 0);
1522*c43e99fdSEd Maste        tt_int_op(event_count_active_virtual, ==, 0);
1523*c43e99fdSEd Maste        tt_int_op(event_count_active_added, ==, 0);
1524*c43e99fdSEd Maste        tt_int_op(event_count_virtual_added, ==, 0);
1525*c43e99fdSEd Maste        tt_int_op(event_count_active_added_virtual, ==, 0);
1526*c43e99fdSEd Maste 
1527*c43e99fdSEd Maste        event_base_add_virtual_(base);
1528*c43e99fdSEd Maste        event_count_active = event_base_get_num_events(base,
1529*c43e99fdSEd Maste 	   EVENT_BASE_COUNT_ACTIVE);
1530*c43e99fdSEd Maste        event_count_virtual = event_base_get_num_events(base,
1531*c43e99fdSEd Maste 	   EVENT_BASE_COUNT_VIRTUAL);
1532*c43e99fdSEd Maste        event_count_added = event_base_get_num_events(base,
1533*c43e99fdSEd Maste 	   EVENT_BASE_COUNT_ADDED);
1534*c43e99fdSEd Maste        event_count_active_virtual = event_base_get_num_events(base,
1535*c43e99fdSEd Maste 	   EVENT_BASE_COUNT_ACTIVE|EVENT_BASE_COUNT_VIRTUAL);
1536*c43e99fdSEd Maste        event_count_active_added = event_base_get_num_events(base,
1537*c43e99fdSEd Maste 	   EVENT_BASE_COUNT_ACTIVE|EVENT_BASE_COUNT_ADDED);
1538*c43e99fdSEd Maste        event_count_virtual_added = event_base_get_num_events(base,
1539*c43e99fdSEd Maste 	   EVENT_BASE_COUNT_VIRTUAL|EVENT_BASE_COUNT_ADDED);
1540*c43e99fdSEd Maste        event_count_active_added_virtual = event_base_get_num_events(base,
1541*c43e99fdSEd Maste 	   EVENT_BASE_COUNT_ACTIVE|
1542*c43e99fdSEd Maste 	   EVENT_BASE_COUNT_ADDED|
1543*c43e99fdSEd Maste 	   EVENT_BASE_COUNT_VIRTUAL);
1544*c43e99fdSEd Maste        tt_int_op(event_count_active, ==, 0);
1545*c43e99fdSEd Maste        tt_int_op(event_count_virtual, ==, 1);
1546*c43e99fdSEd Maste        tt_int_op(event_count_added, ==, 0);
1547*c43e99fdSEd Maste        tt_int_op(event_count_active_virtual, ==, 1);
1548*c43e99fdSEd Maste        tt_int_op(event_count_active_added, ==, 0);
1549*c43e99fdSEd Maste        tt_int_op(event_count_virtual_added, ==, 1);
1550*c43e99fdSEd Maste        tt_int_op(event_count_active_added_virtual, ==, 1);
1551*c43e99fdSEd Maste 
1552*c43e99fdSEd Maste end:
1553*c43e99fdSEd Maste        ;
1554*c43e99fdSEd Maste }
1555*c43e99fdSEd Maste 
1556*c43e99fdSEd Maste static void
1557*c43e99fdSEd Maste test_event_base_get_max_events(void *ptr)
1558*c43e99fdSEd Maste {
1559*c43e99fdSEd Maste 	struct basic_test_data *data = ptr;
1560*c43e99fdSEd Maste 	struct event_base *base = data->base;
1561*c43e99fdSEd Maste 	struct event ev;
1562*c43e99fdSEd Maste 	struct event ev2;
1563*c43e99fdSEd Maste 	int event_count_active;
1564*c43e99fdSEd Maste 	int event_count_virtual;
1565*c43e99fdSEd Maste 	int event_count_added;
1566*c43e99fdSEd Maste 	int event_count_active_virtual;
1567*c43e99fdSEd Maste 	int event_count_active_added;
1568*c43e99fdSEd Maste 	int event_count_virtual_added;
1569*c43e99fdSEd Maste 	int event_count_active_added_virtual;
1570*c43e99fdSEd Maste 
1571*c43e99fdSEd Maste 	struct timeval qsec = {0, 100000};
1572*c43e99fdSEd Maste 
1573*c43e99fdSEd Maste 	event_assign(&ev, base, -1, EV_READ, event_selfarg_cb,
1574*c43e99fdSEd Maste 	    event_self_cbarg());
1575*c43e99fdSEd Maste 	event_assign(&ev2, base, -1, EV_READ, event_selfarg_cb,
1576*c43e99fdSEd Maste 	    event_self_cbarg());
1577*c43e99fdSEd Maste 
1578*c43e99fdSEd Maste 	event_add(&ev, &qsec);
1579*c43e99fdSEd Maste 	event_add(&ev2, &qsec);
1580*c43e99fdSEd Maste 	event_del(&ev2);
1581*c43e99fdSEd Maste 
1582*c43e99fdSEd Maste 	event_count_active = event_base_get_max_events(base,
1583*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ACTIVE, 0);
1584*c43e99fdSEd Maste 	event_count_virtual = event_base_get_max_events(base,
1585*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_VIRTUAL, 0);
1586*c43e99fdSEd Maste 	event_count_added = event_base_get_max_events(base,
1587*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ADDED, 0);
1588*c43e99fdSEd Maste 	event_count_active_virtual = event_base_get_max_events(base,
1589*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ACTIVE | EVENT_BASE_COUNT_VIRTUAL, 0);
1590*c43e99fdSEd Maste 	event_count_active_added = event_base_get_max_events(base,
1591*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ACTIVE | EVENT_BASE_COUNT_ADDED, 0);
1592*c43e99fdSEd Maste 	event_count_virtual_added = event_base_get_max_events(base,
1593*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_VIRTUAL | EVENT_BASE_COUNT_ADDED, 0);
1594*c43e99fdSEd Maste 	event_count_active_added_virtual = event_base_get_max_events(base,
1595*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ACTIVE |
1596*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ADDED |
1597*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_VIRTUAL, 0);
1598*c43e99fdSEd Maste 
1599*c43e99fdSEd Maste 	tt_int_op(event_count_active, ==, 0);
1600*c43e99fdSEd Maste 	tt_int_op(event_count_virtual, ==, 0);
1601*c43e99fdSEd Maste 	/* libevent itself adds a timeout event, so the event_count is 4 here */
1602*c43e99fdSEd Maste 	tt_int_op(event_count_added, ==, 4);
1603*c43e99fdSEd Maste 	tt_int_op(event_count_active_virtual, ==, 0);
1604*c43e99fdSEd Maste 	tt_int_op(event_count_active_added, ==, 4);
1605*c43e99fdSEd Maste 	tt_int_op(event_count_virtual_added, ==, 4);
1606*c43e99fdSEd Maste 	tt_int_op(event_count_active_added_virtual, ==, 4);
1607*c43e99fdSEd Maste 
1608*c43e99fdSEd Maste 	event_active(&ev, EV_READ, 1);
1609*c43e99fdSEd Maste 	event_count_active = event_base_get_max_events(base,
1610*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ACTIVE, 0);
1611*c43e99fdSEd Maste 	event_count_virtual = event_base_get_max_events(base,
1612*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_VIRTUAL, 0);
1613*c43e99fdSEd Maste 	event_count_added = event_base_get_max_events(base,
1614*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ADDED, 0);
1615*c43e99fdSEd Maste 	event_count_active_virtual = event_base_get_max_events(base,
1616*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ACTIVE | EVENT_BASE_COUNT_VIRTUAL, 0);
1617*c43e99fdSEd Maste 	event_count_active_added = event_base_get_max_events(base,
1618*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ACTIVE | EVENT_BASE_COUNT_ADDED, 0);
1619*c43e99fdSEd Maste 	event_count_virtual_added = event_base_get_max_events(base,
1620*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_VIRTUAL | EVENT_BASE_COUNT_ADDED, 0);
1621*c43e99fdSEd Maste 	event_count_active_added_virtual = event_base_get_max_events(base,
1622*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ACTIVE |
1623*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ADDED |
1624*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_VIRTUAL, 0);
1625*c43e99fdSEd Maste 
1626*c43e99fdSEd Maste 	tt_int_op(event_count_active, ==, 1);
1627*c43e99fdSEd Maste 	tt_int_op(event_count_virtual, ==, 0);
1628*c43e99fdSEd Maste 	tt_int_op(event_count_added, ==, 4);
1629*c43e99fdSEd Maste 	tt_int_op(event_count_active_virtual, ==, 1);
1630*c43e99fdSEd Maste 	tt_int_op(event_count_active_added, ==, 5);
1631*c43e99fdSEd Maste 	tt_int_op(event_count_virtual_added, ==, 4);
1632*c43e99fdSEd Maste 	tt_int_op(event_count_active_added_virtual, ==, 5);
1633*c43e99fdSEd Maste 
1634*c43e99fdSEd Maste 	event_base_loop(base, 0);
1635*c43e99fdSEd Maste 	event_count_active = event_base_get_max_events(base,
1636*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ACTIVE, 1);
1637*c43e99fdSEd Maste 	event_count_virtual = event_base_get_max_events(base,
1638*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_VIRTUAL, 1);
1639*c43e99fdSEd Maste 	event_count_added = event_base_get_max_events(base,
1640*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ADDED, 1);
1641*c43e99fdSEd Maste 	event_count_active_virtual = event_base_get_max_events(base,
1642*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ACTIVE | EVENT_BASE_COUNT_VIRTUAL, 0);
1643*c43e99fdSEd Maste 	event_count_active_added = event_base_get_max_events(base,
1644*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ACTIVE | EVENT_BASE_COUNT_ADDED, 0);
1645*c43e99fdSEd Maste 	event_count_virtual_added = event_base_get_max_events(base,
1646*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_VIRTUAL | EVENT_BASE_COUNT_ADDED, 0);
1647*c43e99fdSEd Maste 	event_count_active_added_virtual = event_base_get_max_events(base,
1648*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ACTIVE |
1649*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ADDED |
1650*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_VIRTUAL, 1);
1651*c43e99fdSEd Maste 
1652*c43e99fdSEd Maste 	tt_int_op(event_count_active, ==, 1);
1653*c43e99fdSEd Maste 	tt_int_op(event_count_virtual, ==, 0);
1654*c43e99fdSEd Maste 	tt_int_op(event_count_added, ==, 4);
1655*c43e99fdSEd Maste 	tt_int_op(event_count_active_virtual, ==, 0);
1656*c43e99fdSEd Maste 	tt_int_op(event_count_active_added, ==, 0);
1657*c43e99fdSEd Maste 	tt_int_op(event_count_virtual_added, ==, 0);
1658*c43e99fdSEd Maste 	tt_int_op(event_count_active_added_virtual, ==, 0);
1659*c43e99fdSEd Maste 
1660*c43e99fdSEd Maste 	event_count_active = event_base_get_max_events(base,
1661*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ACTIVE, 0);
1662*c43e99fdSEd Maste 	event_count_virtual = event_base_get_max_events(base,
1663*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_VIRTUAL, 0);
1664*c43e99fdSEd Maste 	event_count_added = event_base_get_max_events(base,
1665*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ADDED, 0);
1666*c43e99fdSEd Maste 	tt_int_op(event_count_active, ==, 0);
1667*c43e99fdSEd Maste 	tt_int_op(event_count_virtual, ==, 0);
1668*c43e99fdSEd Maste 	tt_int_op(event_count_added, ==, 0);
1669*c43e99fdSEd Maste 
1670*c43e99fdSEd Maste 	event_base_add_virtual_(base);
1671*c43e99fdSEd Maste 	event_count_active = event_base_get_max_events(base,
1672*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ACTIVE, 0);
1673*c43e99fdSEd Maste 	event_count_virtual = event_base_get_max_events(base,
1674*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_VIRTUAL, 0);
1675*c43e99fdSEd Maste 	event_count_added = event_base_get_max_events(base,
1676*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ADDED, 0);
1677*c43e99fdSEd Maste 	event_count_active_virtual = event_base_get_max_events(base,
1678*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ACTIVE | EVENT_BASE_COUNT_VIRTUAL, 0);
1679*c43e99fdSEd Maste 	event_count_active_added = event_base_get_max_events(base,
1680*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ACTIVE | EVENT_BASE_COUNT_ADDED, 0);
1681*c43e99fdSEd Maste 	event_count_virtual_added = event_base_get_max_events(base,
1682*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_VIRTUAL | EVENT_BASE_COUNT_ADDED, 0);
1683*c43e99fdSEd Maste 	event_count_active_added_virtual = event_base_get_max_events(base,
1684*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ACTIVE |
1685*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_ADDED |
1686*c43e99fdSEd Maste 	    EVENT_BASE_COUNT_VIRTUAL, 0);
1687*c43e99fdSEd Maste 
1688*c43e99fdSEd Maste 	tt_int_op(event_count_active, ==, 0);
1689*c43e99fdSEd Maste 	tt_int_op(event_count_virtual, ==, 1);
1690*c43e99fdSEd Maste 	tt_int_op(event_count_added, ==, 0);
1691*c43e99fdSEd Maste 	tt_int_op(event_count_active_virtual, ==, 1);
1692*c43e99fdSEd Maste 	tt_int_op(event_count_active_added, ==, 0);
1693*c43e99fdSEd Maste 	tt_int_op(event_count_virtual_added, ==, 1);
1694*c43e99fdSEd Maste 	tt_int_op(event_count_active_added_virtual, ==, 1);
1695*c43e99fdSEd Maste 
1696*c43e99fdSEd Maste end:
1697*c43e99fdSEd Maste        ;
1698*c43e99fdSEd Maste }
1699*c43e99fdSEd Maste 
1700*c43e99fdSEd Maste static void
1701*c43e99fdSEd Maste test_bad_assign(void *ptr)
1702*c43e99fdSEd Maste {
1703*c43e99fdSEd Maste 	struct event ev;
1704*c43e99fdSEd Maste 	int r;
1705*c43e99fdSEd Maste 	/* READ|SIGNAL is not allowed */
1706*c43e99fdSEd Maste 	r = event_assign(&ev, NULL, -1, EV_SIGNAL|EV_READ, dummy_read_cb, NULL);
1707*c43e99fdSEd Maste 	tt_int_op(r,==,-1);
1708*c43e99fdSEd Maste 
1709*c43e99fdSEd Maste end:
1710*c43e99fdSEd Maste 	;
1711*c43e99fdSEd Maste }
1712*c43e99fdSEd Maste 
1713*c43e99fdSEd Maste static int reentrant_cb_run = 0;
1714*c43e99fdSEd Maste 
1715*c43e99fdSEd Maste static void
1716*c43e99fdSEd Maste bad_reentrant_run_loop_cb(evutil_socket_t fd, short what, void *ptr)
1717*c43e99fdSEd Maste {
1718*c43e99fdSEd Maste 	struct event_base *base = ptr;
1719*c43e99fdSEd Maste 	int r;
1720*c43e99fdSEd Maste 	reentrant_cb_run = 1;
1721*c43e99fdSEd Maste 	/* This reentrant call to event_base_loop should be detected and
1722*c43e99fdSEd Maste 	 * should fail */
1723*c43e99fdSEd Maste 	r = event_base_loop(base, 0);
1724*c43e99fdSEd Maste 	tt_int_op(r, ==, -1);
1725*c43e99fdSEd Maste end:
1726*c43e99fdSEd Maste 	;
1727*c43e99fdSEd Maste }
1728*c43e99fdSEd Maste 
1729*c43e99fdSEd Maste static void
1730*c43e99fdSEd Maste test_bad_reentrant(void *ptr)
1731*c43e99fdSEd Maste {
1732*c43e99fdSEd Maste 	struct basic_test_data *data = ptr;
1733*c43e99fdSEd Maste 	struct event_base *base = data->base;
1734*c43e99fdSEd Maste 	struct event ev;
1735*c43e99fdSEd Maste 	int r;
1736*c43e99fdSEd Maste 	event_assign(&ev, base, -1,
1737*c43e99fdSEd Maste 	    0, bad_reentrant_run_loop_cb, base);
1738*c43e99fdSEd Maste 
1739*c43e99fdSEd Maste 	event_active(&ev, EV_WRITE, 1);
1740*c43e99fdSEd Maste 	r = event_base_loop(base, 0);
1741*c43e99fdSEd Maste 	tt_int_op(r, ==, 1);
1742*c43e99fdSEd Maste 	tt_int_op(reentrant_cb_run, ==, 1);
1743*c43e99fdSEd Maste end:
1744*c43e99fdSEd Maste 	;
1745*c43e99fdSEd Maste }
1746*c43e99fdSEd Maste 
1747*c43e99fdSEd Maste static int n_write_a_byte_cb=0;
1748*c43e99fdSEd Maste static int n_read_and_drain_cb=0;
1749*c43e99fdSEd Maste static int n_activate_other_event_cb=0;
1750*c43e99fdSEd Maste static void
1751*c43e99fdSEd Maste write_a_byte_cb(evutil_socket_t fd, short what, void *arg)
1752*c43e99fdSEd Maste {
1753*c43e99fdSEd Maste 	char buf[] = "x";
1754*c43e99fdSEd Maste 	if (write(fd, buf, 1) == 1)
1755*c43e99fdSEd Maste 		++n_write_a_byte_cb;
1756*c43e99fdSEd Maste }
1757*c43e99fdSEd Maste static void
1758*c43e99fdSEd Maste read_and_drain_cb(evutil_socket_t fd, short what, void *arg)
1759*c43e99fdSEd Maste {
1760*c43e99fdSEd Maste 	char buf[128];
1761*c43e99fdSEd Maste 	int n;
1762*c43e99fdSEd Maste 	++n_read_and_drain_cb;
1763*c43e99fdSEd Maste 	while ((n = read(fd, buf, sizeof(buf))) > 0)
1764*c43e99fdSEd Maste 		;
1765*c43e99fdSEd Maste }
1766*c43e99fdSEd Maste 
1767*c43e99fdSEd Maste static void
1768*c43e99fdSEd Maste activate_other_event_cb(evutil_socket_t fd, short what, void *other_)
1769*c43e99fdSEd Maste {
1770*c43e99fdSEd Maste 	struct event *ev_activate = other_;
1771*c43e99fdSEd Maste 	++n_activate_other_event_cb;
1772*c43e99fdSEd Maste 	event_active_later_(ev_activate, EV_READ);
1773*c43e99fdSEd Maste }
1774*c43e99fdSEd Maste 
1775*c43e99fdSEd Maste static void
1776*c43e99fdSEd Maste test_active_later(void *ptr)
1777*c43e99fdSEd Maste {
1778*c43e99fdSEd Maste 	struct basic_test_data *data = ptr;
1779*c43e99fdSEd Maste 	struct event *ev1 = NULL, *ev2 = NULL;
1780*c43e99fdSEd Maste 	struct event ev3, ev4;
1781*c43e99fdSEd Maste 	struct timeval qsec = {0, 100000};
1782*c43e99fdSEd Maste 	ev1 = event_new(data->base, data->pair[0], EV_READ|EV_PERSIST, read_and_drain_cb, NULL);
1783*c43e99fdSEd Maste 	ev2 = event_new(data->base, data->pair[1], EV_WRITE|EV_PERSIST, write_a_byte_cb, NULL);
1784*c43e99fdSEd Maste 	event_assign(&ev3, data->base, -1, 0, activate_other_event_cb, &ev4);
1785*c43e99fdSEd Maste 	event_assign(&ev4, data->base, -1, 0, activate_other_event_cb, &ev3);
1786*c43e99fdSEd Maste 	event_add(ev1, NULL);
1787*c43e99fdSEd Maste 	event_add(ev2, NULL);
1788*c43e99fdSEd Maste 	event_active_later_(&ev3, EV_READ);
1789*c43e99fdSEd Maste 
1790*c43e99fdSEd Maste 	event_base_loopexit(data->base, &qsec);
1791*c43e99fdSEd Maste 
1792*c43e99fdSEd Maste 	event_base_loop(data->base, 0);
1793*c43e99fdSEd Maste 
1794*c43e99fdSEd Maste 	TT_BLATHER(("%d write calls, %d read calls, %d activate-other calls.",
1795*c43e99fdSEd Maste 		n_write_a_byte_cb, n_read_and_drain_cb, n_activate_other_event_cb));
1796*c43e99fdSEd Maste 	event_del(&ev3);
1797*c43e99fdSEd Maste 	event_del(&ev4);
1798*c43e99fdSEd Maste 
1799*c43e99fdSEd Maste 	tt_int_op(n_write_a_byte_cb, ==, n_activate_other_event_cb);
1800*c43e99fdSEd Maste 	tt_int_op(n_write_a_byte_cb, >, 100);
1801*c43e99fdSEd Maste 	tt_int_op(n_read_and_drain_cb, >, 100);
1802*c43e99fdSEd Maste 	tt_int_op(n_activate_other_event_cb, >, 100);
1803*c43e99fdSEd Maste 
1804*c43e99fdSEd Maste 	event_active_later_(&ev4, EV_READ);
1805*c43e99fdSEd Maste 	event_active(&ev4, EV_READ, 1); /* This should make the event
1806*c43e99fdSEd Maste 					   active immediately. */
1807*c43e99fdSEd Maste 	tt_assert((ev4.ev_flags & EVLIST_ACTIVE) != 0);
1808*c43e99fdSEd Maste 	tt_assert((ev4.ev_flags & EVLIST_ACTIVE_LATER) == 0);
1809*c43e99fdSEd Maste 
1810*c43e99fdSEd Maste 	/* Now leave this one around, so that event_free sees it and removes
1811*c43e99fdSEd Maste 	 * it. */
1812*c43e99fdSEd Maste 	event_active_later_(&ev3, EV_READ);
1813*c43e99fdSEd Maste 	event_base_assert_ok_(data->base);
1814*c43e99fdSEd Maste 
1815*c43e99fdSEd Maste end:
1816*c43e99fdSEd Maste 	if (ev1)
1817*c43e99fdSEd Maste 		event_free(ev1);
1818*c43e99fdSEd Maste 	if (ev2)
1819*c43e99fdSEd Maste 		event_free(ev2);
1820*c43e99fdSEd Maste 
1821*c43e99fdSEd Maste 	event_base_free(data->base);
1822*c43e99fdSEd Maste 	data->base = NULL;
1823*c43e99fdSEd Maste }
1824*c43e99fdSEd Maste 
1825*c43e99fdSEd Maste 
1826*c43e99fdSEd Maste static void incr_arg_cb(evutil_socket_t fd, short what, void *arg)
1827*c43e99fdSEd Maste {
1828*c43e99fdSEd Maste 	int *intptr = arg;
1829*c43e99fdSEd Maste 	(void) fd; (void) what;
1830*c43e99fdSEd Maste 	++*intptr;
1831*c43e99fdSEd Maste }
1832*c43e99fdSEd Maste static void remove_timers_cb(evutil_socket_t fd, short what, void *arg)
1833*c43e99fdSEd Maste {
1834*c43e99fdSEd Maste 	struct event **ep = arg;
1835*c43e99fdSEd Maste 	(void) fd; (void) what;
1836*c43e99fdSEd Maste 	event_remove_timer(ep[0]);
1837*c43e99fdSEd Maste 	event_remove_timer(ep[1]);
1838*c43e99fdSEd Maste }
1839*c43e99fdSEd Maste static void send_a_byte_cb(evutil_socket_t fd, short what, void *arg)
1840*c43e99fdSEd Maste {
1841*c43e99fdSEd Maste 	evutil_socket_t *sockp = arg;
1842*c43e99fdSEd Maste 	(void) fd; (void) what;
1843*c43e99fdSEd Maste 	(void) write(*sockp, "A", 1);
1844*c43e99fdSEd Maste }
1845*c43e99fdSEd Maste struct read_not_timeout_param
1846*c43e99fdSEd Maste {
1847*c43e99fdSEd Maste 	struct event **ev;
1848*c43e99fdSEd Maste 	int events;
1849*c43e99fdSEd Maste 	int count;
1850*c43e99fdSEd Maste };
1851*c43e99fdSEd Maste static void read_not_timeout_cb(evutil_socket_t fd, short what, void *arg)
1852*c43e99fdSEd Maste {
1853*c43e99fdSEd Maste 	struct read_not_timeout_param *rntp = arg;
1854*c43e99fdSEd Maste 	char c;
1855*c43e99fdSEd Maste 	ev_ssize_t n;
1856*c43e99fdSEd Maste 	(void) fd; (void) what;
1857*c43e99fdSEd Maste 	n = read(fd, &c, 1);
1858*c43e99fdSEd Maste 	tt_int_op(n, ==, 1);
1859*c43e99fdSEd Maste 	rntp->events |= what;
1860*c43e99fdSEd Maste 	++rntp->count;
1861*c43e99fdSEd Maste 	if(2 == rntp->count) event_del(rntp->ev[0]);
1862*c43e99fdSEd Maste end:
1863*c43e99fdSEd Maste 	;
1864*c43e99fdSEd Maste }
1865*c43e99fdSEd Maste 
1866*c43e99fdSEd Maste static void
1867*c43e99fdSEd Maste test_event_remove_timeout(void *ptr)
1868*c43e99fdSEd Maste {
1869*c43e99fdSEd Maste 	struct basic_test_data *data = ptr;
1870*c43e99fdSEd Maste 	struct event_base *base = data->base;
1871*c43e99fdSEd Maste 	struct event *ev[5];
1872*c43e99fdSEd Maste 	int ev1_fired=0;
1873*c43e99fdSEd Maste 	struct timeval ms25 = { 0, 25*1000 },
1874*c43e99fdSEd Maste 		ms40 = { 0, 40*1000 },
1875*c43e99fdSEd Maste 		ms75 = { 0, 75*1000 },
1876*c43e99fdSEd Maste 		ms125 = { 0, 125*1000 };
1877*c43e99fdSEd Maste 	struct read_not_timeout_param rntp = { ev, 0, 0 };
1878*c43e99fdSEd Maste 
1879*c43e99fdSEd Maste 	event_base_assert_ok_(base);
1880*c43e99fdSEd Maste 
1881*c43e99fdSEd Maste 	ev[0] = event_new(base, data->pair[0], EV_READ|EV_PERSIST,
1882*c43e99fdSEd Maste 	    read_not_timeout_cb, &rntp);
1883*c43e99fdSEd Maste 	ev[1] = evtimer_new(base, incr_arg_cb, &ev1_fired);
1884*c43e99fdSEd Maste 	ev[2] = evtimer_new(base, remove_timers_cb, ev);
1885*c43e99fdSEd Maste 	ev[3] = evtimer_new(base, send_a_byte_cb, &data->pair[1]);
1886*c43e99fdSEd Maste 	ev[4] = evtimer_new(base, send_a_byte_cb, &data->pair[1]);
1887*c43e99fdSEd Maste 	tt_assert(base);
1888*c43e99fdSEd Maste 	event_add(ev[2], &ms25); /* remove timers */
1889*c43e99fdSEd Maste 	event_add(ev[4], &ms40); /* write to test if timer re-activates */
1890*c43e99fdSEd Maste 	event_add(ev[0], &ms75); /* read */
1891*c43e99fdSEd Maste 	event_add(ev[1], &ms75); /* timer */
1892*c43e99fdSEd Maste 	event_add(ev[3], &ms125); /* timeout. */
1893*c43e99fdSEd Maste 	event_base_assert_ok_(base);
1894*c43e99fdSEd Maste 
1895*c43e99fdSEd Maste 	event_base_dispatch(base);
1896*c43e99fdSEd Maste 
1897*c43e99fdSEd Maste 	tt_int_op(ev1_fired, ==, 0);
1898*c43e99fdSEd Maste 	tt_int_op(rntp.events, ==, EV_READ);
1899*c43e99fdSEd Maste 
1900*c43e99fdSEd Maste 	event_base_assert_ok_(base);
1901*c43e99fdSEd Maste end:
1902*c43e99fdSEd Maste 	event_free(ev[0]);
1903*c43e99fdSEd Maste 	event_free(ev[1]);
1904*c43e99fdSEd Maste 	event_free(ev[2]);
1905*c43e99fdSEd Maste 	event_free(ev[3]);
1906*c43e99fdSEd Maste 	event_free(ev[4]);
1907*c43e99fdSEd Maste }
1908*c43e99fdSEd Maste 
1909*c43e99fdSEd Maste static void
1910*c43e99fdSEd Maste test_event_base_new(void *ptr)
1911*c43e99fdSEd Maste {
1912*c43e99fdSEd Maste 	struct basic_test_data *data = ptr;
1913*c43e99fdSEd Maste 	struct event_base *base = 0;
1914*c43e99fdSEd Maste 	struct event ev1;
1915*c43e99fdSEd Maste 	struct basic_cb_args args;
1916*c43e99fdSEd Maste 
1917*c43e99fdSEd Maste 	int towrite = (int)strlen(TEST1)+1;
1918*c43e99fdSEd Maste 	int len = write(data->pair[0], TEST1, towrite);
1919*c43e99fdSEd Maste 
1920*c43e99fdSEd Maste 	if (len < 0)
1921*c43e99fdSEd Maste 		tt_abort_perror("initial write");
1922*c43e99fdSEd Maste 	else if (len != towrite)
1923*c43e99fdSEd Maste 		tt_abort_printf(("initial write fell short (%d of %d bytes)",
1924*c43e99fdSEd Maste 				 len, towrite));
1925*c43e99fdSEd Maste 
1926*c43e99fdSEd Maste 	if (shutdown(data->pair[0], EVUTIL_SHUT_WR))
1927*c43e99fdSEd Maste 		tt_abort_perror("initial write shutdown");
1928*c43e99fdSEd Maste 
1929*c43e99fdSEd Maste 	base = event_base_new();
1930*c43e99fdSEd Maste 	if (!base)
1931*c43e99fdSEd Maste 		tt_abort_msg("failed to create event base");
1932*c43e99fdSEd Maste 
1933*c43e99fdSEd Maste 	args.eb = base;
1934*c43e99fdSEd Maste 	args.ev = &ev1;
1935*c43e99fdSEd Maste 	args.callcount = 0;
1936*c43e99fdSEd Maste 	event_assign(&ev1, base, data->pair[1],
1937*c43e99fdSEd Maste 		     EV_READ|EV_PERSIST, basic_read_cb, &args);
1938*c43e99fdSEd Maste 
1939*c43e99fdSEd Maste 	if (event_add(&ev1, NULL))
1940*c43e99fdSEd Maste 		tt_abort_perror("initial event_add");
1941*c43e99fdSEd Maste 
1942*c43e99fdSEd Maste 	if (event_base_loop(base, 0))
1943*c43e99fdSEd Maste 		tt_abort_msg("unsuccessful exit from event loop");
1944*c43e99fdSEd Maste 
1945*c43e99fdSEd Maste end:
1946*c43e99fdSEd Maste 	if (base)
1947*c43e99fdSEd Maste 		event_base_free(base);
1948*c43e99fdSEd Maste }
1949*c43e99fdSEd Maste 
1950*c43e99fdSEd Maste static void
1951*c43e99fdSEd Maste test_loopexit(void)
1952*c43e99fdSEd Maste {
1953*c43e99fdSEd Maste 	struct timeval tv, tv_start, tv_end;
1954*c43e99fdSEd Maste 	struct event ev;
1955*c43e99fdSEd Maste 
1956*c43e99fdSEd Maste 	setup_test("Loop exit: ");
1957*c43e99fdSEd Maste 
1958*c43e99fdSEd Maste 	tv.tv_usec = 0;
1959*c43e99fdSEd Maste 	tv.tv_sec = 60*60*24;
1960*c43e99fdSEd Maste 	evtimer_set(&ev, timeout_cb, NULL);
1961*c43e99fdSEd Maste 	evtimer_add(&ev, &tv);
1962*c43e99fdSEd Maste 
1963*c43e99fdSEd Maste 	tv.tv_usec = 300*1000;
1964*c43e99fdSEd Maste 	tv.tv_sec = 0;
1965*c43e99fdSEd Maste 	event_loopexit(&tv);
1966*c43e99fdSEd Maste 
1967*c43e99fdSEd Maste 	evutil_gettimeofday(&tv_start, NULL);
1968*c43e99fdSEd Maste 	event_dispatch();
1969*c43e99fdSEd Maste 	evutil_gettimeofday(&tv_end, NULL);
1970*c43e99fdSEd Maste 
1971*c43e99fdSEd Maste 	evtimer_del(&ev);
1972*c43e99fdSEd Maste 
1973*c43e99fdSEd Maste 	tt_assert(event_base_got_exit(global_base));
1974*c43e99fdSEd Maste 	tt_assert(!event_base_got_break(global_base));
1975*c43e99fdSEd Maste 
1976*c43e99fdSEd Maste 	test_timeval_diff_eq(&tv_start, &tv_end, 300);
1977*c43e99fdSEd Maste 
1978*c43e99fdSEd Maste 	test_ok = 1;
1979*c43e99fdSEd Maste end:
1980*c43e99fdSEd Maste 	cleanup_test();
1981*c43e99fdSEd Maste }
1982*c43e99fdSEd Maste 
1983*c43e99fdSEd Maste static void
1984*c43e99fdSEd Maste test_loopexit_multiple(void)
1985*c43e99fdSEd Maste {
1986*c43e99fdSEd Maste 	struct timeval tv, tv_start, tv_end;
1987*c43e99fdSEd Maste 	struct event_base *base;
1988*c43e99fdSEd Maste 
1989*c43e99fdSEd Maste 	setup_test("Loop Multiple exit: ");
1990*c43e99fdSEd Maste 
1991*c43e99fdSEd Maste 	base = event_base_new();
1992*c43e99fdSEd Maste 
1993*c43e99fdSEd Maste 	tv.tv_usec = 200*1000;
1994*c43e99fdSEd Maste 	tv.tv_sec = 0;
1995*c43e99fdSEd Maste 	event_base_loopexit(base, &tv);
1996*c43e99fdSEd Maste 
1997*c43e99fdSEd Maste 	tv.tv_usec = 0;
1998*c43e99fdSEd Maste 	tv.tv_sec = 3;
1999*c43e99fdSEd Maste 	event_base_loopexit(base, &tv);
2000*c43e99fdSEd Maste 
2001*c43e99fdSEd Maste 	evutil_gettimeofday(&tv_start, NULL);
2002*c43e99fdSEd Maste 	event_base_dispatch(base);
2003*c43e99fdSEd Maste 	evutil_gettimeofday(&tv_end, NULL);
2004*c43e99fdSEd Maste 
2005*c43e99fdSEd Maste 	tt_assert(event_base_got_exit(base));
2006*c43e99fdSEd Maste 	tt_assert(!event_base_got_break(base));
2007*c43e99fdSEd Maste 
2008*c43e99fdSEd Maste 	event_base_free(base);
2009*c43e99fdSEd Maste 
2010*c43e99fdSEd Maste 	test_timeval_diff_eq(&tv_start, &tv_end, 200);
2011*c43e99fdSEd Maste 
2012*c43e99fdSEd Maste 	test_ok = 1;
2013*c43e99fdSEd Maste 
2014*c43e99fdSEd Maste end:
2015*c43e99fdSEd Maste 	cleanup_test();
2016*c43e99fdSEd Maste }
2017*c43e99fdSEd Maste 
2018*c43e99fdSEd Maste static void
2019*c43e99fdSEd Maste break_cb(evutil_socket_t fd, short events, void *arg)
2020*c43e99fdSEd Maste {
2021*c43e99fdSEd Maste 	test_ok = 1;
2022*c43e99fdSEd Maste 	event_loopbreak();
2023*c43e99fdSEd Maste }
2024*c43e99fdSEd Maste 
2025*c43e99fdSEd Maste static void
2026*c43e99fdSEd Maste fail_cb(evutil_socket_t fd, short events, void *arg)
2027*c43e99fdSEd Maste {
2028*c43e99fdSEd Maste 	test_ok = 0;
2029*c43e99fdSEd Maste }
2030*c43e99fdSEd Maste 
2031*c43e99fdSEd Maste static void
2032*c43e99fdSEd Maste test_loopbreak(void)
2033*c43e99fdSEd Maste {
2034*c43e99fdSEd Maste 	struct event ev1, ev2;
2035*c43e99fdSEd Maste 	struct timeval tv;
2036*c43e99fdSEd Maste 
2037*c43e99fdSEd Maste 	setup_test("Loop break: ");
2038*c43e99fdSEd Maste 
2039*c43e99fdSEd Maste 	tv.tv_sec = 0;
2040*c43e99fdSEd Maste 	tv.tv_usec = 0;
2041*c43e99fdSEd Maste 	evtimer_set(&ev1, break_cb, NULL);
2042*c43e99fdSEd Maste 	evtimer_add(&ev1, &tv);
2043*c43e99fdSEd Maste 	evtimer_set(&ev2, fail_cb, NULL);
2044*c43e99fdSEd Maste 	evtimer_add(&ev2, &tv);
2045*c43e99fdSEd Maste 
2046*c43e99fdSEd Maste 	event_dispatch();
2047*c43e99fdSEd Maste 
2048*c43e99fdSEd Maste 	tt_assert(!event_base_got_exit(global_base));
2049*c43e99fdSEd Maste 	tt_assert(event_base_got_break(global_base));
2050*c43e99fdSEd Maste 
2051*c43e99fdSEd Maste 	evtimer_del(&ev1);
2052*c43e99fdSEd Maste 	evtimer_del(&ev2);
2053*c43e99fdSEd Maste 
2054*c43e99fdSEd Maste end:
2055*c43e99fdSEd Maste 	cleanup_test();
2056*c43e99fdSEd Maste }
2057*c43e99fdSEd Maste 
2058*c43e99fdSEd Maste static struct event *readd_test_event_last_added = NULL;
2059*c43e99fdSEd Maste static void
2060*c43e99fdSEd Maste re_add_read_cb(evutil_socket_t fd, short event, void *arg)
2061*c43e99fdSEd Maste {
2062*c43e99fdSEd Maste 	char buf[256];
2063*c43e99fdSEd Maste 	struct event *ev_other = arg;
2064*c43e99fdSEd Maste 	ev_ssize_t n_read;
2065*c43e99fdSEd Maste 
2066*c43e99fdSEd Maste 	readd_test_event_last_added = ev_other;
2067*c43e99fdSEd Maste 
2068*c43e99fdSEd Maste 	n_read = read(fd, buf, sizeof(buf));
2069*c43e99fdSEd Maste 
2070*c43e99fdSEd Maste 	if (n_read < 0) {
2071*c43e99fdSEd Maste 		tt_fail_perror("read");
2072*c43e99fdSEd Maste 		event_base_loopbreak(event_get_base(ev_other));
2073*c43e99fdSEd Maste 		return;
2074*c43e99fdSEd Maste 	} else {
2075*c43e99fdSEd Maste 		event_add(ev_other, NULL);
2076*c43e99fdSEd Maste 		++test_ok;
2077*c43e99fdSEd Maste 	}
2078*c43e99fdSEd Maste }
2079*c43e99fdSEd Maste 
2080*c43e99fdSEd Maste static void
2081*c43e99fdSEd Maste test_nonpersist_readd(void)
2082*c43e99fdSEd Maste {
2083*c43e99fdSEd Maste 	struct event ev1, ev2;
2084*c43e99fdSEd Maste 
2085*c43e99fdSEd Maste 	setup_test("Re-add nonpersistent events: ");
2086*c43e99fdSEd Maste 	event_set(&ev1, pair[0], EV_READ, re_add_read_cb, &ev2);
2087*c43e99fdSEd Maste 	event_set(&ev2, pair[1], EV_READ, re_add_read_cb, &ev1);
2088*c43e99fdSEd Maste 
2089*c43e99fdSEd Maste 	if (write(pair[0], "Hello", 5) < 0) {
2090*c43e99fdSEd Maste 		tt_fail_perror("write(pair[0])");
2091*c43e99fdSEd Maste 	}
2092*c43e99fdSEd Maste 
2093*c43e99fdSEd Maste 	if (write(pair[1], "Hello", 5) < 0) {
2094*c43e99fdSEd Maste 		tt_fail_perror("write(pair[1])\n");
2095*c43e99fdSEd Maste 	}
2096*c43e99fdSEd Maste 
2097*c43e99fdSEd Maste 	if (event_add(&ev1, NULL) == -1 ||
2098*c43e99fdSEd Maste 	    event_add(&ev2, NULL) == -1) {
2099*c43e99fdSEd Maste 		test_ok = 0;
2100*c43e99fdSEd Maste 	}
2101*c43e99fdSEd Maste 	if (test_ok != 0)
2102*c43e99fdSEd Maste 		exit(1);
2103*c43e99fdSEd Maste 	event_loop(EVLOOP_ONCE);
2104*c43e99fdSEd Maste 	if (test_ok != 2)
2105*c43e99fdSEd Maste 		exit(1);
2106*c43e99fdSEd Maste 	/* At this point, we executed both callbacks.  Whichever one got
2107*c43e99fdSEd Maste 	 * called first added the second, but the second then immediately got
2108*c43e99fdSEd Maste 	 * deleted before its callback was called.  At this point, though, it
2109*c43e99fdSEd Maste 	 * re-added the first.
2110*c43e99fdSEd Maste 	 */
2111*c43e99fdSEd Maste 	if (!readd_test_event_last_added) {
2112*c43e99fdSEd Maste 		test_ok = 0;
2113*c43e99fdSEd Maste 	} else if (readd_test_event_last_added == &ev1) {
2114*c43e99fdSEd Maste 		if (!event_pending(&ev1, EV_READ, NULL) ||
2115*c43e99fdSEd Maste 		    event_pending(&ev2, EV_READ, NULL))
2116*c43e99fdSEd Maste 			test_ok = 0;
2117*c43e99fdSEd Maste 	} else {
2118*c43e99fdSEd Maste 		if (event_pending(&ev1, EV_READ, NULL) ||
2119*c43e99fdSEd Maste 		    !event_pending(&ev2, EV_READ, NULL))
2120*c43e99fdSEd Maste 			test_ok = 0;
2121*c43e99fdSEd Maste 	}
2122*c43e99fdSEd Maste 
2123*c43e99fdSEd Maste 	event_del(&ev1);
2124*c43e99fdSEd Maste 	event_del(&ev2);
2125*c43e99fdSEd Maste 
2126*c43e99fdSEd Maste 	cleanup_test();
2127*c43e99fdSEd Maste }
2128*c43e99fdSEd Maste 
2129*c43e99fdSEd Maste struct test_pri_event {
2130*c43e99fdSEd Maste 	struct event ev;
2131*c43e99fdSEd Maste 	int count;
2132*c43e99fdSEd Maste };
2133*c43e99fdSEd Maste 
2134*c43e99fdSEd Maste static void
2135*c43e99fdSEd Maste test_priorities_cb(evutil_socket_t fd, short what, void *arg)
2136*c43e99fdSEd Maste {
2137*c43e99fdSEd Maste 	struct test_pri_event *pri = arg;
2138*c43e99fdSEd Maste 	struct timeval tv;
2139*c43e99fdSEd Maste 
2140*c43e99fdSEd Maste 	if (pri->count == 3) {
2141*c43e99fdSEd Maste 		event_loopexit(NULL);
2142*c43e99fdSEd Maste 		return;
2143*c43e99fdSEd Maste 	}
2144*c43e99fdSEd Maste 
2145*c43e99fdSEd Maste 	pri->count++;
2146*c43e99fdSEd Maste 
2147*c43e99fdSEd Maste 	evutil_timerclear(&tv);
2148*c43e99fdSEd Maste 	event_add(&pri->ev, &tv);
2149*c43e99fdSEd Maste }
2150*c43e99fdSEd Maste 
2151*c43e99fdSEd Maste static void
2152*c43e99fdSEd Maste test_priorities_impl(int npriorities)
2153*c43e99fdSEd Maste {
2154*c43e99fdSEd Maste 	struct test_pri_event one, two;
2155*c43e99fdSEd Maste 	struct timeval tv;
2156*c43e99fdSEd Maste 
2157*c43e99fdSEd Maste 	TT_BLATHER(("Testing Priorities %d: ", npriorities));
2158*c43e99fdSEd Maste 
2159*c43e99fdSEd Maste 	event_base_priority_init(global_base, npriorities);
2160*c43e99fdSEd Maste 
2161*c43e99fdSEd Maste 	memset(&one, 0, sizeof(one));
2162*c43e99fdSEd Maste 	memset(&two, 0, sizeof(two));
2163*c43e99fdSEd Maste 
2164*c43e99fdSEd Maste 	timeout_set(&one.ev, test_priorities_cb, &one);
2165*c43e99fdSEd Maste 	if (event_priority_set(&one.ev, 0) == -1) {
2166*c43e99fdSEd Maste 		fprintf(stderr, "%s: failed to set priority", __func__);
2167*c43e99fdSEd Maste 		exit(1);
2168*c43e99fdSEd Maste 	}
2169*c43e99fdSEd Maste 
2170*c43e99fdSEd Maste 	timeout_set(&two.ev, test_priorities_cb, &two);
2171*c43e99fdSEd Maste 	if (event_priority_set(&two.ev, npriorities - 1) == -1) {
2172*c43e99fdSEd Maste 		fprintf(stderr, "%s: failed to set priority", __func__);
2173*c43e99fdSEd Maste 		exit(1);
2174*c43e99fdSEd Maste 	}
2175*c43e99fdSEd Maste 
2176*c43e99fdSEd Maste 	evutil_timerclear(&tv);
2177*c43e99fdSEd Maste 
2178*c43e99fdSEd Maste 	if (event_add(&one.ev, &tv) == -1)
2179*c43e99fdSEd Maste 		exit(1);
2180*c43e99fdSEd Maste 	if (event_add(&two.ev, &tv) == -1)
2181*c43e99fdSEd Maste 		exit(1);
2182*c43e99fdSEd Maste 
2183*c43e99fdSEd Maste 	event_dispatch();
2184*c43e99fdSEd Maste 
2185*c43e99fdSEd Maste 	event_del(&one.ev);
2186*c43e99fdSEd Maste 	event_del(&two.ev);
2187*c43e99fdSEd Maste 
2188*c43e99fdSEd Maste 	if (npriorities == 1) {
2189*c43e99fdSEd Maste 		if (one.count == 3 && two.count == 3)
2190*c43e99fdSEd Maste 			test_ok = 1;
2191*c43e99fdSEd Maste 	} else if (npriorities == 2) {
2192*c43e99fdSEd Maste 		/* Two is called once because event_loopexit is priority 1 */
2193*c43e99fdSEd Maste 		if (one.count == 3 && two.count == 1)
2194*c43e99fdSEd Maste 			test_ok = 1;
2195*c43e99fdSEd Maste 	} else {
2196*c43e99fdSEd Maste 		if (one.count == 3 && two.count == 0)
2197*c43e99fdSEd Maste 			test_ok = 1;
2198*c43e99fdSEd Maste 	}
2199*c43e99fdSEd Maste }
2200*c43e99fdSEd Maste 
2201*c43e99fdSEd Maste static void
2202*c43e99fdSEd Maste test_priorities(void)
2203*c43e99fdSEd Maste {
2204*c43e99fdSEd Maste 	test_priorities_impl(1);
2205*c43e99fdSEd Maste 	if (test_ok)
2206*c43e99fdSEd Maste 		test_priorities_impl(2);
2207*c43e99fdSEd Maste 	if (test_ok)
2208*c43e99fdSEd Maste 		test_priorities_impl(3);
2209*c43e99fdSEd Maste }
2210*c43e99fdSEd Maste 
2211*c43e99fdSEd Maste /* priority-active-inversion: activate a higher-priority event, and make sure
2212*c43e99fdSEd Maste  * it keeps us from running a lower-priority event first. */
2213*c43e99fdSEd Maste static int n_pai_calls = 0;
2214*c43e99fdSEd Maste static struct event pai_events[3];
2215*c43e99fdSEd Maste 
2216*c43e99fdSEd Maste static void
2217*c43e99fdSEd Maste prio_active_inversion_cb(evutil_socket_t fd, short what, void *arg)
2218*c43e99fdSEd Maste {
2219*c43e99fdSEd Maste 	int *call_order = arg;
2220*c43e99fdSEd Maste 	*call_order = n_pai_calls++;
2221*c43e99fdSEd Maste 	if (n_pai_calls == 1) {
2222*c43e99fdSEd Maste 		/* This should activate later, even though it shares a
2223*c43e99fdSEd Maste 		   priority with us. */
2224*c43e99fdSEd Maste 		event_active(&pai_events[1], EV_READ, 1);
2225*c43e99fdSEd Maste 		/* This should activate next, since its priority is higher,
2226*c43e99fdSEd Maste 		   even though we activated it second. */
2227*c43e99fdSEd Maste 		event_active(&pai_events[2], EV_TIMEOUT, 1);
2228*c43e99fdSEd Maste 	}
2229*c43e99fdSEd Maste }
2230*c43e99fdSEd Maste 
2231*c43e99fdSEd Maste static void
2232*c43e99fdSEd Maste test_priority_active_inversion(void *data_)
2233*c43e99fdSEd Maste {
2234*c43e99fdSEd Maste 	struct basic_test_data *data = data_;
2235*c43e99fdSEd Maste 	struct event_base *base = data->base;
2236*c43e99fdSEd Maste 	int call_order[3];
2237*c43e99fdSEd Maste 	int i;
2238*c43e99fdSEd Maste 	tt_int_op(event_base_priority_init(base, 8), ==, 0);
2239*c43e99fdSEd Maste 
2240*c43e99fdSEd Maste 	n_pai_calls = 0;
2241*c43e99fdSEd Maste 	memset(call_order, 0, sizeof(call_order));
2242*c43e99fdSEd Maste 
2243*c43e99fdSEd Maste 	for (i=0;i<3;++i) {
2244*c43e99fdSEd Maste 		event_assign(&pai_events[i], data->base, -1, 0,
2245*c43e99fdSEd Maste 		    prio_active_inversion_cb, &call_order[i]);
2246*c43e99fdSEd Maste 	}
2247*c43e99fdSEd Maste 
2248*c43e99fdSEd Maste 	event_priority_set(&pai_events[0], 4);
2249*c43e99fdSEd Maste 	event_priority_set(&pai_events[1], 4);
2250*c43e99fdSEd Maste 	event_priority_set(&pai_events[2], 0);
2251*c43e99fdSEd Maste 
2252*c43e99fdSEd Maste 	event_active(&pai_events[0], EV_WRITE, 1);
2253*c43e99fdSEd Maste 
2254*c43e99fdSEd Maste 	event_base_dispatch(base);
2255*c43e99fdSEd Maste 	tt_int_op(n_pai_calls, ==, 3);
2256*c43e99fdSEd Maste 	tt_int_op(call_order[0], ==, 0);
2257*c43e99fdSEd Maste 	tt_int_op(call_order[1], ==, 2);
2258*c43e99fdSEd Maste 	tt_int_op(call_order[2], ==, 1);
2259*c43e99fdSEd Maste end:
2260*c43e99fdSEd Maste 	;
2261*c43e99fdSEd Maste }
2262*c43e99fdSEd Maste 
2263*c43e99fdSEd Maste 
2264*c43e99fdSEd Maste static void
2265*c43e99fdSEd Maste test_multiple_cb(evutil_socket_t fd, short event, void *arg)
2266*c43e99fdSEd Maste {
2267*c43e99fdSEd Maste 	if (event & EV_READ)
2268*c43e99fdSEd Maste 		test_ok |= 1;
2269*c43e99fdSEd Maste 	else if (event & EV_WRITE)
2270*c43e99fdSEd Maste 		test_ok |= 2;
2271*c43e99fdSEd Maste }
2272*c43e99fdSEd Maste 
2273*c43e99fdSEd Maste static void
2274*c43e99fdSEd Maste test_multiple_events_for_same_fd(void)
2275*c43e99fdSEd Maste {
2276*c43e99fdSEd Maste    struct event e1, e2;
2277*c43e99fdSEd Maste 
2278*c43e99fdSEd Maste    setup_test("Multiple events for same fd: ");
2279*c43e99fdSEd Maste 
2280*c43e99fdSEd Maste    event_set(&e1, pair[0], EV_READ, test_multiple_cb, NULL);
2281*c43e99fdSEd Maste    event_add(&e1, NULL);
2282*c43e99fdSEd Maste    event_set(&e2, pair[0], EV_WRITE, test_multiple_cb, NULL);
2283*c43e99fdSEd Maste    event_add(&e2, NULL);
2284*c43e99fdSEd Maste    event_loop(EVLOOP_ONCE);
2285*c43e99fdSEd Maste    event_del(&e2);
2286*c43e99fdSEd Maste 
2287*c43e99fdSEd Maste    if (write(pair[1], TEST1, strlen(TEST1)+1) < 0) {
2288*c43e99fdSEd Maste 	   tt_fail_perror("write");
2289*c43e99fdSEd Maste    }
2290*c43e99fdSEd Maste 
2291*c43e99fdSEd Maste    event_loop(EVLOOP_ONCE);
2292*c43e99fdSEd Maste    event_del(&e1);
2293*c43e99fdSEd Maste 
2294*c43e99fdSEd Maste    if (test_ok != 3)
2295*c43e99fdSEd Maste 	   test_ok = 0;
2296*c43e99fdSEd Maste 
2297*c43e99fdSEd Maste    cleanup_test();
2298*c43e99fdSEd Maste }
2299*c43e99fdSEd Maste 
2300*c43e99fdSEd Maste int evtag_decode_int(ev_uint32_t *pnumber, struct evbuffer *evbuf);
2301*c43e99fdSEd Maste int evtag_decode_int64(ev_uint64_t *pnumber, struct evbuffer *evbuf);
2302*c43e99fdSEd Maste int evtag_encode_tag(struct evbuffer *evbuf, ev_uint32_t number);
2303*c43e99fdSEd Maste int evtag_decode_tag(ev_uint32_t *pnumber, struct evbuffer *evbuf);
2304*c43e99fdSEd Maste 
2305*c43e99fdSEd Maste static void
2306*c43e99fdSEd Maste read_once_cb(evutil_socket_t fd, short event, void *arg)
2307*c43e99fdSEd Maste {
2308*c43e99fdSEd Maste 	char buf[256];
2309*c43e99fdSEd Maste 	int len;
2310*c43e99fdSEd Maste 
2311*c43e99fdSEd Maste 	len = read(fd, buf, sizeof(buf));
2312*c43e99fdSEd Maste 
2313*c43e99fdSEd Maste 	if (called) {
2314*c43e99fdSEd Maste 		test_ok = 0;
2315*c43e99fdSEd Maste 	} else if (len) {
2316*c43e99fdSEd Maste 		/* Assumes global pair[0] can be used for writing */
2317*c43e99fdSEd Maste 		if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) {
2318*c43e99fdSEd Maste 			tt_fail_perror("write");
2319*c43e99fdSEd Maste 			test_ok = 0;
2320*c43e99fdSEd Maste 		} else {
2321*c43e99fdSEd Maste 			test_ok = 1;
2322*c43e99fdSEd Maste 		}
2323*c43e99fdSEd Maste 	}
2324*c43e99fdSEd Maste 
2325*c43e99fdSEd Maste 	called++;
2326*c43e99fdSEd Maste }
2327*c43e99fdSEd Maste 
2328*c43e99fdSEd Maste static void
2329*c43e99fdSEd Maste test_want_only_once(void)
2330*c43e99fdSEd Maste {
2331*c43e99fdSEd Maste 	struct event ev;
2332*c43e99fdSEd Maste 	struct timeval tv;
2333*c43e99fdSEd Maste 
2334*c43e99fdSEd Maste 	/* Very simple read test */
2335*c43e99fdSEd Maste 	setup_test("Want read only once: ");
2336*c43e99fdSEd Maste 
2337*c43e99fdSEd Maste 	if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) {
2338*c43e99fdSEd Maste 		tt_fail_perror("write");
2339*c43e99fdSEd Maste 	}
2340*c43e99fdSEd Maste 
2341*c43e99fdSEd Maste 	/* Setup the loop termination */
2342*c43e99fdSEd Maste 	evutil_timerclear(&tv);
2343*c43e99fdSEd Maste 	tv.tv_usec = 300*1000;
2344*c43e99fdSEd Maste 	event_loopexit(&tv);
2345*c43e99fdSEd Maste 
2346*c43e99fdSEd Maste 	event_set(&ev, pair[1], EV_READ, read_once_cb, &ev);
2347*c43e99fdSEd Maste 	if (event_add(&ev, NULL) == -1)
2348*c43e99fdSEd Maste 		exit(1);
2349*c43e99fdSEd Maste 	event_dispatch();
2350*c43e99fdSEd Maste 
2351*c43e99fdSEd Maste 	cleanup_test();
2352*c43e99fdSEd Maste }
2353*c43e99fdSEd Maste 
2354*c43e99fdSEd Maste #define TEST_MAX_INT	6
2355*c43e99fdSEd Maste 
2356*c43e99fdSEd Maste static void
2357*c43e99fdSEd Maste evtag_int_test(void *ptr)
2358*c43e99fdSEd Maste {
2359*c43e99fdSEd Maste 	struct evbuffer *tmp = evbuffer_new();
2360*c43e99fdSEd Maste 	ev_uint32_t integers[TEST_MAX_INT] = {
2361*c43e99fdSEd Maste 		0xaf0, 0x1000, 0x1, 0xdeadbeef, 0x00, 0xbef000
2362*c43e99fdSEd Maste 	};
2363*c43e99fdSEd Maste 	ev_uint32_t integer;
2364*c43e99fdSEd Maste 	ev_uint64_t big_int;
2365*c43e99fdSEd Maste 	int i;
2366*c43e99fdSEd Maste 
2367*c43e99fdSEd Maste 	evtag_init();
2368*c43e99fdSEd Maste 
2369*c43e99fdSEd Maste 	for (i = 0; i < TEST_MAX_INT; i++) {
2370*c43e99fdSEd Maste 		int oldlen, newlen;
2371*c43e99fdSEd Maste 		oldlen = (int)EVBUFFER_LENGTH(tmp);
2372*c43e99fdSEd Maste 		evtag_encode_int(tmp, integers[i]);
2373*c43e99fdSEd Maste 		newlen = (int)EVBUFFER_LENGTH(tmp);
2374*c43e99fdSEd Maste 		TT_BLATHER(("encoded 0x%08x with %d bytes",
2375*c43e99fdSEd Maste 			(unsigned)integers[i], newlen - oldlen));
2376*c43e99fdSEd Maste 		big_int = integers[i];
2377*c43e99fdSEd Maste 		big_int *= 1000000000; /* 1 billion */
2378*c43e99fdSEd Maste 		evtag_encode_int64(tmp, big_int);
2379*c43e99fdSEd Maste 	}
2380*c43e99fdSEd Maste 
2381*c43e99fdSEd Maste 	for (i = 0; i < TEST_MAX_INT; i++) {
2382*c43e99fdSEd Maste 		tt_int_op(evtag_decode_int(&integer, tmp), !=, -1);
2383*c43e99fdSEd Maste 		tt_uint_op(integer, ==, integers[i]);
2384*c43e99fdSEd Maste 		tt_int_op(evtag_decode_int64(&big_int, tmp), !=, -1);
2385*c43e99fdSEd Maste 		tt_assert((big_int / 1000000000) == integers[i]);
2386*c43e99fdSEd Maste 	}
2387*c43e99fdSEd Maste 
2388*c43e99fdSEd Maste 	tt_uint_op(EVBUFFER_LENGTH(tmp), ==, 0);
2389*c43e99fdSEd Maste end:
2390*c43e99fdSEd Maste 	evbuffer_free(tmp);
2391*c43e99fdSEd Maste }
2392*c43e99fdSEd Maste 
2393*c43e99fdSEd Maste static void
2394*c43e99fdSEd Maste evtag_fuzz(void *ptr)
2395*c43e99fdSEd Maste {
2396*c43e99fdSEd Maste 	unsigned char buffer[4096];
2397*c43e99fdSEd Maste 	struct evbuffer *tmp = evbuffer_new();
2398*c43e99fdSEd Maste 	struct timeval tv;
2399*c43e99fdSEd Maste 	int i, j;
2400*c43e99fdSEd Maste 
2401*c43e99fdSEd Maste 	int not_failed = 0;
2402*c43e99fdSEd Maste 
2403*c43e99fdSEd Maste 	evtag_init();
2404*c43e99fdSEd Maste 
2405*c43e99fdSEd Maste 	for (j = 0; j < 100; j++) {
2406*c43e99fdSEd Maste 		for (i = 0; i < (int)sizeof(buffer); i++)
2407*c43e99fdSEd Maste 			buffer[i] = test_weakrand();
2408*c43e99fdSEd Maste 		evbuffer_drain(tmp, -1);
2409*c43e99fdSEd Maste 		evbuffer_add(tmp, buffer, sizeof(buffer));
2410*c43e99fdSEd Maste 
2411*c43e99fdSEd Maste 		if (evtag_unmarshal_timeval(tmp, 0, &tv) != -1)
2412*c43e99fdSEd Maste 			not_failed++;
2413*c43e99fdSEd Maste 	}
2414*c43e99fdSEd Maste 
2415*c43e99fdSEd Maste 	/* The majority of decodes should fail */
2416*c43e99fdSEd Maste 	tt_int_op(not_failed, <, 10);
2417*c43e99fdSEd Maste 
2418*c43e99fdSEd Maste 	/* Now insert some corruption into the tag length field */
2419*c43e99fdSEd Maste 	evbuffer_drain(tmp, -1);
2420*c43e99fdSEd Maste 	evutil_timerclear(&tv);
2421*c43e99fdSEd Maste 	tv.tv_sec = 1;
2422*c43e99fdSEd Maste 	evtag_marshal_timeval(tmp, 0, &tv);
2423*c43e99fdSEd Maste 	evbuffer_add(tmp, buffer, sizeof(buffer));
2424*c43e99fdSEd Maste 
2425*c43e99fdSEd Maste 	((char *)EVBUFFER_DATA(tmp))[1] = '\xff';
2426*c43e99fdSEd Maste 	if (evtag_unmarshal_timeval(tmp, 0, &tv) != -1) {
2427*c43e99fdSEd Maste 		tt_abort_msg("evtag_unmarshal_timeval should have failed");
2428*c43e99fdSEd Maste 	}
2429*c43e99fdSEd Maste 
2430*c43e99fdSEd Maste end:
2431*c43e99fdSEd Maste 	evbuffer_free(tmp);
2432*c43e99fdSEd Maste }
2433*c43e99fdSEd Maste 
2434*c43e99fdSEd Maste static void
2435*c43e99fdSEd Maste evtag_tag_encoding(void *ptr)
2436*c43e99fdSEd Maste {
2437*c43e99fdSEd Maste 	struct evbuffer *tmp = evbuffer_new();
2438*c43e99fdSEd Maste 	ev_uint32_t integers[TEST_MAX_INT] = {
2439*c43e99fdSEd Maste 		0xaf0, 0x1000, 0x1, 0xdeadbeef, 0x00, 0xbef000
2440*c43e99fdSEd Maste 	};
2441*c43e99fdSEd Maste 	ev_uint32_t integer;
2442*c43e99fdSEd Maste 	int i;
2443*c43e99fdSEd Maste 
2444*c43e99fdSEd Maste 	evtag_init();
2445*c43e99fdSEd Maste 
2446*c43e99fdSEd Maste 	for (i = 0; i < TEST_MAX_INT; i++) {
2447*c43e99fdSEd Maste 		int oldlen, newlen;
2448*c43e99fdSEd Maste 		oldlen = (int)EVBUFFER_LENGTH(tmp);
2449*c43e99fdSEd Maste 		evtag_encode_tag(tmp, integers[i]);
2450*c43e99fdSEd Maste 		newlen = (int)EVBUFFER_LENGTH(tmp);
2451*c43e99fdSEd Maste 		TT_BLATHER(("encoded 0x%08x with %d bytes",
2452*c43e99fdSEd Maste 			(unsigned)integers[i], newlen - oldlen));
2453*c43e99fdSEd Maste 	}
2454*c43e99fdSEd Maste 
2455*c43e99fdSEd Maste 	for (i = 0; i < TEST_MAX_INT; i++) {
2456*c43e99fdSEd Maste 		tt_int_op(evtag_decode_tag(&integer, tmp), !=, -1);
2457*c43e99fdSEd Maste 		tt_uint_op(integer, ==, integers[i]);
2458*c43e99fdSEd Maste 	}
2459*c43e99fdSEd Maste 
2460*c43e99fdSEd Maste 	tt_uint_op(EVBUFFER_LENGTH(tmp), ==, 0);
2461*c43e99fdSEd Maste 
2462*c43e99fdSEd Maste end:
2463*c43e99fdSEd Maste 	evbuffer_free(tmp);
2464*c43e99fdSEd Maste }
2465*c43e99fdSEd Maste 
2466*c43e99fdSEd Maste static void
2467*c43e99fdSEd Maste evtag_test_peek(void *ptr)
2468*c43e99fdSEd Maste {
2469*c43e99fdSEd Maste 	struct evbuffer *tmp = evbuffer_new();
2470*c43e99fdSEd Maste 	ev_uint32_t u32;
2471*c43e99fdSEd Maste 
2472*c43e99fdSEd Maste 	evtag_marshal_int(tmp, 30, 0);
2473*c43e99fdSEd Maste 	evtag_marshal_string(tmp, 40, "Hello world");
2474*c43e99fdSEd Maste 
2475*c43e99fdSEd Maste 	tt_int_op(evtag_peek(tmp, &u32), ==, 1);
2476*c43e99fdSEd Maste 	tt_int_op(u32, ==, 30);
2477*c43e99fdSEd Maste 	tt_int_op(evtag_peek_length(tmp, &u32), ==, 0);
2478*c43e99fdSEd Maste 	tt_int_op(u32, ==, 1+1+1);
2479*c43e99fdSEd Maste 	tt_int_op(evtag_consume(tmp), ==, 0);
2480*c43e99fdSEd Maste 
2481*c43e99fdSEd Maste 	tt_int_op(evtag_peek(tmp, &u32), ==, 1);
2482*c43e99fdSEd Maste 	tt_int_op(u32, ==, 40);
2483*c43e99fdSEd Maste 	tt_int_op(evtag_peek_length(tmp, &u32), ==, 0);
2484*c43e99fdSEd Maste 	tt_int_op(u32, ==, 1+1+11);
2485*c43e99fdSEd Maste 	tt_int_op(evtag_payload_length(tmp, &u32), ==, 0);
2486*c43e99fdSEd Maste 	tt_int_op(u32, ==, 11);
2487*c43e99fdSEd Maste 
2488*c43e99fdSEd Maste end:
2489*c43e99fdSEd Maste 	evbuffer_free(tmp);
2490*c43e99fdSEd Maste }
2491*c43e99fdSEd Maste 
2492*c43e99fdSEd Maste 
2493*c43e99fdSEd Maste static void
2494*c43e99fdSEd Maste test_methods(void *ptr)
2495*c43e99fdSEd Maste {
2496*c43e99fdSEd Maste 	const char **methods = event_get_supported_methods();
2497*c43e99fdSEd Maste 	struct event_config *cfg = NULL;
2498*c43e99fdSEd Maste 	struct event_base *base = NULL;
2499*c43e99fdSEd Maste 	const char *backend;
2500*c43e99fdSEd Maste 	int n_methods = 0;
2501*c43e99fdSEd Maste 
2502*c43e99fdSEd Maste 	tt_assert(methods);
2503*c43e99fdSEd Maste 
2504*c43e99fdSEd Maste 	backend = methods[0];
2505*c43e99fdSEd Maste 	while (*methods != NULL) {
2506*c43e99fdSEd Maste 		TT_BLATHER(("Support method: %s", *methods));
2507*c43e99fdSEd Maste 		++methods;
2508*c43e99fdSEd Maste 		++n_methods;
2509*c43e99fdSEd Maste 	}
2510*c43e99fdSEd Maste 
2511*c43e99fdSEd Maste 	cfg = event_config_new();
2512*c43e99fdSEd Maste 	assert(cfg != NULL);
2513*c43e99fdSEd Maste 
2514*c43e99fdSEd Maste 	tt_int_op(event_config_avoid_method(cfg, backend), ==, 0);
2515*c43e99fdSEd Maste 	event_config_set_flag(cfg, EVENT_BASE_FLAG_IGNORE_ENV);
2516*c43e99fdSEd Maste 
2517*c43e99fdSEd Maste 	base = event_base_new_with_config(cfg);
2518*c43e99fdSEd Maste 	if (n_methods > 1) {
2519*c43e99fdSEd Maste 		tt_assert(base);
2520*c43e99fdSEd Maste 		tt_str_op(backend, !=, event_base_get_method(base));
2521*c43e99fdSEd Maste 	} else {
2522*c43e99fdSEd Maste 		tt_assert(base == NULL);
2523*c43e99fdSEd Maste 	}
2524*c43e99fdSEd Maste 
2525*c43e99fdSEd Maste end:
2526*c43e99fdSEd Maste 	if (base)
2527*c43e99fdSEd Maste 		event_base_free(base);
2528*c43e99fdSEd Maste 	if (cfg)
2529*c43e99fdSEd Maste 		event_config_free(cfg);
2530*c43e99fdSEd Maste }
2531*c43e99fdSEd Maste 
2532*c43e99fdSEd Maste static void
2533*c43e99fdSEd Maste test_version(void *arg)
2534*c43e99fdSEd Maste {
2535*c43e99fdSEd Maste 	const char *vstr;
2536*c43e99fdSEd Maste 	ev_uint32_t vint;
2537*c43e99fdSEd Maste 	int major, minor, patch, n;
2538*c43e99fdSEd Maste 
2539*c43e99fdSEd Maste 	vstr = event_get_version();
2540*c43e99fdSEd Maste 	vint = event_get_version_number();
2541*c43e99fdSEd Maste 
2542*c43e99fdSEd Maste 	tt_assert(vstr);
2543*c43e99fdSEd Maste 	tt_assert(vint);
2544*c43e99fdSEd Maste 
2545*c43e99fdSEd Maste 	tt_str_op(vstr, ==, LIBEVENT_VERSION);
2546*c43e99fdSEd Maste 	tt_int_op(vint, ==, LIBEVENT_VERSION_NUMBER);
2547*c43e99fdSEd Maste 
2548*c43e99fdSEd Maste 	n = sscanf(vstr, "%d.%d.%d", &major, &minor, &patch);
2549*c43e99fdSEd Maste 	tt_assert(3 == n);
2550*c43e99fdSEd Maste 	tt_int_op((vint&0xffffff00), ==, ((major<<24)|(minor<<16)|(patch<<8)));
2551*c43e99fdSEd Maste end:
2552*c43e99fdSEd Maste 	;
2553*c43e99fdSEd Maste }
2554*c43e99fdSEd Maste 
2555*c43e99fdSEd Maste static void
2556*c43e99fdSEd Maste test_base_features(void *arg)
2557*c43e99fdSEd Maste {
2558*c43e99fdSEd Maste 	struct event_base *base = NULL;
2559*c43e99fdSEd Maste 	struct event_config *cfg = NULL;
2560*c43e99fdSEd Maste 
2561*c43e99fdSEd Maste 	cfg = event_config_new();
2562*c43e99fdSEd Maste 
2563*c43e99fdSEd Maste 	tt_assert(0 == event_config_require_features(cfg, EV_FEATURE_ET));
2564*c43e99fdSEd Maste 
2565*c43e99fdSEd Maste 	base = event_base_new_with_config(cfg);
2566*c43e99fdSEd Maste 	if (base) {
2567*c43e99fdSEd Maste 		tt_int_op(EV_FEATURE_ET, ==,
2568*c43e99fdSEd Maste 		    event_base_get_features(base) & EV_FEATURE_ET);
2569*c43e99fdSEd Maste 	} else {
2570*c43e99fdSEd Maste 		base = event_base_new();
2571*c43e99fdSEd Maste 		tt_int_op(0, ==, event_base_get_features(base) & EV_FEATURE_ET);
2572*c43e99fdSEd Maste 	}
2573*c43e99fdSEd Maste 
2574*c43e99fdSEd Maste end:
2575*c43e99fdSEd Maste 	if (base)
2576*c43e99fdSEd Maste 		event_base_free(base);
2577*c43e99fdSEd Maste 	if (cfg)
2578*c43e99fdSEd Maste 		event_config_free(cfg);
2579*c43e99fdSEd Maste }
2580*c43e99fdSEd Maste 
2581*c43e99fdSEd Maste #ifdef EVENT__HAVE_SETENV
2582*c43e99fdSEd Maste #define SETENV_OK
2583*c43e99fdSEd Maste #elif !defined(EVENT__HAVE_SETENV) && defined(EVENT__HAVE_PUTENV)
2584*c43e99fdSEd Maste static void setenv(const char *k, const char *v, int o_)
2585*c43e99fdSEd Maste {
2586*c43e99fdSEd Maste 	char b[256];
2587*c43e99fdSEd Maste 	evutil_snprintf(b, sizeof(b), "%s=%s",k,v);
2588*c43e99fdSEd Maste 	putenv(b);
2589*c43e99fdSEd Maste }
2590*c43e99fdSEd Maste #define SETENV_OK
2591*c43e99fdSEd Maste #endif
2592*c43e99fdSEd Maste 
2593*c43e99fdSEd Maste #ifdef EVENT__HAVE_UNSETENV
2594*c43e99fdSEd Maste #define UNSETENV_OK
2595*c43e99fdSEd Maste #elif !defined(EVENT__HAVE_UNSETENV) && defined(EVENT__HAVE_PUTENV)
2596*c43e99fdSEd Maste static void unsetenv(const char *k)
2597*c43e99fdSEd Maste {
2598*c43e99fdSEd Maste 	char b[256];
2599*c43e99fdSEd Maste 	evutil_snprintf(b, sizeof(b), "%s=",k);
2600*c43e99fdSEd Maste 	putenv(b);
2601*c43e99fdSEd Maste }
2602*c43e99fdSEd Maste #define UNSETENV_OK
2603*c43e99fdSEd Maste #endif
2604*c43e99fdSEd Maste 
2605*c43e99fdSEd Maste #if defined(SETENV_OK) && defined(UNSETENV_OK)
2606*c43e99fdSEd Maste static void
2607*c43e99fdSEd Maste methodname_to_envvar(const char *mname, char *buf, size_t buflen)
2608*c43e99fdSEd Maste {
2609*c43e99fdSEd Maste 	char *cp;
2610*c43e99fdSEd Maste 	evutil_snprintf(buf, buflen, "EVENT_NO%s", mname);
2611*c43e99fdSEd Maste 	for (cp = buf; *cp; ++cp) {
2612*c43e99fdSEd Maste 		*cp = EVUTIL_TOUPPER_(*cp);
2613*c43e99fdSEd Maste 	}
2614*c43e99fdSEd Maste }
2615*c43e99fdSEd Maste #endif
2616*c43e99fdSEd Maste 
2617*c43e99fdSEd Maste static void
2618*c43e99fdSEd Maste test_base_environ(void *arg)
2619*c43e99fdSEd Maste {
2620*c43e99fdSEd Maste 	struct event_base *base = NULL;
2621*c43e99fdSEd Maste 	struct event_config *cfg = NULL;
2622*c43e99fdSEd Maste 
2623*c43e99fdSEd Maste #if defined(SETENV_OK) && defined(UNSETENV_OK)
2624*c43e99fdSEd Maste 	const char **basenames;
2625*c43e99fdSEd Maste 	int i, n_methods=0;
2626*c43e99fdSEd Maste 	char varbuf[128];
2627*c43e99fdSEd Maste 	const char *defaultname, *ignoreenvname;
2628*c43e99fdSEd Maste 
2629*c43e99fdSEd Maste 	/* See if unsetenv works before we rely on it. */
2630*c43e99fdSEd Maste 	setenv("EVENT_NOWAFFLES", "1", 1);
2631*c43e99fdSEd Maste 	unsetenv("EVENT_NOWAFFLES");
2632*c43e99fdSEd Maste 	if (getenv("EVENT_NOWAFFLES") != NULL) {
2633*c43e99fdSEd Maste #ifndef EVENT__HAVE_UNSETENV
2634*c43e99fdSEd Maste 		TT_DECLARE("NOTE", ("Can't fake unsetenv; skipping test"));
2635*c43e99fdSEd Maste #else
2636*c43e99fdSEd Maste 		TT_DECLARE("NOTE", ("unsetenv doesn't work; skipping test"));
2637*c43e99fdSEd Maste #endif
2638*c43e99fdSEd Maste 		tt_skip();
2639*c43e99fdSEd Maste 	}
2640*c43e99fdSEd Maste 
2641*c43e99fdSEd Maste 	basenames = event_get_supported_methods();
2642*c43e99fdSEd Maste 	for (i = 0; basenames[i]; ++i) {
2643*c43e99fdSEd Maste 		methodname_to_envvar(basenames[i], varbuf, sizeof(varbuf));
2644*c43e99fdSEd Maste 		unsetenv(varbuf);
2645*c43e99fdSEd Maste 		++n_methods;
2646*c43e99fdSEd Maste 	}
2647*c43e99fdSEd Maste 
2648*c43e99fdSEd Maste 	base = event_base_new();
2649*c43e99fdSEd Maste 	tt_assert(base);
2650*c43e99fdSEd Maste 
2651*c43e99fdSEd Maste 	defaultname = event_base_get_method(base);
2652*c43e99fdSEd Maste 	TT_BLATHER(("default is <%s>", defaultname));
2653*c43e99fdSEd Maste 	event_base_free(base);
2654*c43e99fdSEd Maste 	base = NULL;
2655*c43e99fdSEd Maste 
2656*c43e99fdSEd Maste 	/* Can we disable the method with EVENT_NOfoo ? */
2657*c43e99fdSEd Maste 	if (!strcmp(defaultname, "epoll (with changelist)")) {
2658*c43e99fdSEd Maste  		setenv("EVENT_NOEPOLL", "1", 1);
2659*c43e99fdSEd Maste 		ignoreenvname = "epoll";
2660*c43e99fdSEd Maste 	} else {
2661*c43e99fdSEd Maste 		methodname_to_envvar(defaultname, varbuf, sizeof(varbuf));
2662*c43e99fdSEd Maste 		setenv(varbuf, "1", 1);
2663*c43e99fdSEd Maste 		ignoreenvname = defaultname;
2664*c43e99fdSEd Maste 	}
2665*c43e99fdSEd Maste 
2666*c43e99fdSEd Maste 	/* Use an empty cfg rather than NULL so a failure doesn't exit() */
2667*c43e99fdSEd Maste 	cfg = event_config_new();
2668*c43e99fdSEd Maste 	base = event_base_new_with_config(cfg);
2669*c43e99fdSEd Maste 	event_config_free(cfg);
2670*c43e99fdSEd Maste 	cfg = NULL;
2671*c43e99fdSEd Maste 	if (n_methods == 1) {
2672*c43e99fdSEd Maste 		tt_assert(!base);
2673*c43e99fdSEd Maste 	} else {
2674*c43e99fdSEd Maste 		tt_assert(base);
2675*c43e99fdSEd Maste 		tt_str_op(defaultname, !=, event_base_get_method(base));
2676*c43e99fdSEd Maste 		event_base_free(base);
2677*c43e99fdSEd Maste 		base = NULL;
2678*c43e99fdSEd Maste 	}
2679*c43e99fdSEd Maste 
2680*c43e99fdSEd Maste 	/* Can we disable looking at the environment with IGNORE_ENV ? */
2681*c43e99fdSEd Maste 	cfg = event_config_new();
2682*c43e99fdSEd Maste 	event_config_set_flag(cfg, EVENT_BASE_FLAG_IGNORE_ENV);
2683*c43e99fdSEd Maste 	base = event_base_new_with_config(cfg);
2684*c43e99fdSEd Maste 	tt_assert(base);
2685*c43e99fdSEd Maste 	tt_str_op(ignoreenvname, ==, event_base_get_method(base));
2686*c43e99fdSEd Maste #else
2687*c43e99fdSEd Maste 	tt_skip();
2688*c43e99fdSEd Maste #endif
2689*c43e99fdSEd Maste 
2690*c43e99fdSEd Maste end:
2691*c43e99fdSEd Maste 	if (base)
2692*c43e99fdSEd Maste 		event_base_free(base);
2693*c43e99fdSEd Maste 	if (cfg)
2694*c43e99fdSEd Maste 		event_config_free(cfg);
2695*c43e99fdSEd Maste }
2696*c43e99fdSEd Maste 
2697*c43e99fdSEd Maste static void
2698*c43e99fdSEd Maste read_called_once_cb(evutil_socket_t fd, short event, void *arg)
2699*c43e99fdSEd Maste {
2700*c43e99fdSEd Maste 	tt_int_op(event, ==, EV_READ);
2701*c43e99fdSEd Maste 	called += 1;
2702*c43e99fdSEd Maste end:
2703*c43e99fdSEd Maste 	;
2704*c43e99fdSEd Maste }
2705*c43e99fdSEd Maste 
2706*c43e99fdSEd Maste static void
2707*c43e99fdSEd Maste timeout_called_once_cb(evutil_socket_t fd, short event, void *arg)
2708*c43e99fdSEd Maste {
2709*c43e99fdSEd Maste 	tt_int_op(event, ==, EV_TIMEOUT);
2710*c43e99fdSEd Maste 	called += 100;
2711*c43e99fdSEd Maste end:
2712*c43e99fdSEd Maste 	;
2713*c43e99fdSEd Maste }
2714*c43e99fdSEd Maste 
2715*c43e99fdSEd Maste static void
2716*c43e99fdSEd Maste immediate_called_twice_cb(evutil_socket_t fd, short event, void *arg)
2717*c43e99fdSEd Maste {
2718*c43e99fdSEd Maste 	tt_int_op(event, ==, EV_TIMEOUT);
2719*c43e99fdSEd Maste 	called += 1000;
2720*c43e99fdSEd Maste end:
2721*c43e99fdSEd Maste 	;
2722*c43e99fdSEd Maste }
2723*c43e99fdSEd Maste 
2724*c43e99fdSEd Maste static void
2725*c43e99fdSEd Maste test_event_once(void *ptr)
2726*c43e99fdSEd Maste {
2727*c43e99fdSEd Maste 	struct basic_test_data *data = ptr;
2728*c43e99fdSEd Maste 	struct timeval tv;
2729*c43e99fdSEd Maste 	int r;
2730*c43e99fdSEd Maste 
2731*c43e99fdSEd Maste 	tv.tv_sec = 0;
2732*c43e99fdSEd Maste 	tv.tv_usec = 50*1000;
2733*c43e99fdSEd Maste 	called = 0;
2734*c43e99fdSEd Maste 	r = event_base_once(data->base, data->pair[0], EV_READ,
2735*c43e99fdSEd Maste 	    read_called_once_cb, NULL, NULL);
2736*c43e99fdSEd Maste 	tt_int_op(r, ==, 0);
2737*c43e99fdSEd Maste 	r = event_base_once(data->base, -1, EV_TIMEOUT,
2738*c43e99fdSEd Maste 	    timeout_called_once_cb, NULL, &tv);
2739*c43e99fdSEd Maste 	tt_int_op(r, ==, 0);
2740*c43e99fdSEd Maste 	r = event_base_once(data->base, -1, 0, NULL, NULL, NULL);
2741*c43e99fdSEd Maste 	tt_int_op(r, <, 0);
2742*c43e99fdSEd Maste 	r = event_base_once(data->base, -1, EV_TIMEOUT,
2743*c43e99fdSEd Maste 	    immediate_called_twice_cb, NULL, NULL);
2744*c43e99fdSEd Maste 	tt_int_op(r, ==, 0);
2745*c43e99fdSEd Maste 	tv.tv_sec = 0;
2746*c43e99fdSEd Maste 	tv.tv_usec = 0;
2747*c43e99fdSEd Maste 	r = event_base_once(data->base, -1, EV_TIMEOUT,
2748*c43e99fdSEd Maste 	    immediate_called_twice_cb, NULL, &tv);
2749*c43e99fdSEd Maste 	tt_int_op(r, ==, 0);
2750*c43e99fdSEd Maste 
2751*c43e99fdSEd Maste 	if (write(data->pair[1], TEST1, strlen(TEST1)+1) < 0) {
2752*c43e99fdSEd Maste 		tt_fail_perror("write");
2753*c43e99fdSEd Maste 	}
2754*c43e99fdSEd Maste 
2755*c43e99fdSEd Maste 	shutdown(data->pair[1], EVUTIL_SHUT_WR);
2756*c43e99fdSEd Maste 
2757*c43e99fdSEd Maste 	event_base_dispatch(data->base);
2758*c43e99fdSEd Maste 
2759*c43e99fdSEd Maste 	tt_int_op(called, ==, 2101);
2760*c43e99fdSEd Maste end:
2761*c43e99fdSEd Maste 	;
2762*c43e99fdSEd Maste }
2763*c43e99fdSEd Maste 
2764*c43e99fdSEd Maste static void
2765*c43e99fdSEd Maste test_event_once_never(void *ptr)
2766*c43e99fdSEd Maste {
2767*c43e99fdSEd Maste 	struct basic_test_data *data = ptr;
2768*c43e99fdSEd Maste 	struct timeval tv;
2769*c43e99fdSEd Maste 
2770*c43e99fdSEd Maste 	/* Have one trigger in 10 seconds (don't worry, because) */
2771*c43e99fdSEd Maste 	tv.tv_sec = 10;
2772*c43e99fdSEd Maste 	tv.tv_usec = 0;
2773*c43e99fdSEd Maste 	called = 0;
2774*c43e99fdSEd Maste 	event_base_once(data->base, -1, EV_TIMEOUT,
2775*c43e99fdSEd Maste 	    timeout_called_once_cb, NULL, &tv);
2776*c43e99fdSEd Maste 
2777*c43e99fdSEd Maste 	/* But shut down the base in 75 msec. */
2778*c43e99fdSEd Maste 	tv.tv_sec = 0;
2779*c43e99fdSEd Maste 	tv.tv_usec = 75*1000;
2780*c43e99fdSEd Maste 	event_base_loopexit(data->base, &tv);
2781*c43e99fdSEd Maste 
2782*c43e99fdSEd Maste 	event_base_dispatch(data->base);
2783*c43e99fdSEd Maste 
2784*c43e99fdSEd Maste 	tt_int_op(called, ==, 0);
2785*c43e99fdSEd Maste end:
2786*c43e99fdSEd Maste 	;
2787*c43e99fdSEd Maste }
2788*c43e99fdSEd Maste 
2789*c43e99fdSEd Maste static void
2790*c43e99fdSEd Maste test_event_pending(void *ptr)
2791*c43e99fdSEd Maste {
2792*c43e99fdSEd Maste 	struct basic_test_data *data = ptr;
2793*c43e99fdSEd Maste 	struct event *r=NULL, *w=NULL, *t=NULL;
2794*c43e99fdSEd Maste 	struct timeval tv, now, tv2;
2795*c43e99fdSEd Maste 
2796*c43e99fdSEd Maste 	tv.tv_sec = 0;
2797*c43e99fdSEd Maste 	tv.tv_usec = 500 * 1000;
2798*c43e99fdSEd Maste 	r = event_new(data->base, data->pair[0], EV_READ, simple_read_cb,
2799*c43e99fdSEd Maste 	    NULL);
2800*c43e99fdSEd Maste 	w = event_new(data->base, data->pair[1], EV_WRITE, simple_write_cb,
2801*c43e99fdSEd Maste 	    NULL);
2802*c43e99fdSEd Maste 	t = evtimer_new(data->base, timeout_cb, NULL);
2803*c43e99fdSEd Maste 
2804*c43e99fdSEd Maste 	tt_assert(r);
2805*c43e99fdSEd Maste 	tt_assert(w);
2806*c43e99fdSEd Maste 	tt_assert(t);
2807*c43e99fdSEd Maste 
2808*c43e99fdSEd Maste 	evutil_gettimeofday(&now, NULL);
2809*c43e99fdSEd Maste 	event_add(r, NULL);
2810*c43e99fdSEd Maste 	event_add(t, &tv);
2811*c43e99fdSEd Maste 
2812*c43e99fdSEd Maste 	tt_assert( event_pending(r, EV_READ, NULL));
2813*c43e99fdSEd Maste 	tt_assert(!event_pending(w, EV_WRITE, NULL));
2814*c43e99fdSEd Maste 	tt_assert(!event_pending(r, EV_WRITE, NULL));
2815*c43e99fdSEd Maste 	tt_assert( event_pending(r, EV_READ|EV_WRITE, NULL));
2816*c43e99fdSEd Maste 	tt_assert(!event_pending(r, EV_TIMEOUT, NULL));
2817*c43e99fdSEd Maste 	tt_assert( event_pending(t, EV_TIMEOUT, NULL));
2818*c43e99fdSEd Maste 	tt_assert( event_pending(t, EV_TIMEOUT, &tv2));
2819*c43e99fdSEd Maste 
2820*c43e99fdSEd Maste 	tt_assert(evutil_timercmp(&tv2, &now, >));
2821*c43e99fdSEd Maste 
2822*c43e99fdSEd Maste 	test_timeval_diff_eq(&now, &tv2, 500);
2823*c43e99fdSEd Maste 
2824*c43e99fdSEd Maste end:
2825*c43e99fdSEd Maste 	if (r) {
2826*c43e99fdSEd Maste 		event_del(r);
2827*c43e99fdSEd Maste 		event_free(r);
2828*c43e99fdSEd Maste 	}
2829*c43e99fdSEd Maste 	if (w) {
2830*c43e99fdSEd Maste 		event_del(w);
2831*c43e99fdSEd Maste 		event_free(w);
2832*c43e99fdSEd Maste 	}
2833*c43e99fdSEd Maste 	if (t) {
2834*c43e99fdSEd Maste 		event_del(t);
2835*c43e99fdSEd Maste 		event_free(t);
2836*c43e99fdSEd Maste 	}
2837*c43e99fdSEd Maste }
2838*c43e99fdSEd Maste 
2839*c43e99fdSEd Maste static void
2840*c43e99fdSEd Maste dfd_cb(evutil_socket_t fd, short e, void *data)
2841*c43e99fdSEd Maste {
2842*c43e99fdSEd Maste 	*(int*)data = (int)e;
2843*c43e99fdSEd Maste }
2844*c43e99fdSEd Maste 
2845*c43e99fdSEd Maste static void
2846*c43e99fdSEd Maste test_event_closed_fd_poll(void *arg)
2847*c43e99fdSEd Maste {
2848*c43e99fdSEd Maste 	struct timeval tv;
2849*c43e99fdSEd Maste 	struct event *e;
2850*c43e99fdSEd Maste 	struct basic_test_data *data = (struct basic_test_data *)arg;
2851*c43e99fdSEd Maste 	int i = 0;
2852*c43e99fdSEd Maste 
2853*c43e99fdSEd Maste 	if (strcmp(event_base_get_method(data->base), "poll")) {
2854*c43e99fdSEd Maste 		tinytest_set_test_skipped_();
2855*c43e99fdSEd Maste 		return;
2856*c43e99fdSEd Maste 	}
2857*c43e99fdSEd Maste 
2858*c43e99fdSEd Maste 	e = event_new(data->base, data->pair[0], EV_READ, dfd_cb, &i);
2859*c43e99fdSEd Maste 	tt_assert(e);
2860*c43e99fdSEd Maste 
2861*c43e99fdSEd Maste 	tv.tv_sec = 0;
2862*c43e99fdSEd Maste 	tv.tv_usec = 500 * 1000;
2863*c43e99fdSEd Maste 	event_add(e, &tv);
2864*c43e99fdSEd Maste 	tt_assert(event_pending(e, EV_READ, NULL));
2865*c43e99fdSEd Maste 	close(data->pair[0]);
2866*c43e99fdSEd Maste 	data->pair[0] = -1; /** avoids double-close */
2867*c43e99fdSEd Maste 	event_base_loop(data->base, EVLOOP_ONCE);
2868*c43e99fdSEd Maste 	tt_int_op(i, ==, EV_READ);
2869*c43e99fdSEd Maste 
2870*c43e99fdSEd Maste end:
2871*c43e99fdSEd Maste 	if (e) {
2872*c43e99fdSEd Maste 		event_del(e);
2873*c43e99fdSEd Maste 		event_free(e);
2874*c43e99fdSEd Maste 	}
2875*c43e99fdSEd Maste }
2876*c43e99fdSEd Maste 
2877*c43e99fdSEd Maste #ifndef _WIN32
2878*c43e99fdSEd Maste /* You can't do this test on windows, since dup2 doesn't work on sockets */
2879*c43e99fdSEd Maste 
2880*c43e99fdSEd Maste /* Regression test for our workaround for a fun epoll/linux related bug
2881*c43e99fdSEd Maste  * where fd2 = dup(fd1); add(fd2); close(fd2); dup2(fd1,fd2); add(fd2)
2882*c43e99fdSEd Maste  * will get you an EEXIST */
2883*c43e99fdSEd Maste static void
2884*c43e99fdSEd Maste test_dup_fd(void *arg)
2885*c43e99fdSEd Maste {
2886*c43e99fdSEd Maste 	struct basic_test_data *data = arg;
2887*c43e99fdSEd Maste 	struct event_base *base = data->base;
2888*c43e99fdSEd Maste 	struct event *ev1=NULL, *ev2=NULL;
2889*c43e99fdSEd Maste 	int fd, dfd=-1;
2890*c43e99fdSEd Maste 	int ev1_got, ev2_got;
2891*c43e99fdSEd Maste 
2892*c43e99fdSEd Maste 	tt_int_op(write(data->pair[0], "Hello world",
2893*c43e99fdSEd Maste 		strlen("Hello world")), >, 0);
2894*c43e99fdSEd Maste 	fd = data->pair[1];
2895*c43e99fdSEd Maste 
2896*c43e99fdSEd Maste 	dfd = dup(fd);
2897*c43e99fdSEd Maste 	tt_int_op(dfd, >=, 0);
2898*c43e99fdSEd Maste 
2899*c43e99fdSEd Maste 	ev1 = event_new(base, fd, EV_READ|EV_PERSIST, dfd_cb, &ev1_got);
2900*c43e99fdSEd Maste 	ev2 = event_new(base, dfd, EV_READ|EV_PERSIST, dfd_cb, &ev2_got);
2901*c43e99fdSEd Maste 	ev1_got = ev2_got = 0;
2902*c43e99fdSEd Maste 	event_add(ev1, NULL);
2903*c43e99fdSEd Maste 	event_add(ev2, NULL);
2904*c43e99fdSEd Maste 	event_base_loop(base, EVLOOP_ONCE);
2905*c43e99fdSEd Maste 	tt_int_op(ev1_got, ==, EV_READ);
2906*c43e99fdSEd Maste 	tt_int_op(ev2_got, ==, EV_READ);
2907*c43e99fdSEd Maste 
2908*c43e99fdSEd Maste 	/* Now close and delete dfd then dispatch.  We need to do the
2909*c43e99fdSEd Maste 	 * dispatch here so that when we add it later, we think there
2910*c43e99fdSEd Maste 	 * was an intermediate delete. */
2911*c43e99fdSEd Maste 	close(dfd);
2912*c43e99fdSEd Maste 	event_del(ev2);
2913*c43e99fdSEd Maste 	ev1_got = ev2_got = 0;
2914*c43e99fdSEd Maste 	event_base_loop(base, EVLOOP_ONCE);
2915*c43e99fdSEd Maste 	tt_want_int_op(ev1_got, ==, EV_READ);
2916*c43e99fdSEd Maste 	tt_int_op(ev2_got, ==, 0);
2917*c43e99fdSEd Maste 
2918*c43e99fdSEd Maste 	/* Re-duplicate the fd.  We need to get the same duplicated
2919*c43e99fdSEd Maste 	 * value that we closed to provoke the epoll quirk.  Also, we
2920*c43e99fdSEd Maste 	 * need to change the events to write, or else the old lingering
2921*c43e99fdSEd Maste 	 * read event will make the test pass whether the change was
2922*c43e99fdSEd Maste 	 * successful or not. */
2923*c43e99fdSEd Maste 	tt_int_op(dup2(fd, dfd), ==, dfd);
2924*c43e99fdSEd Maste 	event_free(ev2);
2925*c43e99fdSEd Maste 	ev2 = event_new(base, dfd, EV_WRITE|EV_PERSIST, dfd_cb, &ev2_got);
2926*c43e99fdSEd Maste 	event_add(ev2, NULL);
2927*c43e99fdSEd Maste 	ev1_got = ev2_got = 0;
2928*c43e99fdSEd Maste 	event_base_loop(base, EVLOOP_ONCE);
2929*c43e99fdSEd Maste 	tt_want_int_op(ev1_got, ==, EV_READ);
2930*c43e99fdSEd Maste 	tt_int_op(ev2_got, ==, EV_WRITE);
2931*c43e99fdSEd Maste 
2932*c43e99fdSEd Maste end:
2933*c43e99fdSEd Maste 	if (ev1)
2934*c43e99fdSEd Maste 		event_free(ev1);
2935*c43e99fdSEd Maste 	if (ev2)
2936*c43e99fdSEd Maste 		event_free(ev2);
2937*c43e99fdSEd Maste 	if (dfd >= 0)
2938*c43e99fdSEd Maste 		close(dfd);
2939*c43e99fdSEd Maste }
2940*c43e99fdSEd Maste #endif
2941*c43e99fdSEd Maste 
2942*c43e99fdSEd Maste #ifdef EVENT__DISABLE_MM_REPLACEMENT
2943*c43e99fdSEd Maste static void
2944*c43e99fdSEd Maste test_mm_functions(void *arg)
2945*c43e99fdSEd Maste {
2946*c43e99fdSEd Maste 	tinytest_set_test_skipped_();
2947*c43e99fdSEd Maste }
2948*c43e99fdSEd Maste #else
2949*c43e99fdSEd Maste static int
2950*c43e99fdSEd Maste check_dummy_mem_ok(void *mem_)
2951*c43e99fdSEd Maste {
2952*c43e99fdSEd Maste 	char *mem = mem_;
2953*c43e99fdSEd Maste 	mem -= 16;
2954*c43e99fdSEd Maste 	return !memcmp(mem, "{[<guardedram>]}", 16);
2955*c43e99fdSEd Maste }
2956*c43e99fdSEd Maste 
2957*c43e99fdSEd Maste static void *
2958*c43e99fdSEd Maste dummy_malloc(size_t len)
2959*c43e99fdSEd Maste {
2960*c43e99fdSEd Maste 	char *mem = malloc(len+16);
2961*c43e99fdSEd Maste 	memcpy(mem, "{[<guardedram>]}", 16);
2962*c43e99fdSEd Maste 	return mem+16;
2963*c43e99fdSEd Maste }
2964*c43e99fdSEd Maste 
2965*c43e99fdSEd Maste static void *
2966*c43e99fdSEd Maste dummy_realloc(void *mem_, size_t len)
2967*c43e99fdSEd Maste {
2968*c43e99fdSEd Maste 	char *mem = mem_;
2969*c43e99fdSEd Maste 	if (!mem)
2970*c43e99fdSEd Maste 		return dummy_malloc(len);
2971*c43e99fdSEd Maste 	tt_want(check_dummy_mem_ok(mem_));
2972*c43e99fdSEd Maste 	mem -= 16;
2973*c43e99fdSEd Maste 	mem = realloc(mem, len+16);
2974*c43e99fdSEd Maste 	return mem+16;
2975*c43e99fdSEd Maste }
2976*c43e99fdSEd Maste 
2977*c43e99fdSEd Maste static void
2978*c43e99fdSEd Maste dummy_free(void *mem_)
2979*c43e99fdSEd Maste {
2980*c43e99fdSEd Maste 	char *mem = mem_;
2981*c43e99fdSEd Maste 	tt_want(check_dummy_mem_ok(mem_));
2982*c43e99fdSEd Maste 	mem -= 16;
2983*c43e99fdSEd Maste 	free(mem);
2984*c43e99fdSEd Maste }
2985*c43e99fdSEd Maste 
2986*c43e99fdSEd Maste static void
2987*c43e99fdSEd Maste test_mm_functions(void *arg)
2988*c43e99fdSEd Maste {
2989*c43e99fdSEd Maste 	struct event_base *b = NULL;
2990*c43e99fdSEd Maste 	struct event_config *cfg = NULL;
2991*c43e99fdSEd Maste 	event_set_mem_functions(dummy_malloc, dummy_realloc, dummy_free);
2992*c43e99fdSEd Maste 	cfg = event_config_new();
2993*c43e99fdSEd Maste 	event_config_avoid_method(cfg, "Nonesuch");
2994*c43e99fdSEd Maste 	b = event_base_new_with_config(cfg);
2995*c43e99fdSEd Maste 	tt_assert(b);
2996*c43e99fdSEd Maste 	tt_assert(check_dummy_mem_ok(b));
2997*c43e99fdSEd Maste end:
2998*c43e99fdSEd Maste 	if (cfg)
2999*c43e99fdSEd Maste 		event_config_free(cfg);
3000*c43e99fdSEd Maste 	if (b)
3001*c43e99fdSEd Maste 		event_base_free(b);
3002*c43e99fdSEd Maste }
3003*c43e99fdSEd Maste #endif
3004*c43e99fdSEd Maste 
3005*c43e99fdSEd Maste static void
3006*c43e99fdSEd Maste many_event_cb(evutil_socket_t fd, short event, void *arg)
3007*c43e99fdSEd Maste {
3008*c43e99fdSEd Maste 	int *calledp = arg;
3009*c43e99fdSEd Maste 	*calledp += 1;
3010*c43e99fdSEd Maste }
3011*c43e99fdSEd Maste 
3012*c43e99fdSEd Maste static void
3013*c43e99fdSEd Maste test_many_events(void *arg)
3014*c43e99fdSEd Maste {
3015*c43e99fdSEd Maste 	/* Try 70 events that should all be ready at once.  This will
3016*c43e99fdSEd Maste 	 * exercise the "resize" code on most of the backends, and will make
3017*c43e99fdSEd Maste 	 * sure that we can get past the 64-handle limit of some windows
3018*c43e99fdSEd Maste 	 * functions. */
3019*c43e99fdSEd Maste #define MANY 70
3020*c43e99fdSEd Maste 
3021*c43e99fdSEd Maste 	struct basic_test_data *data = arg;
3022*c43e99fdSEd Maste 	struct event_base *base = data->base;
3023*c43e99fdSEd Maste 	int one_at_a_time = data->setup_data != NULL;
3024*c43e99fdSEd Maste 	evutil_socket_t sock[MANY];
3025*c43e99fdSEd Maste 	struct event *ev[MANY];
3026*c43e99fdSEd Maste 	int called[MANY];
3027*c43e99fdSEd Maste 	int i;
3028*c43e99fdSEd Maste 	int loopflags = EVLOOP_NONBLOCK, evflags=0;
3029*c43e99fdSEd Maste 	if (one_at_a_time) {
3030*c43e99fdSEd Maste 		loopflags |= EVLOOP_ONCE;
3031*c43e99fdSEd Maste 		evflags = EV_PERSIST;
3032*c43e99fdSEd Maste 	}
3033*c43e99fdSEd Maste 
3034*c43e99fdSEd Maste 	memset(sock, 0xff, sizeof(sock));
3035*c43e99fdSEd Maste 	memset(ev, 0, sizeof(ev));
3036*c43e99fdSEd Maste 	memset(called, 0, sizeof(called));
3037*c43e99fdSEd Maste 
3038*c43e99fdSEd Maste 	for (i = 0; i < MANY; ++i) {
3039*c43e99fdSEd Maste 		/* We need an event that will hit the backend, and that will
3040*c43e99fdSEd Maste 		 * be ready immediately.  "Send a datagram" is an easy
3041*c43e99fdSEd Maste 		 * instance of that. */
3042*c43e99fdSEd Maste 		sock[i] = socket(AF_INET, SOCK_DGRAM, 0);
3043*c43e99fdSEd Maste 		tt_assert(sock[i] >= 0);
3044*c43e99fdSEd Maste 		called[i] = 0;
3045*c43e99fdSEd Maste 		ev[i] = event_new(base, sock[i], EV_WRITE|evflags,
3046*c43e99fdSEd Maste 		    many_event_cb, &called[i]);
3047*c43e99fdSEd Maste 		event_add(ev[i], NULL);
3048*c43e99fdSEd Maste 		if (one_at_a_time)
3049*c43e99fdSEd Maste 			event_base_loop(base, EVLOOP_NONBLOCK|EVLOOP_ONCE);
3050*c43e99fdSEd Maste 	}
3051*c43e99fdSEd Maste 
3052*c43e99fdSEd Maste 	event_base_loop(base, loopflags);
3053*c43e99fdSEd Maste 
3054*c43e99fdSEd Maste 	for (i = 0; i < MANY; ++i) {
3055*c43e99fdSEd Maste 		if (one_at_a_time)
3056*c43e99fdSEd Maste 			tt_int_op(called[i], ==, MANY - i + 1);
3057*c43e99fdSEd Maste 		else
3058*c43e99fdSEd Maste 			tt_int_op(called[i], ==, 1);
3059*c43e99fdSEd Maste 	}
3060*c43e99fdSEd Maste 
3061*c43e99fdSEd Maste end:
3062*c43e99fdSEd Maste 	for (i = 0; i < MANY; ++i) {
3063*c43e99fdSEd Maste 		if (ev[i])
3064*c43e99fdSEd Maste 			event_free(ev[i]);
3065*c43e99fdSEd Maste 		if (sock[i] >= 0)
3066*c43e99fdSEd Maste 			evutil_closesocket(sock[i]);
3067*c43e99fdSEd Maste 	}
3068*c43e99fdSEd Maste #undef MANY
3069*c43e99fdSEd Maste }
3070*c43e99fdSEd Maste 
3071*c43e99fdSEd Maste static void
3072*c43e99fdSEd Maste test_struct_event_size(void *arg)
3073*c43e99fdSEd Maste {
3074*c43e99fdSEd Maste 	tt_int_op(event_get_struct_event_size(), <=, sizeof(struct event));
3075*c43e99fdSEd Maste end:
3076*c43e99fdSEd Maste 	;
3077*c43e99fdSEd Maste }
3078*c43e99fdSEd Maste 
3079*c43e99fdSEd Maste static void
3080*c43e99fdSEd Maste test_get_assignment(void *arg)
3081*c43e99fdSEd Maste {
3082*c43e99fdSEd Maste 	struct basic_test_data *data = arg;
3083*c43e99fdSEd Maste 	struct event_base *base = data->base;
3084*c43e99fdSEd Maste 	struct event *ev1 = NULL;
3085*c43e99fdSEd Maste 	const char *str = "foo";
3086*c43e99fdSEd Maste 
3087*c43e99fdSEd Maste 	struct event_base *b;
3088*c43e99fdSEd Maste 	evutil_socket_t s;
3089*c43e99fdSEd Maste 	short what;
3090*c43e99fdSEd Maste 	event_callback_fn cb;
3091*c43e99fdSEd Maste 	void *cb_arg;
3092*c43e99fdSEd Maste 
3093*c43e99fdSEd Maste 	ev1 = event_new(base, data->pair[1], EV_READ, dummy_read_cb, (void*)str);
3094*c43e99fdSEd Maste 	event_get_assignment(ev1, &b, &s, &what, &cb, &cb_arg);
3095*c43e99fdSEd Maste 
3096*c43e99fdSEd Maste 	tt_ptr_op(b, ==, base);
3097*c43e99fdSEd Maste 	tt_int_op(s, ==, data->pair[1]);
3098*c43e99fdSEd Maste 	tt_int_op(what, ==, EV_READ);
3099*c43e99fdSEd Maste 	tt_ptr_op(cb, ==, dummy_read_cb);
3100*c43e99fdSEd Maste 	tt_ptr_op(cb_arg, ==, str);
3101*c43e99fdSEd Maste 
3102*c43e99fdSEd Maste 	/* Now make sure this doesn't crash. */
3103*c43e99fdSEd Maste 	event_get_assignment(ev1, NULL, NULL, NULL, NULL, NULL);
3104*c43e99fdSEd Maste 
3105*c43e99fdSEd Maste end:
3106*c43e99fdSEd Maste 	if (ev1)
3107*c43e99fdSEd Maste 		event_free(ev1);
3108*c43e99fdSEd Maste }
3109*c43e99fdSEd Maste 
3110*c43e99fdSEd Maste struct foreach_helper {
3111*c43e99fdSEd Maste 	int count;
3112*c43e99fdSEd Maste 	const struct event *ev;
3113*c43e99fdSEd Maste };
3114*c43e99fdSEd Maste 
3115*c43e99fdSEd Maste static int
3116*c43e99fdSEd Maste foreach_count_cb(const struct event_base *base, const struct event *ev, void *arg)
3117*c43e99fdSEd Maste {
3118*c43e99fdSEd Maste 	struct foreach_helper *h = event_get_callback_arg(ev);
3119*c43e99fdSEd Maste 	struct timeval *tv = arg;
3120*c43e99fdSEd Maste 	if (event_get_callback(ev) != timeout_cb)
3121*c43e99fdSEd Maste 		return 0;
3122*c43e99fdSEd Maste 	tt_ptr_op(event_get_base(ev), ==, base);
3123*c43e99fdSEd Maste 	tt_int_op(tv->tv_sec, ==, 10);
3124*c43e99fdSEd Maste 	h->ev = ev;
3125*c43e99fdSEd Maste 	h->count++;
3126*c43e99fdSEd Maste 	return 0;
3127*c43e99fdSEd Maste end:
3128*c43e99fdSEd Maste 	return -1;
3129*c43e99fdSEd Maste }
3130*c43e99fdSEd Maste 
3131*c43e99fdSEd Maste static int
3132*c43e99fdSEd Maste foreach_find_cb(const struct event_base *base, const struct event *ev, void *arg)
3133*c43e99fdSEd Maste {
3134*c43e99fdSEd Maste 	const struct event **ev_out = arg;
3135*c43e99fdSEd Maste 	struct foreach_helper *h = event_get_callback_arg(ev);
3136*c43e99fdSEd Maste 	if (event_get_callback(ev) != timeout_cb)
3137*c43e99fdSEd Maste 		return 0;
3138*c43e99fdSEd Maste 	if (h->count == 99) {
3139*c43e99fdSEd Maste 		*ev_out = ev;
3140*c43e99fdSEd Maste 		return 101;
3141*c43e99fdSEd Maste 	}
3142*c43e99fdSEd Maste 	return 0;
3143*c43e99fdSEd Maste }
3144*c43e99fdSEd Maste 
3145*c43e99fdSEd Maste static void
3146*c43e99fdSEd Maste test_event_foreach(void *arg)
3147*c43e99fdSEd Maste {
3148*c43e99fdSEd Maste 	struct basic_test_data *data = arg;
3149*c43e99fdSEd Maste 	struct event_base *base = data->base;
3150*c43e99fdSEd Maste 	struct event *ev[5];
3151*c43e99fdSEd Maste 	struct foreach_helper visited[5];
3152*c43e99fdSEd Maste 	int i;
3153*c43e99fdSEd Maste 	struct timeval ten_sec = {10,0};
3154*c43e99fdSEd Maste 	const struct event *ev_found = NULL;
3155*c43e99fdSEd Maste 
3156*c43e99fdSEd Maste 	for (i = 0; i < 5; ++i) {
3157*c43e99fdSEd Maste 		visited[i].count = 0;
3158*c43e99fdSEd Maste 		visited[i].ev = NULL;
3159*c43e99fdSEd Maste 		ev[i] = event_new(base, -1, 0, timeout_cb, &visited[i]);
3160*c43e99fdSEd Maste 	}
3161*c43e99fdSEd Maste 
3162*c43e99fdSEd Maste 	tt_int_op(-1, ==, event_base_foreach_event(NULL, foreach_count_cb, NULL));
3163*c43e99fdSEd Maste 	tt_int_op(-1, ==, event_base_foreach_event(base, NULL, NULL));
3164*c43e99fdSEd Maste 
3165*c43e99fdSEd Maste 	event_add(ev[0], &ten_sec);
3166*c43e99fdSEd Maste 	event_add(ev[1], &ten_sec);
3167*c43e99fdSEd Maste 	event_active(ev[1], EV_TIMEOUT, 1);
3168*c43e99fdSEd Maste 	event_active(ev[2], EV_TIMEOUT, 1);
3169*c43e99fdSEd Maste 	event_add(ev[3], &ten_sec);
3170*c43e99fdSEd Maste 	/* Don't touch ev[4]. */
3171*c43e99fdSEd Maste 
3172*c43e99fdSEd Maste 	tt_int_op(0, ==, event_base_foreach_event(base, foreach_count_cb,
3173*c43e99fdSEd Maste 		&ten_sec));
3174*c43e99fdSEd Maste 	tt_int_op(1, ==, visited[0].count);
3175*c43e99fdSEd Maste 	tt_int_op(1, ==, visited[1].count);
3176*c43e99fdSEd Maste 	tt_int_op(1, ==, visited[2].count);
3177*c43e99fdSEd Maste 	tt_int_op(1, ==, visited[3].count);
3178*c43e99fdSEd Maste 	tt_ptr_op(ev[0], ==, visited[0].ev);
3179*c43e99fdSEd Maste 	tt_ptr_op(ev[1], ==, visited[1].ev);
3180*c43e99fdSEd Maste 	tt_ptr_op(ev[2], ==, visited[2].ev);
3181*c43e99fdSEd Maste 	tt_ptr_op(ev[3], ==, visited[3].ev);
3182*c43e99fdSEd Maste 
3183*c43e99fdSEd Maste 	visited[2].count = 99;
3184*c43e99fdSEd Maste 	tt_int_op(101, ==, event_base_foreach_event(base, foreach_find_cb,
3185*c43e99fdSEd Maste 		&ev_found));
3186*c43e99fdSEd Maste 	tt_ptr_op(ev_found, ==, ev[2]);
3187*c43e99fdSEd Maste 
3188*c43e99fdSEd Maste end:
3189*c43e99fdSEd Maste 	for (i=0; i<5; ++i) {
3190*c43e99fdSEd Maste 		event_free(ev[i]);
3191*c43e99fdSEd Maste 	}
3192*c43e99fdSEd Maste }
3193*c43e99fdSEd Maste 
3194*c43e99fdSEd Maste static struct event_base *cached_time_base = NULL;
3195*c43e99fdSEd Maste static int cached_time_reset = 0;
3196*c43e99fdSEd Maste static int cached_time_sleep = 0;
3197*c43e99fdSEd Maste static void
3198*c43e99fdSEd Maste cache_time_cb(evutil_socket_t fd, short what, void *arg)
3199*c43e99fdSEd Maste {
3200*c43e99fdSEd Maste 	struct timeval *tv = arg;
3201*c43e99fdSEd Maste 	tt_int_op(0, ==, event_base_gettimeofday_cached(cached_time_base, tv));
3202*c43e99fdSEd Maste 	if (cached_time_sleep) {
3203*c43e99fdSEd Maste 		struct timeval delay = { 0, 30*1000 };
3204*c43e99fdSEd Maste 		evutil_usleep_(&delay);
3205*c43e99fdSEd Maste 	}
3206*c43e99fdSEd Maste 	if (cached_time_reset) {
3207*c43e99fdSEd Maste 		event_base_update_cache_time(cached_time_base);
3208*c43e99fdSEd Maste 	}
3209*c43e99fdSEd Maste end:
3210*c43e99fdSEd Maste 	;
3211*c43e99fdSEd Maste }
3212*c43e99fdSEd Maste 
3213*c43e99fdSEd Maste static void
3214*c43e99fdSEd Maste test_gettimeofday_cached(void *arg)
3215*c43e99fdSEd Maste {
3216*c43e99fdSEd Maste 	struct basic_test_data *data = arg;
3217*c43e99fdSEd Maste 	struct event_config *cfg = NULL;
3218*c43e99fdSEd Maste 	struct event_base *base = NULL;
3219*c43e99fdSEd Maste 	struct timeval tv1, tv2, tv3, now;
3220*c43e99fdSEd Maste 	struct event *ev1=NULL, *ev2=NULL, *ev3=NULL;
3221*c43e99fdSEd Maste 	int cached_time_disable = strstr(data->setup_data, "disable") != NULL;
3222*c43e99fdSEd Maste 
3223*c43e99fdSEd Maste 	cfg = event_config_new();
3224*c43e99fdSEd Maste 	if (cached_time_disable) {
3225*c43e99fdSEd Maste 		event_config_set_flag(cfg, EVENT_BASE_FLAG_NO_CACHE_TIME);
3226*c43e99fdSEd Maste 	}
3227*c43e99fdSEd Maste 	cached_time_base = base = event_base_new_with_config(cfg);
3228*c43e99fdSEd Maste 	tt_assert(base);
3229*c43e99fdSEd Maste 
3230*c43e99fdSEd Maste 	/* Try gettimeofday_cached outside of an event loop. */
3231*c43e99fdSEd Maste 	evutil_gettimeofday(&now, NULL);
3232*c43e99fdSEd Maste 	tt_int_op(0, ==, event_base_gettimeofday_cached(NULL, &tv1));
3233*c43e99fdSEd Maste 	tt_int_op(0, ==, event_base_gettimeofday_cached(base, &tv2));
3234*c43e99fdSEd Maste 	tt_int_op(timeval_msec_diff(&tv1, &tv2), <, 10);
3235*c43e99fdSEd Maste 	tt_int_op(timeval_msec_diff(&tv1, &now), <, 10);
3236*c43e99fdSEd Maste 
3237*c43e99fdSEd Maste 	cached_time_reset = strstr(data->setup_data, "reset") != NULL;
3238*c43e99fdSEd Maste 	cached_time_sleep = strstr(data->setup_data, "sleep") != NULL;
3239*c43e99fdSEd Maste 
3240*c43e99fdSEd Maste 	ev1 = event_new(base, -1, 0, cache_time_cb, &tv1);
3241*c43e99fdSEd Maste 	ev2 = event_new(base, -1, 0, cache_time_cb, &tv2);
3242*c43e99fdSEd Maste 	ev3 = event_new(base, -1, 0, cache_time_cb, &tv3);
3243*c43e99fdSEd Maste 
3244*c43e99fdSEd Maste 	event_active(ev1, EV_TIMEOUT, 1);
3245*c43e99fdSEd Maste 	event_active(ev2, EV_TIMEOUT, 1);
3246*c43e99fdSEd Maste 	event_active(ev3, EV_TIMEOUT, 1);
3247*c43e99fdSEd Maste 
3248*c43e99fdSEd Maste 	event_base_dispatch(base);
3249*c43e99fdSEd Maste 
3250*c43e99fdSEd Maste 	if (cached_time_reset && cached_time_sleep) {
3251*c43e99fdSEd Maste 		tt_int_op(labs(timeval_msec_diff(&tv1,&tv2)), >, 10);
3252*c43e99fdSEd Maste 		tt_int_op(labs(timeval_msec_diff(&tv2,&tv3)), >, 10);
3253*c43e99fdSEd Maste 	} else if (cached_time_disable && cached_time_sleep) {
3254*c43e99fdSEd Maste 		tt_int_op(labs(timeval_msec_diff(&tv1,&tv2)), >, 10);
3255*c43e99fdSEd Maste 		tt_int_op(labs(timeval_msec_diff(&tv2,&tv3)), >, 10);
3256*c43e99fdSEd Maste 	} else if (! cached_time_disable) {
3257*c43e99fdSEd Maste 		tt_assert(evutil_timercmp(&tv1, &tv2, ==));
3258*c43e99fdSEd Maste 		tt_assert(evutil_timercmp(&tv2, &tv3, ==));
3259*c43e99fdSEd Maste 	}
3260*c43e99fdSEd Maste 
3261*c43e99fdSEd Maste end:
3262*c43e99fdSEd Maste 	if (ev1)
3263*c43e99fdSEd Maste 		event_free(ev1);
3264*c43e99fdSEd Maste 	if (ev2)
3265*c43e99fdSEd Maste 		event_free(ev2);
3266*c43e99fdSEd Maste 	if (ev3)
3267*c43e99fdSEd Maste 		event_free(ev3);
3268*c43e99fdSEd Maste 	if (base)
3269*c43e99fdSEd Maste 		event_base_free(base);
3270*c43e99fdSEd Maste 	if (cfg)
3271*c43e99fdSEd Maste 		event_config_free(cfg);
3272*c43e99fdSEd Maste }
3273*c43e99fdSEd Maste 
3274*c43e99fdSEd Maste static void
3275*c43e99fdSEd Maste tabf_cb(evutil_socket_t fd, short what, void *arg)
3276*c43e99fdSEd Maste {
3277*c43e99fdSEd Maste 	int *ptr = arg;
3278*c43e99fdSEd Maste 	*ptr = what;
3279*c43e99fdSEd Maste 	*ptr += 0x10000;
3280*c43e99fdSEd Maste }
3281*c43e99fdSEd Maste 
3282*c43e99fdSEd Maste static void
3283*c43e99fdSEd Maste test_active_by_fd(void *arg)
3284*c43e99fdSEd Maste {
3285*c43e99fdSEd Maste 	struct basic_test_data *data = arg;
3286*c43e99fdSEd Maste 	struct event_base *base = data->base;
3287*c43e99fdSEd Maste 	struct event *ev1 = NULL, *ev2 = NULL, *ev3 = NULL, *ev4 = NULL;
3288*c43e99fdSEd Maste 	int e1,e2,e3,e4;
3289*c43e99fdSEd Maste #ifndef _WIN32
3290*c43e99fdSEd Maste 	struct event *evsig = NULL;
3291*c43e99fdSEd Maste 	int es;
3292*c43e99fdSEd Maste #endif
3293*c43e99fdSEd Maste 	struct timeval tenmin = { 600, 0 };
3294*c43e99fdSEd Maste 
3295*c43e99fdSEd Maste 	/* Ensure no crash on nonexistent FD. */
3296*c43e99fdSEd Maste 	event_base_active_by_fd(base, 1000, EV_READ);
3297*c43e99fdSEd Maste 
3298*c43e99fdSEd Maste 	/* Ensure no crash on bogus FD. */
3299*c43e99fdSEd Maste 	event_base_active_by_fd(base, -1, EV_READ);
3300*c43e99fdSEd Maste 
3301*c43e99fdSEd Maste 	/* Ensure no crash on nonexistent/bogus signal. */
3302*c43e99fdSEd Maste 	event_base_active_by_signal(base, 1000);
3303*c43e99fdSEd Maste 	event_base_active_by_signal(base, -1);
3304*c43e99fdSEd Maste 
3305*c43e99fdSEd Maste 	event_base_assert_ok_(base);
3306*c43e99fdSEd Maste 
3307*c43e99fdSEd Maste 	e1 = e2 = e3 = e4 = 0;
3308*c43e99fdSEd Maste 	ev1 = event_new(base, data->pair[0], EV_READ, tabf_cb, &e1);
3309*c43e99fdSEd Maste 	ev2 = event_new(base, data->pair[0], EV_WRITE, tabf_cb, &e2);
3310*c43e99fdSEd Maste 	ev3 = event_new(base, data->pair[1], EV_READ, tabf_cb, &e3);
3311*c43e99fdSEd Maste 	ev4 = event_new(base, data->pair[1], EV_READ, tabf_cb, &e4);
3312*c43e99fdSEd Maste 	tt_assert(ev1);
3313*c43e99fdSEd Maste 	tt_assert(ev2);
3314*c43e99fdSEd Maste 	tt_assert(ev3);
3315*c43e99fdSEd Maste 	tt_assert(ev4);
3316*c43e99fdSEd Maste #ifndef _WIN32
3317*c43e99fdSEd Maste 	evsig = event_new(base, SIGHUP, EV_SIGNAL, tabf_cb, &es);
3318*c43e99fdSEd Maste 	tt_assert(evsig);
3319*c43e99fdSEd Maste 	event_add(evsig, &tenmin);
3320*c43e99fdSEd Maste #endif
3321*c43e99fdSEd Maste 
3322*c43e99fdSEd Maste 	event_add(ev1, &tenmin);
3323*c43e99fdSEd Maste 	event_add(ev2, NULL);
3324*c43e99fdSEd Maste 	event_add(ev3, NULL);
3325*c43e99fdSEd Maste 	event_add(ev4, &tenmin);
3326*c43e99fdSEd Maste 
3327*c43e99fdSEd Maste 
3328*c43e99fdSEd Maste 	event_base_assert_ok_(base);
3329*c43e99fdSEd Maste 
3330*c43e99fdSEd Maste 	/* Trigger 2, 3, 4 */
3331*c43e99fdSEd Maste 	event_base_active_by_fd(base, data->pair[0], EV_WRITE);
3332*c43e99fdSEd Maste 	event_base_active_by_fd(base, data->pair[1], EV_READ);
3333*c43e99fdSEd Maste #ifndef _WIN32
3334*c43e99fdSEd Maste 	event_base_active_by_signal(base, SIGHUP);
3335*c43e99fdSEd Maste #endif
3336*c43e99fdSEd Maste 
3337*c43e99fdSEd Maste 	event_base_assert_ok_(base);
3338*c43e99fdSEd Maste 
3339*c43e99fdSEd Maste 	event_base_loop(base, EVLOOP_ONCE);
3340*c43e99fdSEd Maste 
3341*c43e99fdSEd Maste 	tt_int_op(e1, ==, 0);
3342*c43e99fdSEd Maste 	tt_int_op(e2, ==, EV_WRITE | 0x10000);
3343*c43e99fdSEd Maste 	tt_int_op(e3, ==, EV_READ | 0x10000);
3344*c43e99fdSEd Maste 	/* Mask out EV_WRITE here, since it could be genuinely writeable. */
3345*c43e99fdSEd Maste 	tt_int_op((e4 & ~EV_WRITE), ==, EV_READ | 0x10000);
3346*c43e99fdSEd Maste #ifndef _WIN32
3347*c43e99fdSEd Maste 	tt_int_op(es, ==, EV_SIGNAL | 0x10000);
3348*c43e99fdSEd Maste #endif
3349*c43e99fdSEd Maste 
3350*c43e99fdSEd Maste end:
3351*c43e99fdSEd Maste 	if (ev1)
3352*c43e99fdSEd Maste 		event_free(ev1);
3353*c43e99fdSEd Maste 	if (ev2)
3354*c43e99fdSEd Maste 		event_free(ev2);
3355*c43e99fdSEd Maste 	if (ev3)
3356*c43e99fdSEd Maste 		event_free(ev3);
3357*c43e99fdSEd Maste 	if (ev4)
3358*c43e99fdSEd Maste 		event_free(ev4);
3359*c43e99fdSEd Maste #ifndef _WIN32
3360*c43e99fdSEd Maste 	if (evsig)
3361*c43e99fdSEd Maste 		event_free(evsig);
3362*c43e99fdSEd Maste #endif
3363*c43e99fdSEd Maste }
3364*c43e99fdSEd Maste 
3365*c43e99fdSEd Maste struct testcase_t main_testcases[] = {
3366*c43e99fdSEd Maste 	/* Some converted-over tests */
3367*c43e99fdSEd Maste 	{ "methods", test_methods, TT_FORK, NULL, NULL },
3368*c43e99fdSEd Maste 	{ "version", test_version, 0, NULL, NULL },
3369*c43e99fdSEd Maste 	BASIC(base_features, TT_FORK|TT_NO_LOGS),
3370*c43e99fdSEd Maste 	{ "base_environ", test_base_environ, TT_FORK, NULL, NULL },
3371*c43e99fdSEd Maste 
3372*c43e99fdSEd Maste 	BASIC(event_base_new, TT_FORK|TT_NEED_SOCKETPAIR),
3373*c43e99fdSEd Maste 	BASIC(free_active_base, TT_FORK|TT_NEED_SOCKETPAIR),
3374*c43e99fdSEd Maste 
3375*c43e99fdSEd Maste 	BASIC(manipulate_active_events, TT_FORK|TT_NEED_BASE),
3376*c43e99fdSEd Maste 	BASIC(event_new_selfarg, TT_FORK|TT_NEED_BASE),
3377*c43e99fdSEd Maste 	BASIC(event_assign_selfarg, TT_FORK|TT_NEED_BASE),
3378*c43e99fdSEd Maste 	BASIC(event_base_get_num_events, TT_FORK|TT_NEED_BASE),
3379*c43e99fdSEd Maste 	BASIC(event_base_get_max_events, TT_FORK|TT_NEED_BASE),
3380*c43e99fdSEd Maste 
3381*c43e99fdSEd Maste 	BASIC(bad_assign, TT_FORK|TT_NEED_BASE|TT_NO_LOGS),
3382*c43e99fdSEd Maste 	BASIC(bad_reentrant, TT_FORK|TT_NEED_BASE|TT_NO_LOGS),
3383*c43e99fdSEd Maste 	BASIC(active_later, TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR),
3384*c43e99fdSEd Maste 	BASIC(event_remove_timeout, TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR),
3385*c43e99fdSEd Maste 
3386*c43e99fdSEd Maste 	/* These are still using the old API */
3387*c43e99fdSEd Maste 	LEGACY(persistent_timeout, TT_FORK|TT_NEED_BASE),
3388*c43e99fdSEd Maste 	{ "persistent_timeout_jump", test_persistent_timeout_jump, TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
3389*c43e99fdSEd Maste 	{ "persistent_active_timeout", test_persistent_active_timeout,
3390*c43e99fdSEd Maste 	  TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
3391*c43e99fdSEd Maste 	LEGACY(priorities, TT_FORK|TT_NEED_BASE),
3392*c43e99fdSEd Maste 	BASIC(priority_active_inversion, TT_FORK|TT_NEED_BASE),
3393*c43e99fdSEd Maste 	{ "common_timeout", test_common_timeout, TT_FORK|TT_NEED_BASE,
3394*c43e99fdSEd Maste 	  &basic_setup, NULL },
3395*c43e99fdSEd Maste 
3396*c43e99fdSEd Maste 	/* These legacy tests may not all need all of these flags. */
3397*c43e99fdSEd Maste 	LEGACY(simpleread, TT_ISOLATED),
3398*c43e99fdSEd Maste 	LEGACY(simpleread_multiple, TT_ISOLATED),
3399*c43e99fdSEd Maste 	LEGACY(simplewrite, TT_ISOLATED),
3400*c43e99fdSEd Maste 	{ "simpleclose", test_simpleclose, TT_FORK, &basic_setup,
3401*c43e99fdSEd Maste 	  NULL },
3402*c43e99fdSEd Maste 	LEGACY(multiple, TT_ISOLATED),
3403*c43e99fdSEd Maste 	LEGACY(persistent, TT_ISOLATED),
3404*c43e99fdSEd Maste 	LEGACY(combined, TT_ISOLATED),
3405*c43e99fdSEd Maste 	LEGACY(simpletimeout, TT_ISOLATED),
3406*c43e99fdSEd Maste 	LEGACY(loopbreak, TT_ISOLATED),
3407*c43e99fdSEd Maste 	LEGACY(loopexit, TT_ISOLATED),
3408*c43e99fdSEd Maste 	LEGACY(loopexit_multiple, TT_ISOLATED),
3409*c43e99fdSEd Maste 	LEGACY(nonpersist_readd, TT_ISOLATED),
3410*c43e99fdSEd Maste 	LEGACY(multiple_events_for_same_fd, TT_ISOLATED),
3411*c43e99fdSEd Maste 	LEGACY(want_only_once, TT_ISOLATED),
3412*c43e99fdSEd Maste 	{ "event_once", test_event_once, TT_ISOLATED, &basic_setup, NULL },
3413*c43e99fdSEd Maste 	{ "event_once_never", test_event_once_never, TT_ISOLATED, &basic_setup, NULL },
3414*c43e99fdSEd Maste 	{ "event_pending", test_event_pending, TT_ISOLATED, &basic_setup,
3415*c43e99fdSEd Maste 	  NULL },
3416*c43e99fdSEd Maste 	{ "event_closed_fd_poll", test_event_closed_fd_poll, TT_ISOLATED, &basic_setup,
3417*c43e99fdSEd Maste 	  NULL },
3418*c43e99fdSEd Maste 
3419*c43e99fdSEd Maste #ifndef _WIN32
3420*c43e99fdSEd Maste 	{ "dup_fd", test_dup_fd, TT_ISOLATED, &basic_setup, NULL },
3421*c43e99fdSEd Maste #endif
3422*c43e99fdSEd Maste 	{ "mm_functions", test_mm_functions, TT_FORK, NULL, NULL },
3423*c43e99fdSEd Maste 	{ "many_events", test_many_events, TT_ISOLATED, &basic_setup, NULL },
3424*c43e99fdSEd Maste 	{ "many_events_slow_add", test_many_events, TT_ISOLATED, &basic_setup, (void*)1 },
3425*c43e99fdSEd Maste 
3426*c43e99fdSEd Maste 	{ "struct_event_size", test_struct_event_size, 0, NULL, NULL },
3427*c43e99fdSEd Maste 	BASIC(get_assignment, TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR),
3428*c43e99fdSEd Maste 
3429*c43e99fdSEd Maste 	BASIC(event_foreach, TT_FORK|TT_NEED_BASE),
3430*c43e99fdSEd Maste 	{ "gettimeofday_cached", test_gettimeofday_cached, TT_FORK, &basic_setup, (void*)"" },
3431*c43e99fdSEd Maste 	{ "gettimeofday_cached_sleep", test_gettimeofday_cached, TT_FORK, &basic_setup, (void*)"sleep" },
3432*c43e99fdSEd Maste 	{ "gettimeofday_cached_reset", test_gettimeofday_cached, TT_FORK, &basic_setup, (void*)"sleep reset" },
3433*c43e99fdSEd Maste 	{ "gettimeofday_cached_disabled", test_gettimeofday_cached, TT_FORK, &basic_setup, (void*)"sleep disable" },
3434*c43e99fdSEd Maste 	{ "gettimeofday_cached_disabled_nosleep", test_gettimeofday_cached, TT_FORK, &basic_setup, (void*)"disable" },
3435*c43e99fdSEd Maste 
3436*c43e99fdSEd Maste 	BASIC(active_by_fd, TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR),
3437*c43e99fdSEd Maste 
3438*c43e99fdSEd Maste #ifndef _WIN32
3439*c43e99fdSEd Maste 	LEGACY(fork, TT_ISOLATED),
3440*c43e99fdSEd Maste #endif
3441*c43e99fdSEd Maste #ifdef EVENT__HAVE_PTHREADS
3442*c43e99fdSEd Maste 	/** TODO: support win32 */
3443*c43e99fdSEd Maste 	LEGACY(del_wait, TT_ISOLATED|TT_NEED_THREADS),
3444*c43e99fdSEd Maste #endif
3445*c43e99fdSEd Maste 
3446*c43e99fdSEd Maste 	END_OF_TESTCASES
3447*c43e99fdSEd Maste };
3448*c43e99fdSEd Maste 
3449*c43e99fdSEd Maste struct testcase_t evtag_testcases[] = {
3450*c43e99fdSEd Maste 	{ "int", evtag_int_test, TT_FORK, NULL, NULL },
3451*c43e99fdSEd Maste 	{ "fuzz", evtag_fuzz, TT_FORK, NULL, NULL },
3452*c43e99fdSEd Maste 	{ "encoding", evtag_tag_encoding, TT_FORK, NULL, NULL },
3453*c43e99fdSEd Maste 	{ "peek", evtag_test_peek, 0, NULL, NULL },
3454*c43e99fdSEd Maste 
3455*c43e99fdSEd Maste 	END_OF_TESTCASES
3456*c43e99fdSEd Maste };
3457*c43e99fdSEd Maste 
3458*c43e99fdSEd Maste struct testcase_t signal_testcases[] = {
3459*c43e99fdSEd Maste #ifndef _WIN32
3460*c43e99fdSEd Maste 	LEGACY(simplestsignal, TT_ISOLATED),
3461*c43e99fdSEd Maste 	LEGACY(simplesignal, TT_ISOLATED),
3462*c43e99fdSEd Maste 	LEGACY(multiplesignal, TT_ISOLATED),
3463*c43e99fdSEd Maste 	LEGACY(immediatesignal, TT_ISOLATED),
3464*c43e99fdSEd Maste 	LEGACY(signal_dealloc, TT_ISOLATED),
3465*c43e99fdSEd Maste 	LEGACY(signal_pipeloss, TT_ISOLATED),
3466*c43e99fdSEd Maste 	LEGACY(signal_switchbase, TT_ISOLATED|TT_NO_LOGS),
3467*c43e99fdSEd Maste 	LEGACY(signal_restore, TT_ISOLATED),
3468*c43e99fdSEd Maste 	LEGACY(signal_assert, TT_ISOLATED),
3469*c43e99fdSEd Maste 	LEGACY(signal_while_processing, TT_ISOLATED),
3470*c43e99fdSEd Maste #endif
3471*c43e99fdSEd Maste 	END_OF_TESTCASES
3472*c43e99fdSEd Maste };
3473*c43e99fdSEd Maste 
3474