1*0a6a1f1dSLionel Sambuc /* $NetBSD: regress.c,v 1.8 2015/01/29 07:26:02 spz Exp $ */
2e985b929SDavid van Moolenbroek /*
3e985b929SDavid van Moolenbroek * Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu>
4e985b929SDavid van Moolenbroek * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
5e985b929SDavid van Moolenbroek *
6e985b929SDavid van Moolenbroek * Redistribution and use in source and binary forms, with or without
7e985b929SDavid van Moolenbroek * modification, are permitted provided that the following conditions
8e985b929SDavid van Moolenbroek * are met:
9e985b929SDavid van Moolenbroek * 1. Redistributions of source code must retain the above copyright
10e985b929SDavid van Moolenbroek * notice, this list of conditions and the following disclaimer.
11e985b929SDavid van Moolenbroek * 2. Redistributions in binary form must reproduce the above copyright
12e985b929SDavid van Moolenbroek * notice, this list of conditions and the following disclaimer in the
13e985b929SDavid van Moolenbroek * documentation and/or other materials provided with the distribution.
14e985b929SDavid van Moolenbroek * 3. The name of the author may not be used to endorse or promote products
15e985b929SDavid van Moolenbroek * derived from this software without specific prior written permission.
16e985b929SDavid van Moolenbroek *
17e985b929SDavid van Moolenbroek * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18e985b929SDavid van Moolenbroek * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19e985b929SDavid van Moolenbroek * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20e985b929SDavid van Moolenbroek * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21e985b929SDavid van Moolenbroek * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22e985b929SDavid van Moolenbroek * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23e985b929SDavid van Moolenbroek * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24e985b929SDavid van Moolenbroek * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25e985b929SDavid van Moolenbroek * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26e985b929SDavid van Moolenbroek * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27e985b929SDavid van Moolenbroek */
28e985b929SDavid van Moolenbroek
29e985b929SDavid van Moolenbroek #ifdef WIN32
30e985b929SDavid van Moolenbroek #include <winsock2.h>
31e985b929SDavid van Moolenbroek #include <windows.h>
32e985b929SDavid van Moolenbroek #endif
33e985b929SDavid van Moolenbroek
34e985b929SDavid van Moolenbroek #include "event2/event-config.h"
35e985b929SDavid van Moolenbroek #include <sys/cdefs.h>
36*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: regress.c,v 1.8 2015/01/29 07:26:02 spz Exp $");
37e985b929SDavid van Moolenbroek
38e985b929SDavid van Moolenbroek #include <sys/types.h>
39e985b929SDavid van Moolenbroek #include <sys/stat.h>
40e985b929SDavid van Moolenbroek #ifdef _EVENT_HAVE_SYS_TIME_H
41e985b929SDavid van Moolenbroek #include <sys/time.h>
42e985b929SDavid van Moolenbroek #endif
43e985b929SDavid van Moolenbroek #include <sys/queue.h>
44e985b929SDavid van Moolenbroek #ifndef WIN32
45e985b929SDavid van Moolenbroek #include <sys/socket.h>
46e985b929SDavid van Moolenbroek #include <sys/wait.h>
47e985b929SDavid van Moolenbroek #include <signal.h>
48e985b929SDavid van Moolenbroek #include <unistd.h>
49e985b929SDavid van Moolenbroek #include <netdb.h>
50e985b929SDavid van Moolenbroek #endif
51e985b929SDavid van Moolenbroek #include <fcntl.h>
52e985b929SDavid van Moolenbroek #include <signal.h>
53e985b929SDavid van Moolenbroek #include <stdlib.h>
54e985b929SDavid van Moolenbroek #include <stdio.h>
55e985b929SDavid van Moolenbroek #include <string.h>
56e985b929SDavid van Moolenbroek #include <errno.h>
57e985b929SDavid van Moolenbroek #include <assert.h>
58e985b929SDavid van Moolenbroek #include <ctype.h>
59e985b929SDavid van Moolenbroek
60e985b929SDavid van Moolenbroek #include "event2/event.h"
61e985b929SDavid van Moolenbroek #include "event2/event_struct.h"
62e985b929SDavid van Moolenbroek #include "event2/event_compat.h"
63e985b929SDavid van Moolenbroek #include "event2/tag.h"
64e985b929SDavid van Moolenbroek #include "event2/buffer.h"
65e985b929SDavid van Moolenbroek #include "event2/buffer_compat.h"
66e985b929SDavid van Moolenbroek #include "event2/util.h"
67e985b929SDavid van Moolenbroek #include "event-internal.h"
68e985b929SDavid van Moolenbroek #include "evthread-internal.h"
69e985b929SDavid van Moolenbroek #include "util-internal.h"
70e985b929SDavid van Moolenbroek #include "log-internal.h"
71e985b929SDavid van Moolenbroek
72e985b929SDavid van Moolenbroek #include "regress.h"
73e985b929SDavid van Moolenbroek
74e985b929SDavid van Moolenbroek #ifndef WIN32
75e985b929SDavid van Moolenbroek #include "regress.gen.h"
76e985b929SDavid van Moolenbroek #endif
77e985b929SDavid van Moolenbroek
78e985b929SDavid van Moolenbroek evutil_socket_t pair[2];
79e985b929SDavid van Moolenbroek int test_ok;
80e985b929SDavid van Moolenbroek int called;
81e985b929SDavid van Moolenbroek struct event_base *global_base;
82e985b929SDavid van Moolenbroek
83e985b929SDavid van Moolenbroek static char wbuf[4096];
84e985b929SDavid van Moolenbroek static char rbuf[4096];
85e985b929SDavid van Moolenbroek static int woff;
86e985b929SDavid van Moolenbroek static int roff;
87e985b929SDavid van Moolenbroek static int usepersist;
88e985b929SDavid van Moolenbroek static struct timeval tset;
89e985b929SDavid van Moolenbroek static struct timeval tcalled;
90e985b929SDavid van Moolenbroek
91e985b929SDavid van Moolenbroek
92e985b929SDavid van Moolenbroek #define TEST1 "this is a test"
93e985b929SDavid van Moolenbroek #define SECONDS 1
94e985b929SDavid van Moolenbroek
95e985b929SDavid van Moolenbroek #ifndef SHUT_WR
96e985b929SDavid van Moolenbroek #define SHUT_WR 1
97e985b929SDavid van Moolenbroek #endif
98e985b929SDavid van Moolenbroek
99e985b929SDavid van Moolenbroek #ifdef WIN32
100e985b929SDavid van Moolenbroek #define write(fd,buf,len) send((fd),(buf),(int)(len),0)
101e985b929SDavid van Moolenbroek #define read(fd,buf,len) recv((fd),(buf),(int)(len),0)
102e985b929SDavid van Moolenbroek #endif
103e985b929SDavid van Moolenbroek
104e985b929SDavid van Moolenbroek struct basic_cb_args
105e985b929SDavid van Moolenbroek {
106e985b929SDavid van Moolenbroek struct event_base *eb;
107e985b929SDavid van Moolenbroek struct event *ev;
108e985b929SDavid van Moolenbroek unsigned int callcount;
109e985b929SDavid van Moolenbroek };
110e985b929SDavid van Moolenbroek
111e985b929SDavid van Moolenbroek static void
simple_read_cb(evutil_socket_t fd,short event,void * arg)112e985b929SDavid van Moolenbroek simple_read_cb(evutil_socket_t fd, short event, void *arg)
113e985b929SDavid van Moolenbroek {
114e985b929SDavid van Moolenbroek char buf[256];
115e985b929SDavid van Moolenbroek int len;
116e985b929SDavid van Moolenbroek
117e985b929SDavid van Moolenbroek len = read(fd, buf, sizeof(buf));
118e985b929SDavid van Moolenbroek
119e985b929SDavid van Moolenbroek if (len) {
120e985b929SDavid van Moolenbroek if (!called) {
121e985b929SDavid van Moolenbroek if (event_add(arg, NULL) == -1)
122e985b929SDavid van Moolenbroek exit(1);
123e985b929SDavid van Moolenbroek }
124e985b929SDavid van Moolenbroek } else if (called == 1)
125e985b929SDavid van Moolenbroek test_ok = 1;
126e985b929SDavid van Moolenbroek
127e985b929SDavid van Moolenbroek called++;
128e985b929SDavid van Moolenbroek }
129e985b929SDavid van Moolenbroek
130e985b929SDavid van Moolenbroek static void
basic_read_cb(evutil_socket_t fd,short event,void * data)131e985b929SDavid van Moolenbroek basic_read_cb(evutil_socket_t fd, short event, void *data)
132e985b929SDavid van Moolenbroek {
133e985b929SDavid van Moolenbroek char buf[256];
134e985b929SDavid van Moolenbroek int len;
135e985b929SDavid van Moolenbroek struct basic_cb_args *arg = data;
136e985b929SDavid van Moolenbroek
137e985b929SDavid van Moolenbroek len = read(fd, buf, sizeof(buf));
138e985b929SDavid van Moolenbroek
139e985b929SDavid van Moolenbroek if (len < 0) {
140e985b929SDavid van Moolenbroek tt_fail_perror("read (callback)");
141e985b929SDavid van Moolenbroek } else {
142e985b929SDavid van Moolenbroek switch (arg->callcount++) {
143e985b929SDavid van Moolenbroek case 0: /* first call: expect to read data; cycle */
144e985b929SDavid van Moolenbroek if (len > 0)
145e985b929SDavid van Moolenbroek return;
146e985b929SDavid van Moolenbroek
147e985b929SDavid van Moolenbroek tt_fail_msg("EOF before data read");
148e985b929SDavid van Moolenbroek break;
149e985b929SDavid van Moolenbroek
150e985b929SDavid van Moolenbroek case 1: /* second call: expect EOF; stop */
151e985b929SDavid van Moolenbroek if (len > 0)
152e985b929SDavid van Moolenbroek tt_fail_msg("not all data read on first cycle");
153e985b929SDavid van Moolenbroek break;
154e985b929SDavid van Moolenbroek
155e985b929SDavid van Moolenbroek default: /* third call: should not happen */
156e985b929SDavid van Moolenbroek tt_fail_msg("too many cycles");
157e985b929SDavid van Moolenbroek }
158e985b929SDavid van Moolenbroek }
159e985b929SDavid van Moolenbroek
160e985b929SDavid van Moolenbroek event_del(arg->ev);
161e985b929SDavid van Moolenbroek event_base_loopexit(arg->eb, NULL);
162e985b929SDavid van Moolenbroek }
163e985b929SDavid van Moolenbroek
164e985b929SDavid van Moolenbroek static void
dummy_read_cb(evutil_socket_t fd,short event,void * arg)165e985b929SDavid van Moolenbroek dummy_read_cb(evutil_socket_t fd, short event, void *arg)
166e985b929SDavid van Moolenbroek {
167e985b929SDavid van Moolenbroek }
168e985b929SDavid van Moolenbroek
169e985b929SDavid van Moolenbroek static void
simple_write_cb(evutil_socket_t fd,short event,void * arg)170e985b929SDavid van Moolenbroek simple_write_cb(evutil_socket_t fd, short event, void *arg)
171e985b929SDavid van Moolenbroek {
172e985b929SDavid van Moolenbroek int len;
173e985b929SDavid van Moolenbroek
174e985b929SDavid van Moolenbroek len = write(fd, TEST1, strlen(TEST1) + 1);
175e985b929SDavid van Moolenbroek if (len == -1)
176e985b929SDavid van Moolenbroek test_ok = 0;
177e985b929SDavid van Moolenbroek else
178e985b929SDavid van Moolenbroek test_ok = 1;
179e985b929SDavid van Moolenbroek }
180e985b929SDavid van Moolenbroek
181e985b929SDavid van Moolenbroek static void
multiple_write_cb(evutil_socket_t fd,short event,void * arg)182e985b929SDavid van Moolenbroek multiple_write_cb(evutil_socket_t fd, short event, void *arg)
183e985b929SDavid van Moolenbroek {
184e985b929SDavid van Moolenbroek struct event *ev = arg;
185e985b929SDavid van Moolenbroek int len;
186e985b929SDavid van Moolenbroek
187e985b929SDavid van Moolenbroek len = 128;
188e985b929SDavid van Moolenbroek if (woff + len >= (int)sizeof(wbuf))
189e985b929SDavid van Moolenbroek len = sizeof(wbuf) - woff;
190e985b929SDavid van Moolenbroek
191e985b929SDavid van Moolenbroek len = write(fd, wbuf + woff, len);
192e985b929SDavid van Moolenbroek if (len == -1) {
193e985b929SDavid van Moolenbroek fprintf(stderr, "%s: write\n", __func__);
194e985b929SDavid van Moolenbroek if (usepersist)
195e985b929SDavid van Moolenbroek event_del(ev);
196e985b929SDavid van Moolenbroek return;
197e985b929SDavid van Moolenbroek }
198e985b929SDavid van Moolenbroek
199e985b929SDavid van Moolenbroek woff += len;
200e985b929SDavid van Moolenbroek
201e985b929SDavid van Moolenbroek if (woff >= (int)sizeof(wbuf)) {
202e985b929SDavid van Moolenbroek shutdown(fd, SHUT_WR);
203e985b929SDavid van Moolenbroek if (usepersist)
204e985b929SDavid van Moolenbroek event_del(ev);
205e985b929SDavid van Moolenbroek return;
206e985b929SDavid van Moolenbroek }
207e985b929SDavid van Moolenbroek
208e985b929SDavid van Moolenbroek if (!usepersist) {
209e985b929SDavid van Moolenbroek if (event_add(ev, NULL) == -1)
210e985b929SDavid van Moolenbroek exit(1);
211e985b929SDavid van Moolenbroek }
212e985b929SDavid van Moolenbroek }
213e985b929SDavid van Moolenbroek
214e985b929SDavid van Moolenbroek static void
multiple_read_cb(evutil_socket_t fd,short event,void * arg)215e985b929SDavid van Moolenbroek multiple_read_cb(evutil_socket_t fd, short event, void *arg)
216e985b929SDavid van Moolenbroek {
217e985b929SDavid van Moolenbroek struct event *ev = arg;
218e985b929SDavid van Moolenbroek int len;
219e985b929SDavid van Moolenbroek
220e985b929SDavid van Moolenbroek len = read(fd, rbuf + roff, sizeof(rbuf) - roff);
221e985b929SDavid van Moolenbroek if (len == -1)
222e985b929SDavid van Moolenbroek fprintf(stderr, "%s: read\n", __func__);
223e985b929SDavid van Moolenbroek if (len <= 0) {
224e985b929SDavid van Moolenbroek if (usepersist)
225e985b929SDavid van Moolenbroek event_del(ev);
226e985b929SDavid van Moolenbroek return;
227e985b929SDavid van Moolenbroek }
228e985b929SDavid van Moolenbroek
229e985b929SDavid van Moolenbroek roff += len;
230e985b929SDavid van Moolenbroek if (!usepersist) {
231e985b929SDavid van Moolenbroek if (event_add(ev, NULL) == -1)
232e985b929SDavid van Moolenbroek exit(1);
233e985b929SDavid van Moolenbroek }
234e985b929SDavid van Moolenbroek }
235e985b929SDavid van Moolenbroek
236e985b929SDavid van Moolenbroek static void
timeout_cb(evutil_socket_t fd,short event,void * arg)237e985b929SDavid van Moolenbroek timeout_cb(evutil_socket_t fd, short event, void *arg)
238e985b929SDavid van Moolenbroek {
239e985b929SDavid van Moolenbroek struct timeval tv;
240e985b929SDavid van Moolenbroek int diff;
241e985b929SDavid van Moolenbroek
242e985b929SDavid van Moolenbroek evutil_gettimeofday(&tcalled, NULL);
243e985b929SDavid van Moolenbroek if (evutil_timercmp(&tcalled, &tset, >))
244e985b929SDavid van Moolenbroek evutil_timersub(&tcalled, &tset, &tv);
245e985b929SDavid van Moolenbroek else
246e985b929SDavid van Moolenbroek evutil_timersub(&tset, &tcalled, &tv);
247e985b929SDavid van Moolenbroek
248e985b929SDavid van Moolenbroek diff = tv.tv_sec*1000 + tv.tv_usec/1000 - SECONDS * 1000;
249e985b929SDavid van Moolenbroek if (diff < 0)
250e985b929SDavid van Moolenbroek diff = -diff;
251e985b929SDavid van Moolenbroek
252e985b929SDavid van Moolenbroek if (diff < 100)
253e985b929SDavid van Moolenbroek test_ok = 1;
254e985b929SDavid van Moolenbroek }
255e985b929SDavid van Moolenbroek
256e985b929SDavid van Moolenbroek struct both {
257e985b929SDavid van Moolenbroek struct event ev;
258e985b929SDavid van Moolenbroek int nread;
259e985b929SDavid van Moolenbroek };
260e985b929SDavid van Moolenbroek
261e985b929SDavid van Moolenbroek static void
combined_read_cb(evutil_socket_t fd,short event,void * arg)262e985b929SDavid van Moolenbroek combined_read_cb(evutil_socket_t fd, short event, void *arg)
263e985b929SDavid van Moolenbroek {
264e985b929SDavid van Moolenbroek struct both *both = arg;
265e985b929SDavid van Moolenbroek char buf[128];
266e985b929SDavid van Moolenbroek int len;
267e985b929SDavid van Moolenbroek
268e985b929SDavid van Moolenbroek len = read(fd, buf, sizeof(buf));
269e985b929SDavid van Moolenbroek if (len == -1)
270e985b929SDavid van Moolenbroek fprintf(stderr, "%s: read\n", __func__);
271e985b929SDavid van Moolenbroek if (len <= 0)
272e985b929SDavid van Moolenbroek return;
273e985b929SDavid van Moolenbroek
274e985b929SDavid van Moolenbroek both->nread += len;
275e985b929SDavid van Moolenbroek if (event_add(&both->ev, NULL) == -1)
276e985b929SDavid van Moolenbroek exit(1);
277e985b929SDavid van Moolenbroek }
278e985b929SDavid van Moolenbroek
279e985b929SDavid van Moolenbroek static void
combined_write_cb(evutil_socket_t fd,short event,void * arg)280e985b929SDavid van Moolenbroek combined_write_cb(evutil_socket_t fd, short event, void *arg)
281e985b929SDavid van Moolenbroek {
282e985b929SDavid van Moolenbroek struct both *both = arg;
283e985b929SDavid van Moolenbroek char buf[128];
284e985b929SDavid van Moolenbroek int len;
285e985b929SDavid van Moolenbroek
286e985b929SDavid van Moolenbroek len = sizeof(buf);
287e985b929SDavid van Moolenbroek if (len > both->nread)
288e985b929SDavid van Moolenbroek len = both->nread;
289e985b929SDavid van Moolenbroek
290e985b929SDavid van Moolenbroek memset(buf, 'q', len);
291e985b929SDavid van Moolenbroek
292e985b929SDavid van Moolenbroek len = write(fd, buf, len);
293e985b929SDavid van Moolenbroek if (len == -1)
294e985b929SDavid van Moolenbroek fprintf(stderr, "%s: write\n", __func__);
295e985b929SDavid van Moolenbroek if (len <= 0) {
296e985b929SDavid van Moolenbroek shutdown(fd, SHUT_WR);
297e985b929SDavid van Moolenbroek return;
298e985b929SDavid van Moolenbroek }
299e985b929SDavid van Moolenbroek
300e985b929SDavid van Moolenbroek both->nread -= len;
301e985b929SDavid van Moolenbroek if (event_add(&both->ev, NULL) == -1)
302e985b929SDavid van Moolenbroek exit(1);
303e985b929SDavid van Moolenbroek }
304e985b929SDavid van Moolenbroek
305e985b929SDavid van Moolenbroek /* These macros used to replicate the work of the legacy test wrapper code */
306e985b929SDavid van Moolenbroek #define setup_test(x) do { \
307e985b929SDavid van Moolenbroek if (!in_legacy_test_wrapper) { \
308e985b929SDavid van Moolenbroek TT_FAIL(("Legacy test %s not wrapped properly", x)); \
309e985b929SDavid van Moolenbroek return; \
310e985b929SDavid van Moolenbroek } \
311e985b929SDavid van Moolenbroek } while (/*CONSTCOND*/0)
312e985b929SDavid van Moolenbroek #define cleanup_test() setup_test("cleanup")
313e985b929SDavid van Moolenbroek
314e985b929SDavid van Moolenbroek static void
test_simpleread(void)315e985b929SDavid van Moolenbroek test_simpleread(void)
316e985b929SDavid van Moolenbroek {
317e985b929SDavid van Moolenbroek struct event ev;
318e985b929SDavid van Moolenbroek
319e985b929SDavid van Moolenbroek /* Very simple read test */
320e985b929SDavid van Moolenbroek setup_test("Simple read: ");
321e985b929SDavid van Moolenbroek
322e985b929SDavid van Moolenbroek if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) {
323e985b929SDavid van Moolenbroek tt_fail_perror("write");
324e985b929SDavid van Moolenbroek }
325e985b929SDavid van Moolenbroek
326e985b929SDavid van Moolenbroek shutdown(pair[0], SHUT_WR);
327e985b929SDavid van Moolenbroek
328e985b929SDavid van Moolenbroek event_set(&ev, pair[1], EV_READ, simple_read_cb, &ev);
329e985b929SDavid van Moolenbroek if (event_add(&ev, NULL) == -1)
330e985b929SDavid van Moolenbroek exit(1);
331e985b929SDavid van Moolenbroek event_dispatch();
332e985b929SDavid van Moolenbroek
333e985b929SDavid van Moolenbroek cleanup_test();
334e985b929SDavid van Moolenbroek }
335e985b929SDavid van Moolenbroek
336e985b929SDavid van Moolenbroek static void
test_simplewrite(void)337e985b929SDavid van Moolenbroek test_simplewrite(void)
338e985b929SDavid van Moolenbroek {
339e985b929SDavid van Moolenbroek struct event ev;
340e985b929SDavid van Moolenbroek
341e985b929SDavid van Moolenbroek /* Very simple write test */
342e985b929SDavid van Moolenbroek setup_test("Simple write: ");
343e985b929SDavid van Moolenbroek
344e985b929SDavid van Moolenbroek event_set(&ev, pair[0], EV_WRITE, simple_write_cb, &ev);
345e985b929SDavid van Moolenbroek if (event_add(&ev, NULL) == -1)
346e985b929SDavid van Moolenbroek exit(1);
347e985b929SDavid van Moolenbroek event_dispatch();
348e985b929SDavid van Moolenbroek
349e985b929SDavid van Moolenbroek cleanup_test();
350e985b929SDavid van Moolenbroek }
351e985b929SDavid van Moolenbroek
352e985b929SDavid van Moolenbroek static void
simpleread_multiple_cb(evutil_socket_t fd,short event,void * arg)353e985b929SDavid van Moolenbroek simpleread_multiple_cb(evutil_socket_t fd, short event, void *arg)
354e985b929SDavid van Moolenbroek {
355e985b929SDavid van Moolenbroek if (++called == 2)
356e985b929SDavid van Moolenbroek test_ok = 1;
357e985b929SDavid van Moolenbroek }
358e985b929SDavid van Moolenbroek
359e985b929SDavid van Moolenbroek static void
test_simpleread_multiple(void)360e985b929SDavid van Moolenbroek test_simpleread_multiple(void)
361e985b929SDavid van Moolenbroek {
362e985b929SDavid van Moolenbroek struct event one, two;
363e985b929SDavid van Moolenbroek
364e985b929SDavid van Moolenbroek /* Very simple read test */
365e985b929SDavid van Moolenbroek setup_test("Simple read to multiple evens: ");
366e985b929SDavid van Moolenbroek
367e985b929SDavid van Moolenbroek if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) {
368e985b929SDavid van Moolenbroek tt_fail_perror("write");
369e985b929SDavid van Moolenbroek }
370e985b929SDavid van Moolenbroek
371e985b929SDavid van Moolenbroek shutdown(pair[0], SHUT_WR);
372e985b929SDavid van Moolenbroek
373e985b929SDavid van Moolenbroek event_set(&one, pair[1], EV_READ, simpleread_multiple_cb, NULL);
374e985b929SDavid van Moolenbroek if (event_add(&one, NULL) == -1)
375e985b929SDavid van Moolenbroek exit(1);
376e985b929SDavid van Moolenbroek event_set(&two, pair[1], EV_READ, simpleread_multiple_cb, NULL);
377e985b929SDavid van Moolenbroek if (event_add(&two, NULL) == -1)
378e985b929SDavid van Moolenbroek exit(1);
379e985b929SDavid van Moolenbroek event_dispatch();
380e985b929SDavid van Moolenbroek
381e985b929SDavid van Moolenbroek cleanup_test();
382e985b929SDavid van Moolenbroek }
383e985b929SDavid van Moolenbroek
384e985b929SDavid van Moolenbroek static int have_closed = 0;
385e985b929SDavid van Moolenbroek static int premature_event = 0;
386e985b929SDavid van Moolenbroek static void
simpleclose_close_fd_cb(evutil_socket_t s,short what,void * ptr)387e985b929SDavid van Moolenbroek simpleclose_close_fd_cb(evutil_socket_t s, short what, void *ptr)
388e985b929SDavid van Moolenbroek {
389e985b929SDavid van Moolenbroek evutil_socket_t **fds = ptr;
390e985b929SDavid van Moolenbroek TT_BLATHER(("Closing"));
391e985b929SDavid van Moolenbroek evutil_closesocket(*fds[0]);
392e985b929SDavid van Moolenbroek evutil_closesocket(*fds[1]);
393e985b929SDavid van Moolenbroek *fds[0] = -1;
394e985b929SDavid van Moolenbroek *fds[1] = -1;
395e985b929SDavid van Moolenbroek have_closed = 1;
396e985b929SDavid van Moolenbroek }
397e985b929SDavid van Moolenbroek
398e985b929SDavid van Moolenbroek static void
record_event_cb(evutil_socket_t s,short what,void * ptr)399e985b929SDavid van Moolenbroek record_event_cb(evutil_socket_t s, short what, void *ptr)
400e985b929SDavid van Moolenbroek {
401e985b929SDavid van Moolenbroek short *whatp = ptr;
402e985b929SDavid van Moolenbroek if (!have_closed)
403e985b929SDavid van Moolenbroek premature_event = 1;
404e985b929SDavid van Moolenbroek *whatp = what;
405e985b929SDavid van Moolenbroek TT_BLATHER(("Recorded %d on socket %d", (int)what, (int)s));
406e985b929SDavid van Moolenbroek }
407e985b929SDavid van Moolenbroek
408e985b929SDavid van Moolenbroek static void
test_simpleclose(void * ptr)409e985b929SDavid van Moolenbroek test_simpleclose(void *ptr)
410e985b929SDavid van Moolenbroek {
411e985b929SDavid van Moolenbroek /* Test that a close of FD is detected as a read and as a write. */
412e985b929SDavid van Moolenbroek struct event_base *base = event_base_new();
413e985b929SDavid van Moolenbroek evutil_socket_t pair1[2]={-1,-1}, pair2[2] = {-1, -1};
414e985b929SDavid van Moolenbroek evutil_socket_t *to_close[2];
415e985b929SDavid van Moolenbroek struct event *rev=NULL, *wev=NULL, *closeev=NULL;
416e985b929SDavid van Moolenbroek struct timeval tv;
417e985b929SDavid van Moolenbroek short got_read_on_close = 0, got_write_on_close = 0;
418e985b929SDavid van Moolenbroek char buf[1024];
419e985b929SDavid van Moolenbroek memset(buf, 99, sizeof(buf));
420e985b929SDavid van Moolenbroek #ifdef WIN32
421e985b929SDavid van Moolenbroek #define LOCAL_SOCKETPAIR_AF AF_INET
422e985b929SDavid van Moolenbroek #else
423e985b929SDavid van Moolenbroek #define LOCAL_SOCKETPAIR_AF AF_UNIX
424e985b929SDavid van Moolenbroek #endif
425e985b929SDavid van Moolenbroek if (evutil_socketpair(LOCAL_SOCKETPAIR_AF, SOCK_STREAM, 0, pair1)<0)
426e985b929SDavid van Moolenbroek TT_DIE(("socketpair: %s", strerror(errno)));
427e985b929SDavid van Moolenbroek if (evutil_socketpair(LOCAL_SOCKETPAIR_AF, SOCK_STREAM, 0, pair2)<0)
428e985b929SDavid van Moolenbroek TT_DIE(("socketpair: %s", strerror(errno)));
429e985b929SDavid van Moolenbroek if (evutil_make_socket_nonblocking(pair1[1]) < 0)
430e985b929SDavid van Moolenbroek TT_DIE(("make_socket_nonblocking"));
431e985b929SDavid van Moolenbroek if (evutil_make_socket_nonblocking(pair2[1]) < 0)
432e985b929SDavid van Moolenbroek TT_DIE(("make_socket_nonblocking"));
433e985b929SDavid van Moolenbroek
434e985b929SDavid van Moolenbroek /** Stuff pair2[1] full of data, until write fails */
435e985b929SDavid van Moolenbroek while (1) {
436e985b929SDavid van Moolenbroek int r = write(pair2[1], buf, sizeof(buf));
437e985b929SDavid van Moolenbroek if (r<0) {
438e985b929SDavid van Moolenbroek int err = evutil_socket_geterror(pair2[1]);
439e985b929SDavid van Moolenbroek if (! EVUTIL_ERR_RW_RETRIABLE(err))
440e985b929SDavid van Moolenbroek TT_DIE(("write failed strangely: %s",
441e985b929SDavid van Moolenbroek evutil_socket_error_to_string(err)));
442e985b929SDavid van Moolenbroek break;
443e985b929SDavid van Moolenbroek }
444e985b929SDavid van Moolenbroek }
445e985b929SDavid van Moolenbroek to_close[0] = &pair1[0];
446e985b929SDavid van Moolenbroek to_close[1] = &pair2[0];
447e985b929SDavid van Moolenbroek
448e985b929SDavid van Moolenbroek closeev = event_new(base, -1, EV_TIMEOUT, simpleclose_close_fd_cb,
449e985b929SDavid van Moolenbroek to_close);
450e985b929SDavid van Moolenbroek rev = event_new(base, pair1[1], EV_READ, record_event_cb,
451e985b929SDavid van Moolenbroek &got_read_on_close);
452e985b929SDavid van Moolenbroek TT_BLATHER(("Waiting for read on %d", (int)pair1[1]));
453e985b929SDavid van Moolenbroek wev = event_new(base, pair2[1], EV_WRITE, record_event_cb,
454e985b929SDavid van Moolenbroek &got_write_on_close);
455e985b929SDavid van Moolenbroek TT_BLATHER(("Waiting for write on %d", (int)pair2[1]));
456e985b929SDavid van Moolenbroek tv.tv_sec = 0;
457e985b929SDavid van Moolenbroek tv.tv_usec = 100*1000; /* Close pair1[0] after a little while, and make
458e985b929SDavid van Moolenbroek * sure we get a read event. */
459e985b929SDavid van Moolenbroek event_add(closeev, &tv);
460e985b929SDavid van Moolenbroek event_add(rev, NULL);
461e985b929SDavid van Moolenbroek event_add(wev, NULL);
462e985b929SDavid van Moolenbroek /* Don't let the test go on too long. */
463e985b929SDavid van Moolenbroek tv.tv_sec = 0;
464e985b929SDavid van Moolenbroek tv.tv_usec = 200*1000;
465e985b929SDavid van Moolenbroek event_base_loopexit(base, &tv);
466e985b929SDavid van Moolenbroek event_base_loop(base, 0);
467e985b929SDavid van Moolenbroek
468e985b929SDavid van Moolenbroek tt_int_op(got_read_on_close, ==, EV_READ);
469e985b929SDavid van Moolenbroek tt_int_op(got_write_on_close, ==, EV_WRITE);
470e985b929SDavid van Moolenbroek tt_int_op(premature_event, ==, 0);
471e985b929SDavid van Moolenbroek
472e985b929SDavid van Moolenbroek end:
473e985b929SDavid van Moolenbroek if (pair1[0] >= 0)
474e985b929SDavid van Moolenbroek evutil_closesocket(pair1[0]);
475e985b929SDavid van Moolenbroek if (pair1[1] >= 0)
476e985b929SDavid van Moolenbroek evutil_closesocket(pair1[1]);
477e985b929SDavid van Moolenbroek if (pair2[0] >= 0)
478e985b929SDavid van Moolenbroek evutil_closesocket(pair2[0]);
479e985b929SDavid van Moolenbroek if (pair2[1] >= 0)
480e985b929SDavid van Moolenbroek evutil_closesocket(pair2[1]);
481e985b929SDavid van Moolenbroek if (rev)
482e985b929SDavid van Moolenbroek event_free(rev);
483e985b929SDavid van Moolenbroek if (wev)
484e985b929SDavid van Moolenbroek event_free(wev);
485e985b929SDavid van Moolenbroek if (closeev)
486e985b929SDavid van Moolenbroek event_free(closeev);
487e985b929SDavid van Moolenbroek if (base)
488e985b929SDavid van Moolenbroek event_base_free(base);
489e985b929SDavid van Moolenbroek }
490e985b929SDavid van Moolenbroek
491e985b929SDavid van Moolenbroek
492e985b929SDavid van Moolenbroek static void
test_multiple(void)493e985b929SDavid van Moolenbroek test_multiple(void)
494e985b929SDavid van Moolenbroek {
495e985b929SDavid van Moolenbroek struct event ev, ev2;
496e985b929SDavid van Moolenbroek int i;
497e985b929SDavid van Moolenbroek
498e985b929SDavid van Moolenbroek /* Multiple read and write test */
499e985b929SDavid van Moolenbroek setup_test("Multiple read/write: ");
500e985b929SDavid van Moolenbroek memset(rbuf, 0, sizeof(rbuf));
501e985b929SDavid van Moolenbroek for (i = 0; i < (int)sizeof(wbuf); i++)
502e985b929SDavid van Moolenbroek wbuf[i] = i;
503e985b929SDavid van Moolenbroek
504e985b929SDavid van Moolenbroek roff = woff = 0;
505e985b929SDavid van Moolenbroek usepersist = 0;
506e985b929SDavid van Moolenbroek
507e985b929SDavid van Moolenbroek event_set(&ev, pair[0], EV_WRITE, multiple_write_cb, &ev);
508e985b929SDavid van Moolenbroek if (event_add(&ev, NULL) == -1)
509e985b929SDavid van Moolenbroek exit(1);
510e985b929SDavid van Moolenbroek event_set(&ev2, pair[1], EV_READ, multiple_read_cb, &ev2);
511e985b929SDavid van Moolenbroek if (event_add(&ev2, NULL) == -1)
512e985b929SDavid van Moolenbroek exit(1);
513e985b929SDavid van Moolenbroek event_dispatch();
514e985b929SDavid van Moolenbroek
515e985b929SDavid van Moolenbroek if (roff == woff)
516e985b929SDavid van Moolenbroek test_ok = memcmp(rbuf, wbuf, sizeof(wbuf)) == 0;
517e985b929SDavid van Moolenbroek
518e985b929SDavid van Moolenbroek cleanup_test();
519e985b929SDavid van Moolenbroek }
520e985b929SDavid van Moolenbroek
521e985b929SDavid van Moolenbroek static void
test_persistent(void)522e985b929SDavid van Moolenbroek test_persistent(void)
523e985b929SDavid van Moolenbroek {
524e985b929SDavid van Moolenbroek struct event ev, ev2;
525e985b929SDavid van Moolenbroek int i;
526e985b929SDavid van Moolenbroek
527e985b929SDavid van Moolenbroek /* Multiple read and write test with persist */
528e985b929SDavid van Moolenbroek setup_test("Persist read/write: ");
529e985b929SDavid van Moolenbroek memset(rbuf, 0, sizeof(rbuf));
530e985b929SDavid van Moolenbroek for (i = 0; i < (int)sizeof(wbuf); i++)
531e985b929SDavid van Moolenbroek wbuf[i] = i;
532e985b929SDavid van Moolenbroek
533e985b929SDavid van Moolenbroek roff = woff = 0;
534e985b929SDavid van Moolenbroek usepersist = 1;
535e985b929SDavid van Moolenbroek
536e985b929SDavid van Moolenbroek event_set(&ev, pair[0], EV_WRITE|EV_PERSIST, multiple_write_cb, &ev);
537e985b929SDavid van Moolenbroek if (event_add(&ev, NULL) == -1)
538e985b929SDavid van Moolenbroek exit(1);
539e985b929SDavid van Moolenbroek event_set(&ev2, pair[1], EV_READ|EV_PERSIST, multiple_read_cb, &ev2);
540e985b929SDavid van Moolenbroek if (event_add(&ev2, NULL) == -1)
541e985b929SDavid van Moolenbroek exit(1);
542e985b929SDavid van Moolenbroek event_dispatch();
543e985b929SDavid van Moolenbroek
544e985b929SDavid van Moolenbroek if (roff == woff)
545e985b929SDavid van Moolenbroek test_ok = memcmp(rbuf, wbuf, sizeof(wbuf)) == 0;
546e985b929SDavid van Moolenbroek
547e985b929SDavid van Moolenbroek cleanup_test();
548e985b929SDavid van Moolenbroek }
549e985b929SDavid van Moolenbroek
550e985b929SDavid van Moolenbroek static void
test_combined(void)551e985b929SDavid van Moolenbroek test_combined(void)
552e985b929SDavid van Moolenbroek {
553e985b929SDavid van Moolenbroek struct both r1, r2, w1, w2;
554e985b929SDavid van Moolenbroek
555e985b929SDavid van Moolenbroek setup_test("Combined read/write: ");
556e985b929SDavid van Moolenbroek memset(&r1, 0, sizeof(r1));
557e985b929SDavid van Moolenbroek memset(&r2, 0, sizeof(r2));
558e985b929SDavid van Moolenbroek memset(&w1, 0, sizeof(w1));
559e985b929SDavid van Moolenbroek memset(&w2, 0, sizeof(w2));
560e985b929SDavid van Moolenbroek
561e985b929SDavid van Moolenbroek w1.nread = 4096;
562e985b929SDavid van Moolenbroek w2.nread = 8192;
563e985b929SDavid van Moolenbroek
564e985b929SDavid van Moolenbroek event_set(&r1.ev, pair[0], EV_READ, combined_read_cb, &r1);
565e985b929SDavid van Moolenbroek event_set(&w1.ev, pair[0], EV_WRITE, combined_write_cb, &w1);
566e985b929SDavid van Moolenbroek event_set(&r2.ev, pair[1], EV_READ, combined_read_cb, &r2);
567e985b929SDavid van Moolenbroek event_set(&w2.ev, pair[1], EV_WRITE, combined_write_cb, &w2);
568e985b929SDavid van Moolenbroek tt_assert(event_add(&r1.ev, NULL) != -1);
569e985b929SDavid van Moolenbroek tt_assert(!event_add(&w1.ev, NULL));
570e985b929SDavid van Moolenbroek tt_assert(!event_add(&r2.ev, NULL));
571e985b929SDavid van Moolenbroek tt_assert(!event_add(&w2.ev, NULL));
572e985b929SDavid van Moolenbroek event_dispatch();
573e985b929SDavid van Moolenbroek
574e985b929SDavid van Moolenbroek if (r1.nread == 8192 && r2.nread == 4096)
575e985b929SDavid van Moolenbroek test_ok = 1;
576e985b929SDavid van Moolenbroek
577e985b929SDavid van Moolenbroek end:
578e985b929SDavid van Moolenbroek cleanup_test();
579e985b929SDavid van Moolenbroek }
580e985b929SDavid van Moolenbroek
581e985b929SDavid van Moolenbroek static void
test_simpletimeout(void)582e985b929SDavid van Moolenbroek test_simpletimeout(void)
583e985b929SDavid van Moolenbroek {
584e985b929SDavid van Moolenbroek struct timeval tv;
585e985b929SDavid van Moolenbroek struct event ev;
586e985b929SDavid van Moolenbroek
587e985b929SDavid van Moolenbroek setup_test("Simple timeout: ");
588e985b929SDavid van Moolenbroek
589e985b929SDavid van Moolenbroek tv.tv_usec = 0;
590e985b929SDavid van Moolenbroek tv.tv_sec = SECONDS;
591e985b929SDavid van Moolenbroek evtimer_set(&ev, timeout_cb, NULL);
592e985b929SDavid van Moolenbroek evtimer_add(&ev, &tv);
593e985b929SDavid van Moolenbroek
594e985b929SDavid van Moolenbroek evutil_gettimeofday(&tset, NULL);
595e985b929SDavid van Moolenbroek event_dispatch();
596e985b929SDavid van Moolenbroek
597e985b929SDavid van Moolenbroek cleanup_test();
598e985b929SDavid van Moolenbroek }
599e985b929SDavid van Moolenbroek
600e985b929SDavid van Moolenbroek static void
periodic_timeout_cb(evutil_socket_t fd,short event,void * arg)601e985b929SDavid van Moolenbroek periodic_timeout_cb(evutil_socket_t fd, short event, void *arg)
602e985b929SDavid van Moolenbroek {
603e985b929SDavid van Moolenbroek int *count = arg;
604e985b929SDavid van Moolenbroek
605e985b929SDavid van Moolenbroek (*count)++;
606e985b929SDavid van Moolenbroek if (*count == 6) {
607e985b929SDavid van Moolenbroek /* call loopexit only once - on slow machines(?), it is
608e985b929SDavid van Moolenbroek * apparently possible for this to get called twice. */
609e985b929SDavid van Moolenbroek test_ok = 1;
610e985b929SDavid van Moolenbroek event_base_loopexit(global_base, NULL);
611e985b929SDavid van Moolenbroek }
612e985b929SDavid van Moolenbroek }
613e985b929SDavid van Moolenbroek
614e985b929SDavid van Moolenbroek static void
test_persistent_timeout(void)615e985b929SDavid van Moolenbroek test_persistent_timeout(void)
616e985b929SDavid van Moolenbroek {
617e985b929SDavid van Moolenbroek struct timeval tv;
618e985b929SDavid van Moolenbroek struct event ev;
619e985b929SDavid van Moolenbroek int count = 0;
620e985b929SDavid van Moolenbroek
621e985b929SDavid van Moolenbroek evutil_timerclear(&tv);
622e985b929SDavid van Moolenbroek tv.tv_usec = 10000;
623e985b929SDavid van Moolenbroek
624e985b929SDavid van Moolenbroek event_assign(&ev, global_base, -1, EV_TIMEOUT|EV_PERSIST,
625e985b929SDavid van Moolenbroek periodic_timeout_cb, &count);
626e985b929SDavid van Moolenbroek event_add(&ev, &tv);
627e985b929SDavid van Moolenbroek
628e985b929SDavid van Moolenbroek event_dispatch();
629e985b929SDavid van Moolenbroek
630e985b929SDavid van Moolenbroek event_del(&ev);
631e985b929SDavid van Moolenbroek }
632e985b929SDavid van Moolenbroek
633e985b929SDavid van Moolenbroek static void
test_persistent_timeout_jump(void * ptr)634e985b929SDavid van Moolenbroek test_persistent_timeout_jump(void *ptr)
635e985b929SDavid van Moolenbroek {
636e985b929SDavid van Moolenbroek struct basic_test_data *data = ptr;
637e985b929SDavid van Moolenbroek struct event ev;
638e985b929SDavid van Moolenbroek int count = 0;
639e985b929SDavid van Moolenbroek struct timeval msec100 = { 0, 100 * 1000 };
640e985b929SDavid van Moolenbroek struct timeval msec50 = { 0, 50 * 1000 };
641e985b929SDavid van Moolenbroek
642e985b929SDavid van Moolenbroek event_assign(&ev, data->base, -1, EV_PERSIST, periodic_timeout_cb, &count);
643e985b929SDavid van Moolenbroek event_add(&ev, &msec100);
644e985b929SDavid van Moolenbroek /* Wait for a bit */
645e985b929SDavid van Moolenbroek #ifdef _WIN32
646e985b929SDavid van Moolenbroek Sleep(1000);
647e985b929SDavid van Moolenbroek #else
648e985b929SDavid van Moolenbroek sleep(1);
649e985b929SDavid van Moolenbroek #endif
650e985b929SDavid van Moolenbroek event_base_loopexit(data->base, &msec50);
651e985b929SDavid van Moolenbroek event_base_dispatch(data->base);
652e985b929SDavid van Moolenbroek tt_int_op(count, ==, 1);
653e985b929SDavid van Moolenbroek
654e985b929SDavid van Moolenbroek end:
655e985b929SDavid van Moolenbroek event_del(&ev);
656e985b929SDavid van Moolenbroek }
657e985b929SDavid van Moolenbroek
658e985b929SDavid van Moolenbroek struct persist_active_timeout_called {
659e985b929SDavid van Moolenbroek int n;
660e985b929SDavid van Moolenbroek short events[16];
661e985b929SDavid van Moolenbroek struct timeval tvs[16];
662e985b929SDavid van Moolenbroek };
663e985b929SDavid van Moolenbroek
664e985b929SDavid van Moolenbroek static void
activate_cb(evutil_socket_t fd,short event,void * arg)665e985b929SDavid van Moolenbroek activate_cb(evutil_socket_t fd, short event, void *arg)
666e985b929SDavid van Moolenbroek {
667e985b929SDavid van Moolenbroek struct event *ev = arg;
668e985b929SDavid van Moolenbroek event_active(ev, EV_READ, 1);
669e985b929SDavid van Moolenbroek }
670e985b929SDavid van Moolenbroek
671e985b929SDavid van Moolenbroek static void
persist_active_timeout_cb(evutil_socket_t fd,short event,void * arg)672e985b929SDavid van Moolenbroek persist_active_timeout_cb(evutil_socket_t fd, short event, void *arg)
673e985b929SDavid van Moolenbroek {
674e985b929SDavid van Moolenbroek struct persist_active_timeout_called *c = arg;
675e985b929SDavid van Moolenbroek if (c->n < 15) {
676e985b929SDavid van Moolenbroek c->events[c->n] = event;
677e985b929SDavid van Moolenbroek evutil_gettimeofday(&c->tvs[c->n], NULL);
678e985b929SDavid van Moolenbroek ++c->n;
679e985b929SDavid van Moolenbroek }
680e985b929SDavid van Moolenbroek }
681e985b929SDavid van Moolenbroek
682e985b929SDavid van Moolenbroek static void
test_persistent_active_timeout(void * ptr)683e985b929SDavid van Moolenbroek test_persistent_active_timeout(void *ptr)
684e985b929SDavid van Moolenbroek {
685e985b929SDavid van Moolenbroek struct timeval tv, tv2, tv_exit, start;
686e985b929SDavid van Moolenbroek struct event ev;
687e985b929SDavid van Moolenbroek struct persist_active_timeout_called res;
688e985b929SDavid van Moolenbroek
689e985b929SDavid van Moolenbroek struct basic_test_data *data = ptr;
690e985b929SDavid van Moolenbroek struct event_base *base = data->base;
691e985b929SDavid van Moolenbroek
692e985b929SDavid van Moolenbroek memset(&res, 0, sizeof(res));
693e985b929SDavid van Moolenbroek
694e985b929SDavid van Moolenbroek tv.tv_sec = 0;
695e985b929SDavid van Moolenbroek tv.tv_usec = 200 * 1000;
696e985b929SDavid van Moolenbroek event_assign(&ev, base, -1, EV_TIMEOUT|EV_PERSIST,
697e985b929SDavid van Moolenbroek persist_active_timeout_cb, &res);
698e985b929SDavid van Moolenbroek event_add(&ev, &tv);
699e985b929SDavid van Moolenbroek
700e985b929SDavid van Moolenbroek tv2.tv_sec = 0;
701e985b929SDavid van Moolenbroek tv2.tv_usec = 100 * 1000;
702e985b929SDavid van Moolenbroek event_base_once(base, -1, EV_TIMEOUT, activate_cb, &ev, &tv2);
703e985b929SDavid van Moolenbroek
704e985b929SDavid van Moolenbroek tv_exit.tv_sec = 0;
705e985b929SDavid van Moolenbroek tv_exit.tv_usec = 600 * 1000;
706e985b929SDavid van Moolenbroek event_base_loopexit(base, &tv_exit);
707e985b929SDavid van Moolenbroek
708e985b929SDavid van Moolenbroek event_base_assert_ok(base);
709e985b929SDavid van Moolenbroek evutil_gettimeofday(&start, NULL);
710e985b929SDavid van Moolenbroek
711e985b929SDavid van Moolenbroek event_base_dispatch(base);
712e985b929SDavid van Moolenbroek event_base_assert_ok(base);
713e985b929SDavid van Moolenbroek
714e985b929SDavid van Moolenbroek tt_int_op(res.n, ==, 3);
715e985b929SDavid van Moolenbroek tt_int_op(res.events[0], ==, EV_READ);
716e985b929SDavid van Moolenbroek tt_int_op(res.events[1], ==, EV_TIMEOUT);
717e985b929SDavid van Moolenbroek tt_int_op(res.events[2], ==, EV_TIMEOUT);
718e985b929SDavid van Moolenbroek test_timeval_diff_eq(&start, &res.tvs[0], 100);
719e985b929SDavid van Moolenbroek test_timeval_diff_eq(&start, &res.tvs[1], 300);
720e985b929SDavid van Moolenbroek test_timeval_diff_eq(&start, &res.tvs[2], 500);
721e985b929SDavid van Moolenbroek end:
722e985b929SDavid van Moolenbroek event_del(&ev);
723e985b929SDavid van Moolenbroek }
724e985b929SDavid van Moolenbroek
725e985b929SDavid van Moolenbroek struct common_timeout_info {
726e985b929SDavid van Moolenbroek struct event ev;
727e985b929SDavid van Moolenbroek struct timeval called_at;
728e985b929SDavid van Moolenbroek int which;
729e985b929SDavid van Moolenbroek int count;
730e985b929SDavid van Moolenbroek };
731e985b929SDavid van Moolenbroek
732e985b929SDavid van Moolenbroek static void
common_timeout_cb(evutil_socket_t fd,short event,void * arg)733e985b929SDavid van Moolenbroek common_timeout_cb(evutil_socket_t fd, short event, void *arg)
734e985b929SDavid van Moolenbroek {
735e985b929SDavid van Moolenbroek struct common_timeout_info *ti = arg;
736e985b929SDavid van Moolenbroek ++ti->count;
737e985b929SDavid van Moolenbroek evutil_gettimeofday(&ti->called_at, NULL);
738e985b929SDavid van Moolenbroek if (ti->count >= 6)
739e985b929SDavid van Moolenbroek event_del(&ti->ev);
740e985b929SDavid van Moolenbroek }
741e985b929SDavid van Moolenbroek
742e985b929SDavid van Moolenbroek static void
test_common_timeout(void * ptr)743e985b929SDavid van Moolenbroek test_common_timeout(void *ptr)
744e985b929SDavid van Moolenbroek {
745e985b929SDavid van Moolenbroek struct basic_test_data *data = ptr;
746e985b929SDavid van Moolenbroek
747e985b929SDavid van Moolenbroek struct event_base *base = data->base;
748e985b929SDavid van Moolenbroek int i;
749e985b929SDavid van Moolenbroek struct common_timeout_info info[100];
750e985b929SDavid van Moolenbroek
751e985b929SDavid van Moolenbroek struct timeval now;
752e985b929SDavid van Moolenbroek struct timeval tmp_100_ms = { 0, 100*1000 };
753e985b929SDavid van Moolenbroek struct timeval tmp_200_ms = { 0, 200*1000 };
754e985b929SDavid van Moolenbroek
755e985b929SDavid van Moolenbroek const struct timeval *ms_100, *ms_200;
756e985b929SDavid van Moolenbroek
757e985b929SDavid van Moolenbroek ms_100 = event_base_init_common_timeout(base, &tmp_100_ms);
758e985b929SDavid van Moolenbroek ms_200 = event_base_init_common_timeout(base, &tmp_200_ms);
759e985b929SDavid van Moolenbroek tt_assert(ms_100);
760e985b929SDavid van Moolenbroek tt_assert(ms_200);
761e985b929SDavid van Moolenbroek tt_ptr_op(event_base_init_common_timeout(base, &tmp_200_ms),
762e985b929SDavid van Moolenbroek ==, ms_200);
763e985b929SDavid van Moolenbroek tt_int_op(ms_100->tv_sec, ==, 0);
764e985b929SDavid van Moolenbroek tt_int_op(ms_200->tv_sec, ==, 0);
765e985b929SDavid van Moolenbroek tt_int_op(ms_100->tv_usec, ==, 100000|0x50000000);
766e985b929SDavid van Moolenbroek tt_int_op(ms_200->tv_usec, ==, 200000|0x50100000);
767e985b929SDavid van Moolenbroek
768e985b929SDavid van Moolenbroek memset(info, 0, sizeof(info));
769e985b929SDavid van Moolenbroek
770e985b929SDavid van Moolenbroek for (i=0; i<100; ++i) {
771e985b929SDavid van Moolenbroek info[i].which = i;
772e985b929SDavid van Moolenbroek event_assign(&info[i].ev, base, -1, EV_TIMEOUT|EV_PERSIST,
773e985b929SDavid van Moolenbroek common_timeout_cb, &info[i]);
774e985b929SDavid van Moolenbroek if (i % 2) {
775e985b929SDavid van Moolenbroek event_add(&info[i].ev, ms_100);
776e985b929SDavid van Moolenbroek } else {
777e985b929SDavid van Moolenbroek event_add(&info[i].ev, ms_200);
778e985b929SDavid van Moolenbroek }
779e985b929SDavid van Moolenbroek }
780e985b929SDavid van Moolenbroek
781e985b929SDavid van Moolenbroek event_base_assert_ok(base);
782e985b929SDavid van Moolenbroek event_base_dispatch(base);
783e985b929SDavid van Moolenbroek
784e985b929SDavid van Moolenbroek evutil_gettimeofday(&now, NULL);
785e985b929SDavid van Moolenbroek event_base_assert_ok(base);
786e985b929SDavid van Moolenbroek
787e985b929SDavid van Moolenbroek for (i=0; i<10; ++i) {
788e985b929SDavid van Moolenbroek struct timeval tmp;
789e985b929SDavid van Moolenbroek int ms_diff;
790e985b929SDavid van Moolenbroek tt_int_op(info[i].count, ==, 6);
791e985b929SDavid van Moolenbroek evutil_timersub(&now, &info[i].called_at, &tmp);
792e985b929SDavid van Moolenbroek ms_diff = tmp.tv_usec/1000 + tmp.tv_sec*1000;
793e985b929SDavid van Moolenbroek if (i % 2) {
794e985b929SDavid van Moolenbroek tt_int_op(ms_diff, >, 500);
795e985b929SDavid van Moolenbroek tt_int_op(ms_diff, <, 700);
796e985b929SDavid van Moolenbroek } else {
797e985b929SDavid van Moolenbroek tt_int_op(ms_diff, >, -100);
798e985b929SDavid van Moolenbroek tt_int_op(ms_diff, <, 100);
799e985b929SDavid van Moolenbroek }
800e985b929SDavid van Moolenbroek }
801e985b929SDavid van Moolenbroek
802e985b929SDavid van Moolenbroek /* Make sure we can free the base with some events in. */
803e985b929SDavid van Moolenbroek for (i=0; i<100; ++i) {
804e985b929SDavid van Moolenbroek if (i % 2) {
805e985b929SDavid van Moolenbroek event_add(&info[i].ev, ms_100);
806e985b929SDavid van Moolenbroek } else {
807e985b929SDavid van Moolenbroek event_add(&info[i].ev, ms_200);
808e985b929SDavid van Moolenbroek }
809e985b929SDavid van Moolenbroek }
810e985b929SDavid van Moolenbroek
811e985b929SDavid van Moolenbroek end:
812e985b929SDavid van Moolenbroek event_base_free(data->base); /* need to do this here before info is
813e985b929SDavid van Moolenbroek * out-of-scope */
814e985b929SDavid van Moolenbroek data->base = NULL;
815e985b929SDavid van Moolenbroek }
816e985b929SDavid van Moolenbroek
817e985b929SDavid van Moolenbroek #ifndef WIN32
818e985b929SDavid van Moolenbroek static void signal_cb(evutil_socket_t fd, short event, void *arg);
819e985b929SDavid van Moolenbroek
820e985b929SDavid van Moolenbroek #define current_base event_global_current_base_
821e985b929SDavid van Moolenbroek extern struct event_base *current_base;
822e985b929SDavid van Moolenbroek
823e985b929SDavid van Moolenbroek static void
child_signal_cb(evutil_socket_t fd,short event,void * arg)824e985b929SDavid van Moolenbroek child_signal_cb(evutil_socket_t fd, short event, void *arg)
825e985b929SDavid van Moolenbroek {
826e985b929SDavid van Moolenbroek struct timeval tv;
827e985b929SDavid van Moolenbroek int *pint = arg;
828e985b929SDavid van Moolenbroek
829e985b929SDavid van Moolenbroek *pint = 1;
830e985b929SDavid van Moolenbroek
831e985b929SDavid van Moolenbroek tv.tv_usec = 500000;
832e985b929SDavid van Moolenbroek tv.tv_sec = 0;
833e985b929SDavid van Moolenbroek event_loopexit(&tv);
834e985b929SDavid van Moolenbroek }
835e985b929SDavid van Moolenbroek
836e985b929SDavid van Moolenbroek static void
test_fork(void)837e985b929SDavid van Moolenbroek test_fork(void)
838e985b929SDavid van Moolenbroek {
839e985b929SDavid van Moolenbroek int status, got_sigchld = 0;
840e985b929SDavid van Moolenbroek struct event ev, sig_ev;
841e985b929SDavid van Moolenbroek pid_t pid;
842e985b929SDavid van Moolenbroek
843e985b929SDavid van Moolenbroek setup_test("After fork: ");
844e985b929SDavid van Moolenbroek
845e985b929SDavid van Moolenbroek tt_assert(current_base);
846e985b929SDavid van Moolenbroek evthread_make_base_notifiable(current_base);
847e985b929SDavid van Moolenbroek
848e985b929SDavid van Moolenbroek if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) {
849e985b929SDavid van Moolenbroek tt_fail_perror("write");
850e985b929SDavid van Moolenbroek }
851e985b929SDavid van Moolenbroek
852e985b929SDavid van Moolenbroek event_set(&ev, pair[1], EV_READ, simple_read_cb, &ev);
853e985b929SDavid van Moolenbroek if (event_add(&ev, NULL) == -1)
854e985b929SDavid van Moolenbroek exit(1);
855e985b929SDavid van Moolenbroek
856e985b929SDavid van Moolenbroek evsignal_set(&sig_ev, SIGCHLD, child_signal_cb, &got_sigchld);
857e985b929SDavid van Moolenbroek evsignal_add(&sig_ev, NULL);
858e985b929SDavid van Moolenbroek
859e985b929SDavid van Moolenbroek event_base_assert_ok(current_base);
860e985b929SDavid van Moolenbroek TT_BLATHER(("Before fork"));
861e985b929SDavid van Moolenbroek if ((pid = regress_fork()) == 0) {
862e985b929SDavid van Moolenbroek /* in the child */
863e985b929SDavid van Moolenbroek TT_BLATHER(("In child, before reinit"));
864e985b929SDavid van Moolenbroek event_base_assert_ok(current_base);
865e985b929SDavid van Moolenbroek if (event_reinit(current_base) == -1) {
866e985b929SDavid van Moolenbroek fprintf(stdout, "FAILED (reinit)\n");
867e985b929SDavid van Moolenbroek exit(1);
868e985b929SDavid van Moolenbroek }
869e985b929SDavid van Moolenbroek TT_BLATHER(("After reinit"));
870e985b929SDavid van Moolenbroek event_base_assert_ok(current_base);
871e985b929SDavid van Moolenbroek TT_BLATHER(("After assert-ok"));
872e985b929SDavid van Moolenbroek
873e985b929SDavid van Moolenbroek evsignal_del(&sig_ev);
874e985b929SDavid van Moolenbroek
875e985b929SDavid van Moolenbroek called = 0;
876e985b929SDavid van Moolenbroek
877e985b929SDavid van Moolenbroek event_dispatch();
878e985b929SDavid van Moolenbroek
879e985b929SDavid van Moolenbroek event_base_free(current_base);
880e985b929SDavid van Moolenbroek
881e985b929SDavid van Moolenbroek /* we do not send an EOF; simple_read_cb requires an EOF
882e985b929SDavid van Moolenbroek * to set test_ok. we just verify that the callback was
883e985b929SDavid van Moolenbroek * called. */
884e985b929SDavid van Moolenbroek exit(test_ok != 0 || called != 2 ? -2 : 76);
885e985b929SDavid van Moolenbroek }
886e985b929SDavid van Moolenbroek
887e985b929SDavid van Moolenbroek /* wait for the child to read the data */
888e985b929SDavid van Moolenbroek sleep(1);
889e985b929SDavid van Moolenbroek
890e985b929SDavid van Moolenbroek if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) {
891e985b929SDavid van Moolenbroek tt_fail_perror("write");
892e985b929SDavid van Moolenbroek }
893e985b929SDavid van Moolenbroek
894e985b929SDavid van Moolenbroek TT_BLATHER(("Before waitpid"));
895e985b929SDavid van Moolenbroek if (waitpid(pid, &status, 0) == -1) {
896e985b929SDavid van Moolenbroek fprintf(stdout, "FAILED (fork)\n");
897e985b929SDavid van Moolenbroek exit(1);
898e985b929SDavid van Moolenbroek }
899e985b929SDavid van Moolenbroek TT_BLATHER(("After waitpid"));
900e985b929SDavid van Moolenbroek
901e985b929SDavid van Moolenbroek if (WEXITSTATUS(status) != 76) {
902e985b929SDavid van Moolenbroek fprintf(stdout, "FAILED (exit): %d\n", WEXITSTATUS(status));
903e985b929SDavid van Moolenbroek exit(1);
904e985b929SDavid van Moolenbroek }
905e985b929SDavid van Moolenbroek
906e985b929SDavid van Moolenbroek /* test that the current event loop still works */
907e985b929SDavid van Moolenbroek if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) {
908e985b929SDavid van Moolenbroek fprintf(stderr, "%s: write\n", __func__);
909e985b929SDavid van Moolenbroek }
910e985b929SDavid van Moolenbroek
911e985b929SDavid van Moolenbroek shutdown(pair[0], SHUT_WR);
912e985b929SDavid van Moolenbroek
913e985b929SDavid van Moolenbroek event_dispatch();
914e985b929SDavid van Moolenbroek
915e985b929SDavid van Moolenbroek if (!got_sigchld) {
916e985b929SDavid van Moolenbroek fprintf(stdout, "FAILED (sigchld)\n");
917e985b929SDavid van Moolenbroek exit(1);
918e985b929SDavid van Moolenbroek }
919e985b929SDavid van Moolenbroek
920e985b929SDavid van Moolenbroek evsignal_del(&sig_ev);
921e985b929SDavid van Moolenbroek
922e985b929SDavid van Moolenbroek end:
923e985b929SDavid van Moolenbroek cleanup_test();
924e985b929SDavid van Moolenbroek }
925e985b929SDavid van Moolenbroek
926e985b929SDavid van Moolenbroek static void
signal_cb_sa(int sig)927e985b929SDavid van Moolenbroek signal_cb_sa(int sig)
928e985b929SDavid van Moolenbroek {
929e985b929SDavid van Moolenbroek test_ok = 2;
930e985b929SDavid van Moolenbroek }
931e985b929SDavid van Moolenbroek
932e985b929SDavid van Moolenbroek static void
signal_cb(evutil_socket_t fd,short event,void * arg)933e985b929SDavid van Moolenbroek signal_cb(evutil_socket_t fd, short event, void *arg)
934e985b929SDavid van Moolenbroek {
935e985b929SDavid van Moolenbroek struct event *ev = arg;
936e985b929SDavid van Moolenbroek
937e985b929SDavid van Moolenbroek evsignal_del(ev);
938e985b929SDavid van Moolenbroek test_ok = 1;
939e985b929SDavid van Moolenbroek }
940e985b929SDavid van Moolenbroek
941e985b929SDavid van Moolenbroek static void
test_simplesignal(void)942e985b929SDavid van Moolenbroek test_simplesignal(void)
943e985b929SDavid van Moolenbroek {
944e985b929SDavid van Moolenbroek struct event ev;
945e985b929SDavid van Moolenbroek struct itimerval itv;
946e985b929SDavid van Moolenbroek
947e985b929SDavid van Moolenbroek setup_test("Simple signal: ");
948e985b929SDavid van Moolenbroek evsignal_set(&ev, SIGALRM, signal_cb, &ev);
949e985b929SDavid van Moolenbroek evsignal_add(&ev, NULL);
950e985b929SDavid van Moolenbroek /* find bugs in which operations are re-ordered */
951e985b929SDavid van Moolenbroek evsignal_del(&ev);
952e985b929SDavid van Moolenbroek evsignal_add(&ev, NULL);
953e985b929SDavid van Moolenbroek
954e985b929SDavid van Moolenbroek memset(&itv, 0, sizeof(itv));
955e985b929SDavid van Moolenbroek itv.it_value.tv_sec = 1;
956e985b929SDavid van Moolenbroek if (setitimer(ITIMER_REAL, &itv, NULL) == -1)
957e985b929SDavid van Moolenbroek goto skip_simplesignal;
958e985b929SDavid van Moolenbroek
959e985b929SDavid van Moolenbroek event_dispatch();
960e985b929SDavid van Moolenbroek skip_simplesignal:
961e985b929SDavid van Moolenbroek if (evsignal_del(&ev) == -1)
962e985b929SDavid van Moolenbroek test_ok = 0;
963e985b929SDavid van Moolenbroek
964e985b929SDavid van Moolenbroek cleanup_test();
965e985b929SDavid van Moolenbroek }
966e985b929SDavid van Moolenbroek
967e985b929SDavid van Moolenbroek static void
test_multiplesignal(void)968e985b929SDavid van Moolenbroek test_multiplesignal(void)
969e985b929SDavid van Moolenbroek {
970e985b929SDavid van Moolenbroek struct event ev_one, ev_two;
971e985b929SDavid van Moolenbroek struct itimerval itv;
972e985b929SDavid van Moolenbroek
973e985b929SDavid van Moolenbroek setup_test("Multiple signal: ");
974e985b929SDavid van Moolenbroek
975e985b929SDavid van Moolenbroek evsignal_set(&ev_one, SIGALRM, signal_cb, &ev_one);
976e985b929SDavid van Moolenbroek evsignal_add(&ev_one, NULL);
977e985b929SDavid van Moolenbroek
978e985b929SDavid van Moolenbroek evsignal_set(&ev_two, SIGALRM, signal_cb, &ev_two);
979e985b929SDavid van Moolenbroek evsignal_add(&ev_two, NULL);
980e985b929SDavid van Moolenbroek
981e985b929SDavid van Moolenbroek memset(&itv, 0, sizeof(itv));
982e985b929SDavid van Moolenbroek itv.it_value.tv_sec = 1;
983e985b929SDavid van Moolenbroek if (setitimer(ITIMER_REAL, &itv, NULL) == -1)
984e985b929SDavid van Moolenbroek goto skip_simplesignal;
985e985b929SDavid van Moolenbroek
986e985b929SDavid van Moolenbroek event_dispatch();
987e985b929SDavid van Moolenbroek
988e985b929SDavid van Moolenbroek skip_simplesignal:
989e985b929SDavid van Moolenbroek if (evsignal_del(&ev_one) == -1)
990e985b929SDavid van Moolenbroek test_ok = 0;
991e985b929SDavid van Moolenbroek if (evsignal_del(&ev_two) == -1)
992e985b929SDavid van Moolenbroek test_ok = 0;
993e985b929SDavid van Moolenbroek
994e985b929SDavid van Moolenbroek cleanup_test();
995e985b929SDavid van Moolenbroek }
996e985b929SDavid van Moolenbroek
997e985b929SDavid van Moolenbroek static void
test_immediatesignal(void)998e985b929SDavid van Moolenbroek test_immediatesignal(void)
999e985b929SDavid van Moolenbroek {
1000e985b929SDavid van Moolenbroek struct event ev;
1001e985b929SDavid van Moolenbroek
1002e985b929SDavid van Moolenbroek test_ok = 0;
1003e985b929SDavid van Moolenbroek evsignal_set(&ev, SIGUSR1, signal_cb, &ev);
1004e985b929SDavid van Moolenbroek evsignal_add(&ev, NULL);
1005e985b929SDavid van Moolenbroek raise(SIGUSR1);
1006e985b929SDavid van Moolenbroek event_loop(EVLOOP_NONBLOCK);
1007e985b929SDavid van Moolenbroek evsignal_del(&ev);
1008e985b929SDavid van Moolenbroek cleanup_test();
1009e985b929SDavid van Moolenbroek }
1010e985b929SDavid van Moolenbroek
1011e985b929SDavid van Moolenbroek static void
test_signal_dealloc(void)1012e985b929SDavid van Moolenbroek test_signal_dealloc(void)
1013e985b929SDavid van Moolenbroek {
1014e985b929SDavid van Moolenbroek /* make sure that evsignal_event is event_del'ed and pipe closed */
1015e985b929SDavid van Moolenbroek struct event ev;
1016e985b929SDavid van Moolenbroek struct event_base *base = event_init();
1017e985b929SDavid van Moolenbroek evsignal_set(&ev, SIGUSR1, signal_cb, &ev);
1018e985b929SDavid van Moolenbroek evsignal_add(&ev, NULL);
1019e985b929SDavid van Moolenbroek evsignal_del(&ev);
1020e985b929SDavid van Moolenbroek event_base_free(base);
1021e985b929SDavid van Moolenbroek /* If we got here without asserting, we're fine. */
1022e985b929SDavid van Moolenbroek test_ok = 1;
1023e985b929SDavid van Moolenbroek cleanup_test();
1024e985b929SDavid van Moolenbroek }
1025e985b929SDavid van Moolenbroek
1026e985b929SDavid van Moolenbroek static void
test_signal_pipeloss(void)1027e985b929SDavid van Moolenbroek test_signal_pipeloss(void)
1028e985b929SDavid van Moolenbroek {
1029e985b929SDavid van Moolenbroek /* make sure that the base1 pipe is closed correctly. */
1030e985b929SDavid van Moolenbroek struct event_base *base1, *base2;
1031e985b929SDavid van Moolenbroek int pipe1;
1032e985b929SDavid van Moolenbroek test_ok = 0;
1033e985b929SDavid van Moolenbroek base1 = event_init();
1034e985b929SDavid van Moolenbroek pipe1 = base1->sig.ev_signal_pair[0];
1035e985b929SDavid van Moolenbroek base2 = event_init();
1036e985b929SDavid van Moolenbroek event_base_free(base2);
1037e985b929SDavid van Moolenbroek event_base_free(base1);
1038e985b929SDavid van Moolenbroek if (close(pipe1) != -1 || errno!=EBADF) {
1039e985b929SDavid van Moolenbroek /* fd must be closed, so second close gives -1, EBADF */
1040e985b929SDavid van Moolenbroek printf("signal pipe not closed. ");
1041e985b929SDavid van Moolenbroek test_ok = 0;
1042e985b929SDavid van Moolenbroek } else {
1043e985b929SDavid van Moolenbroek test_ok = 1;
1044e985b929SDavid van Moolenbroek }
1045e985b929SDavid van Moolenbroek cleanup_test();
1046e985b929SDavid van Moolenbroek }
1047e985b929SDavid van Moolenbroek
1048e985b929SDavid van Moolenbroek /*
1049e985b929SDavid van Moolenbroek * make two bases to catch signals, use both of them. this only works
1050e985b929SDavid van Moolenbroek * for event mechanisms that use our signal pipe trick. kqueue handles
1051e985b929SDavid van Moolenbroek * signals internally, and all interested kqueues get all the signals.
1052e985b929SDavid van Moolenbroek */
1053e985b929SDavid van Moolenbroek static void
test_signal_switchbase(void)1054e985b929SDavid van Moolenbroek test_signal_switchbase(void)
1055e985b929SDavid van Moolenbroek {
1056e985b929SDavid van Moolenbroek struct event ev1, ev2;
1057e985b929SDavid van Moolenbroek struct event_base *base1, *base2;
1058e985b929SDavid van Moolenbroek int is_kqueue;
1059e985b929SDavid van Moolenbroek test_ok = 0;
1060e985b929SDavid van Moolenbroek base1 = event_init();
1061e985b929SDavid van Moolenbroek base2 = event_init();
1062e985b929SDavid van Moolenbroek is_kqueue = !strcmp(event_get_method(),"kqueue");
1063e985b929SDavid van Moolenbroek evsignal_set(&ev1, SIGUSR1, signal_cb, &ev1);
1064e985b929SDavid van Moolenbroek evsignal_set(&ev2, SIGUSR1, signal_cb, &ev2);
1065e985b929SDavid van Moolenbroek if (event_base_set(base1, &ev1) ||
1066e985b929SDavid van Moolenbroek event_base_set(base2, &ev2) ||
1067e985b929SDavid van Moolenbroek event_add(&ev1, NULL) ||
1068e985b929SDavid van Moolenbroek event_add(&ev2, NULL)) {
1069e985b929SDavid van Moolenbroek fprintf(stderr, "%s: cannot set base, add\n", __func__);
1070e985b929SDavid van Moolenbroek exit(1);
1071e985b929SDavid van Moolenbroek }
1072e985b929SDavid van Moolenbroek
1073e985b929SDavid van Moolenbroek tt_ptr_op(event_get_base(&ev1), ==, base1);
1074e985b929SDavid van Moolenbroek tt_ptr_op(event_get_base(&ev2), ==, base2);
1075e985b929SDavid van Moolenbroek
1076e985b929SDavid van Moolenbroek test_ok = 0;
1077e985b929SDavid van Moolenbroek /* can handle signal before loop is called */
1078e985b929SDavid van Moolenbroek raise(SIGUSR1);
1079e985b929SDavid van Moolenbroek event_base_loop(base2, EVLOOP_NONBLOCK);
1080e985b929SDavid van Moolenbroek if (is_kqueue) {
1081e985b929SDavid van Moolenbroek if (!test_ok)
1082e985b929SDavid van Moolenbroek goto end;
1083e985b929SDavid van Moolenbroek test_ok = 0;
1084e985b929SDavid van Moolenbroek }
1085e985b929SDavid van Moolenbroek event_base_loop(base1, EVLOOP_NONBLOCK);
1086e985b929SDavid van Moolenbroek if (test_ok && !is_kqueue) {
1087e985b929SDavid van Moolenbroek test_ok = 0;
1088e985b929SDavid van Moolenbroek
1089e985b929SDavid van Moolenbroek /* set base1 to handle signals */
1090e985b929SDavid van Moolenbroek event_base_loop(base1, EVLOOP_NONBLOCK);
1091e985b929SDavid van Moolenbroek raise(SIGUSR1);
1092e985b929SDavid van Moolenbroek event_base_loop(base1, EVLOOP_NONBLOCK);
1093e985b929SDavid van Moolenbroek event_base_loop(base2, EVLOOP_NONBLOCK);
1094e985b929SDavid van Moolenbroek }
1095e985b929SDavid van Moolenbroek end:
1096e985b929SDavid van Moolenbroek event_base_free(base1);
1097e985b929SDavid van Moolenbroek event_base_free(base2);
1098e985b929SDavid van Moolenbroek cleanup_test();
1099e985b929SDavid van Moolenbroek }
1100e985b929SDavid van Moolenbroek
1101e985b929SDavid van Moolenbroek /*
1102e985b929SDavid van Moolenbroek * assert that a signal event removed from the event queue really is
1103e985b929SDavid van Moolenbroek * removed - with no possibility of it's parent handler being fired.
1104e985b929SDavid van Moolenbroek */
1105e985b929SDavid van Moolenbroek static void
test_signal_assert(void)1106e985b929SDavid van Moolenbroek test_signal_assert(void)
1107e985b929SDavid van Moolenbroek {
1108e985b929SDavid van Moolenbroek struct event ev;
1109e985b929SDavid van Moolenbroek struct event_base *base = event_init();
1110e985b929SDavid van Moolenbroek test_ok = 0;
1111e985b929SDavid van Moolenbroek /* use SIGCONT so we don't kill ourselves when we signal to nowhere */
1112e985b929SDavid van Moolenbroek evsignal_set(&ev, SIGCONT, signal_cb, &ev);
1113e985b929SDavid van Moolenbroek evsignal_add(&ev, NULL);
1114e985b929SDavid van Moolenbroek /*
1115e985b929SDavid van Moolenbroek * if evsignal_del() fails to reset the handler, it's current handler
1116e985b929SDavid van Moolenbroek * will still point to evsig_handler().
1117e985b929SDavid van Moolenbroek */
1118e985b929SDavid van Moolenbroek evsignal_del(&ev);
1119e985b929SDavid van Moolenbroek
1120e985b929SDavid van Moolenbroek raise(SIGCONT);
1121e985b929SDavid van Moolenbroek #if 0
1122e985b929SDavid van Moolenbroek /* only way to verify we were in evsig_handler() */
1123e985b929SDavid van Moolenbroek /* XXXX Now there's no longer a good way. */
1124e985b929SDavid van Moolenbroek if (base->sig.evsig_caught)
1125e985b929SDavid van Moolenbroek test_ok = 0;
1126e985b929SDavid van Moolenbroek else
1127e985b929SDavid van Moolenbroek test_ok = 1;
1128e985b929SDavid van Moolenbroek #else
1129e985b929SDavid van Moolenbroek test_ok = 1;
1130e985b929SDavid van Moolenbroek #endif
1131e985b929SDavid van Moolenbroek
1132e985b929SDavid van Moolenbroek event_base_free(base);
1133e985b929SDavid van Moolenbroek cleanup_test();
1134e985b929SDavid van Moolenbroek return;
1135e985b929SDavid van Moolenbroek }
1136e985b929SDavid van Moolenbroek
1137e985b929SDavid van Moolenbroek /*
1138e985b929SDavid van Moolenbroek * assert that we restore our previous signal handler properly.
1139e985b929SDavid van Moolenbroek */
1140e985b929SDavid van Moolenbroek static void
test_signal_restore(void)1141e985b929SDavid van Moolenbroek test_signal_restore(void)
1142e985b929SDavid van Moolenbroek {
1143e985b929SDavid van Moolenbroek struct event ev;
1144e985b929SDavid van Moolenbroek struct event_base *base = event_init();
1145e985b929SDavid van Moolenbroek #ifdef _EVENT_HAVE_SIGACTION
1146e985b929SDavid van Moolenbroek struct sigaction sa;
1147e985b929SDavid van Moolenbroek #endif
1148e985b929SDavid van Moolenbroek
1149e985b929SDavid van Moolenbroek test_ok = 0;
1150e985b929SDavid van Moolenbroek #ifdef _EVENT_HAVE_SIGACTION
1151e985b929SDavid van Moolenbroek sa.sa_handler = signal_cb_sa;
1152e985b929SDavid van Moolenbroek sa.sa_flags = 0x0;
1153e985b929SDavid van Moolenbroek sigemptyset(&sa.sa_mask);
1154e985b929SDavid van Moolenbroek if (sigaction(SIGUSR1, &sa, NULL) == -1)
1155e985b929SDavid van Moolenbroek goto out;
1156e985b929SDavid van Moolenbroek #else
1157e985b929SDavid van Moolenbroek if (signal(SIGUSR1, signal_cb_sa) == SIG_ERR)
1158e985b929SDavid van Moolenbroek goto out;
1159e985b929SDavid van Moolenbroek #endif
1160e985b929SDavid van Moolenbroek evsignal_set(&ev, SIGUSR1, signal_cb, &ev);
1161e985b929SDavid van Moolenbroek evsignal_add(&ev, NULL);
1162e985b929SDavid van Moolenbroek evsignal_del(&ev);
1163e985b929SDavid van Moolenbroek
1164e985b929SDavid van Moolenbroek raise(SIGUSR1);
1165e985b929SDavid van Moolenbroek /* 1 == signal_cb, 2 == signal_cb_sa, we want our previous handler */
1166e985b929SDavid van Moolenbroek if (test_ok != 2)
1167e985b929SDavid van Moolenbroek test_ok = 0;
1168e985b929SDavid van Moolenbroek out:
1169e985b929SDavid van Moolenbroek event_base_free(base);
1170e985b929SDavid van Moolenbroek cleanup_test();
1171e985b929SDavid van Moolenbroek return;
1172e985b929SDavid van Moolenbroek }
1173e985b929SDavid van Moolenbroek
1174e985b929SDavid van Moolenbroek static void
signal_cb_swp(int sig,short event,void * arg)1175e985b929SDavid van Moolenbroek signal_cb_swp(int sig, short event, void *arg)
1176e985b929SDavid van Moolenbroek {
1177e985b929SDavid van Moolenbroek called++;
1178e985b929SDavid van Moolenbroek if (called < 5)
1179e985b929SDavid van Moolenbroek raise(sig);
1180e985b929SDavid van Moolenbroek else
1181e985b929SDavid van Moolenbroek event_loopexit(NULL);
1182e985b929SDavid van Moolenbroek }
1183e985b929SDavid van Moolenbroek static void
timeout_cb_swp(evutil_socket_t fd,short event,void * arg)1184e985b929SDavid van Moolenbroek timeout_cb_swp(evutil_socket_t fd, short event, void *arg)
1185e985b929SDavid van Moolenbroek {
1186e985b929SDavid van Moolenbroek if (called == -1) {
1187e985b929SDavid van Moolenbroek struct timeval tv = {5, 0};
1188e985b929SDavid van Moolenbroek
1189e985b929SDavid van Moolenbroek called = 0;
1190e985b929SDavid van Moolenbroek evtimer_add((struct event *)arg, &tv);
1191e985b929SDavid van Moolenbroek raise(SIGUSR1);
1192e985b929SDavid van Moolenbroek return;
1193e985b929SDavid van Moolenbroek }
1194e985b929SDavid van Moolenbroek test_ok = 0;
1195e985b929SDavid van Moolenbroek event_loopexit(NULL);
1196e985b929SDavid van Moolenbroek }
1197e985b929SDavid van Moolenbroek
1198e985b929SDavid van Moolenbroek static void
test_signal_while_processing(void)1199e985b929SDavid van Moolenbroek test_signal_while_processing(void)
1200e985b929SDavid van Moolenbroek {
1201e985b929SDavid van Moolenbroek struct event_base *base = event_init();
1202e985b929SDavid van Moolenbroek struct event ev, ev_timer;
1203e985b929SDavid van Moolenbroek struct timeval tv = {0, 0};
1204e985b929SDavid van Moolenbroek
1205e985b929SDavid van Moolenbroek setup_test("Receiving a signal while processing other signal: ");
1206e985b929SDavid van Moolenbroek
1207e985b929SDavid van Moolenbroek called = -1;
1208e985b929SDavid van Moolenbroek test_ok = 1;
1209e985b929SDavid van Moolenbroek signal_set(&ev, SIGUSR1, signal_cb_swp, NULL);
1210e985b929SDavid van Moolenbroek signal_add(&ev, NULL);
1211e985b929SDavid van Moolenbroek evtimer_set(&ev_timer, timeout_cb_swp, &ev_timer);
1212e985b929SDavid van Moolenbroek evtimer_add(&ev_timer, &tv);
1213e985b929SDavid van Moolenbroek event_dispatch();
1214e985b929SDavid van Moolenbroek
1215e985b929SDavid van Moolenbroek event_base_free(base);
1216e985b929SDavid van Moolenbroek cleanup_test();
1217e985b929SDavid van Moolenbroek return;
1218e985b929SDavid van Moolenbroek }
1219e985b929SDavid van Moolenbroek #endif
1220e985b929SDavid van Moolenbroek
1221e985b929SDavid van Moolenbroek static void
test_free_active_base(void * ptr)1222e985b929SDavid van Moolenbroek test_free_active_base(void *ptr)
1223e985b929SDavid van Moolenbroek {
1224e985b929SDavid van Moolenbroek struct basic_test_data *data = ptr;
1225e985b929SDavid van Moolenbroek struct event_base *base1;
1226e985b929SDavid van Moolenbroek struct event ev1;
1227e985b929SDavid van Moolenbroek
1228e985b929SDavid van Moolenbroek base1 = event_init();
1229e985b929SDavid van Moolenbroek if (base1) {
1230e985b929SDavid van Moolenbroek event_assign(&ev1, base1, data->pair[1], EV_READ,
1231e985b929SDavid van Moolenbroek dummy_read_cb, NULL);
1232e985b929SDavid van Moolenbroek event_add(&ev1, NULL);
1233e985b929SDavid van Moolenbroek event_base_free(base1); /* should not crash */
1234e985b929SDavid van Moolenbroek } else {
1235e985b929SDavid van Moolenbroek tt_fail_msg("failed to create event_base for test");
1236e985b929SDavid van Moolenbroek }
1237e985b929SDavid van Moolenbroek
1238e985b929SDavid van Moolenbroek base1 = event_init();
1239e985b929SDavid van Moolenbroek tt_assert(base1);
1240e985b929SDavid van Moolenbroek event_assign(&ev1, base1, 0, 0, dummy_read_cb, NULL);
1241e985b929SDavid van Moolenbroek event_active(&ev1, EV_READ, 1);
1242e985b929SDavid van Moolenbroek event_base_free(base1);
1243e985b929SDavid van Moolenbroek end:
1244e985b929SDavid van Moolenbroek ;
1245e985b929SDavid van Moolenbroek }
1246e985b929SDavid van Moolenbroek
1247e985b929SDavid van Moolenbroek static void
test_manipulate_active_events(void * ptr)1248e985b929SDavid van Moolenbroek test_manipulate_active_events(void *ptr)
1249e985b929SDavid van Moolenbroek {
1250e985b929SDavid van Moolenbroek struct basic_test_data *data = ptr;
1251e985b929SDavid van Moolenbroek struct event_base *base = data->base;
1252e985b929SDavid van Moolenbroek struct event ev1;
1253e985b929SDavid van Moolenbroek
1254e985b929SDavid van Moolenbroek event_assign(&ev1, base, -1, EV_TIMEOUT, dummy_read_cb, NULL);
1255e985b929SDavid van Moolenbroek
1256e985b929SDavid van Moolenbroek /* Make sure an active event is pending. */
1257e985b929SDavid van Moolenbroek event_active(&ev1, EV_READ, 1);
1258e985b929SDavid van Moolenbroek tt_int_op(event_pending(&ev1, EV_READ|EV_TIMEOUT|EV_WRITE, NULL),
1259e985b929SDavid van Moolenbroek ==, EV_READ);
1260e985b929SDavid van Moolenbroek
1261e985b929SDavid van Moolenbroek /* Make sure that activating an event twice works. */
1262e985b929SDavid van Moolenbroek event_active(&ev1, EV_WRITE, 1);
1263e985b929SDavid van Moolenbroek tt_int_op(event_pending(&ev1, EV_READ|EV_TIMEOUT|EV_WRITE, NULL),
1264e985b929SDavid van Moolenbroek ==, EV_READ|EV_WRITE);
1265e985b929SDavid van Moolenbroek
1266e985b929SDavid van Moolenbroek end:
1267e985b929SDavid van Moolenbroek event_del(&ev1);
1268e985b929SDavid van Moolenbroek }
1269e985b929SDavid van Moolenbroek
1270e985b929SDavid van Moolenbroek static void
test_bad_assign(void * ptr)1271e985b929SDavid van Moolenbroek test_bad_assign(void *ptr)
1272e985b929SDavid van Moolenbroek {
1273e985b929SDavid van Moolenbroek struct event ev;
1274e985b929SDavid van Moolenbroek int r;
1275e985b929SDavid van Moolenbroek /* READ|SIGNAL is not allowed */
1276e985b929SDavid van Moolenbroek r = event_assign(&ev, NULL, -1, EV_SIGNAL|EV_READ, dummy_read_cb, NULL);
1277e985b929SDavid van Moolenbroek tt_int_op(r,==,-1);
1278e985b929SDavid van Moolenbroek
1279e985b929SDavid van Moolenbroek end:
1280e985b929SDavid van Moolenbroek ;
1281e985b929SDavid van Moolenbroek }
1282e985b929SDavid van Moolenbroek
1283e985b929SDavid van Moolenbroek static int reentrant_cb_run = 0;
1284e985b929SDavid van Moolenbroek
1285e985b929SDavid van Moolenbroek static void
bad_reentrant_run_loop_cb(evutil_socket_t fd,short what,void * ptr)1286e985b929SDavid van Moolenbroek bad_reentrant_run_loop_cb(evutil_socket_t fd, short what, void *ptr)
1287e985b929SDavid van Moolenbroek {
1288e985b929SDavid van Moolenbroek struct event_base *base = ptr;
1289e985b929SDavid van Moolenbroek int r;
1290e985b929SDavid van Moolenbroek reentrant_cb_run = 1;
1291e985b929SDavid van Moolenbroek /* This reentrant call to event_base_loop should be detected and
1292e985b929SDavid van Moolenbroek * should fail */
1293e985b929SDavid van Moolenbroek r = event_base_loop(base, 0);
1294e985b929SDavid van Moolenbroek tt_int_op(r, ==, -1);
1295e985b929SDavid van Moolenbroek end:
1296e985b929SDavid van Moolenbroek ;
1297e985b929SDavid van Moolenbroek }
1298e985b929SDavid van Moolenbroek
1299e985b929SDavid van Moolenbroek static void
test_bad_reentrant(void * ptr)1300e985b929SDavid van Moolenbroek test_bad_reentrant(void *ptr)
1301e985b929SDavid van Moolenbroek {
1302e985b929SDavid van Moolenbroek struct basic_test_data *data = ptr;
1303e985b929SDavid van Moolenbroek struct event_base *base = data->base;
1304e985b929SDavid van Moolenbroek struct event ev;
1305e985b929SDavid van Moolenbroek int r;
1306e985b929SDavid van Moolenbroek event_assign(&ev, base, -1,
1307e985b929SDavid van Moolenbroek 0, bad_reentrant_run_loop_cb, base);
1308e985b929SDavid van Moolenbroek
1309e985b929SDavid van Moolenbroek event_active(&ev, EV_WRITE, 1);
1310e985b929SDavid van Moolenbroek r = event_base_loop(base, 0);
1311e985b929SDavid van Moolenbroek tt_int_op(r, ==, 1);
1312e985b929SDavid van Moolenbroek tt_int_op(reentrant_cb_run, ==, 1);
1313e985b929SDavid van Moolenbroek end:
1314e985b929SDavid van Moolenbroek ;
1315e985b929SDavid van Moolenbroek }
1316e985b929SDavid van Moolenbroek
1317e985b929SDavid van Moolenbroek static void
test_event_base_new(void * ptr)1318e985b929SDavid van Moolenbroek test_event_base_new(void *ptr)
1319e985b929SDavid van Moolenbroek {
1320e985b929SDavid van Moolenbroek struct basic_test_data *data = ptr;
1321e985b929SDavid van Moolenbroek struct event_base *base = 0;
1322e985b929SDavid van Moolenbroek struct event ev1;
1323e985b929SDavid van Moolenbroek struct basic_cb_args args;
1324e985b929SDavid van Moolenbroek
1325e985b929SDavid van Moolenbroek int towrite = (int)strlen(TEST1)+1;
1326e985b929SDavid van Moolenbroek int len = write(data->pair[0], TEST1, towrite);
1327e985b929SDavid van Moolenbroek
1328e985b929SDavid van Moolenbroek if (len < 0)
1329e985b929SDavid van Moolenbroek tt_abort_perror("initial write");
1330e985b929SDavid van Moolenbroek else if (len != towrite)
1331e985b929SDavid van Moolenbroek tt_abort_printf(("initial write fell short (%d of %d bytes)",
1332e985b929SDavid van Moolenbroek len, towrite));
1333e985b929SDavid van Moolenbroek
1334e985b929SDavid van Moolenbroek if (shutdown(data->pair[0], SHUT_WR))
1335e985b929SDavid van Moolenbroek tt_abort_perror("initial write shutdown");
1336e985b929SDavid van Moolenbroek
1337e985b929SDavid van Moolenbroek base = event_base_new();
1338e985b929SDavid van Moolenbroek if (!base)
1339e985b929SDavid van Moolenbroek tt_abort_msg("failed to create event base");
1340e985b929SDavid van Moolenbroek
1341e985b929SDavid van Moolenbroek args.eb = base;
1342e985b929SDavid van Moolenbroek args.ev = &ev1;
1343e985b929SDavid van Moolenbroek args.callcount = 0;
1344e985b929SDavid van Moolenbroek event_assign(&ev1, base, data->pair[1],
1345e985b929SDavid van Moolenbroek EV_READ|EV_PERSIST, basic_read_cb, &args);
1346e985b929SDavid van Moolenbroek
1347e985b929SDavid van Moolenbroek if (event_add(&ev1, NULL))
1348e985b929SDavid van Moolenbroek tt_abort_perror("initial event_add");
1349e985b929SDavid van Moolenbroek
1350e985b929SDavid van Moolenbroek if (event_base_loop(base, 0))
1351e985b929SDavid van Moolenbroek tt_abort_msg("unsuccessful exit from event loop");
1352e985b929SDavid van Moolenbroek
1353e985b929SDavid van Moolenbroek end:
1354e985b929SDavid van Moolenbroek if (base)
1355e985b929SDavid van Moolenbroek event_base_free(base);
1356e985b929SDavid van Moolenbroek }
1357e985b929SDavid van Moolenbroek
1358e985b929SDavid van Moolenbroek static void
test_loopexit(void)1359e985b929SDavid van Moolenbroek test_loopexit(void)
1360e985b929SDavid van Moolenbroek {
1361e985b929SDavid van Moolenbroek struct timeval tv, tv_start, tv_end;
1362e985b929SDavid van Moolenbroek struct event ev;
1363e985b929SDavid van Moolenbroek
1364e985b929SDavid van Moolenbroek setup_test("Loop exit: ");
1365e985b929SDavid van Moolenbroek
1366e985b929SDavid van Moolenbroek tv.tv_usec = 0;
1367e985b929SDavid van Moolenbroek tv.tv_sec = 60*60*24;
1368e985b929SDavid van Moolenbroek evtimer_set(&ev, timeout_cb, NULL);
1369e985b929SDavid van Moolenbroek evtimer_add(&ev, &tv);
1370e985b929SDavid van Moolenbroek
1371e985b929SDavid van Moolenbroek tv.tv_usec = 0;
1372*0a6a1f1dSLionel Sambuc tv.tv_sec = 1;
1373e985b929SDavid van Moolenbroek event_loopexit(&tv);
1374e985b929SDavid van Moolenbroek
1375e985b929SDavid van Moolenbroek evutil_gettimeofday(&tv_start, NULL);
1376e985b929SDavid van Moolenbroek event_dispatch();
1377e985b929SDavid van Moolenbroek evutil_gettimeofday(&tv_end, NULL);
1378e985b929SDavid van Moolenbroek evutil_timersub(&tv_end, &tv_start, &tv_end);
1379e985b929SDavid van Moolenbroek
1380e985b929SDavid van Moolenbroek evtimer_del(&ev);
1381e985b929SDavid van Moolenbroek
1382e985b929SDavid van Moolenbroek tt_assert(event_base_got_exit(global_base));
1383e985b929SDavid van Moolenbroek tt_assert(!event_base_got_break(global_base));
1384e985b929SDavid van Moolenbroek
1385e985b929SDavid van Moolenbroek if (tv.tv_sec < 2)
1386e985b929SDavid van Moolenbroek test_ok = 1;
1387e985b929SDavid van Moolenbroek
1388e985b929SDavid van Moolenbroek end:
1389e985b929SDavid van Moolenbroek cleanup_test();
1390e985b929SDavid van Moolenbroek }
1391e985b929SDavid van Moolenbroek
1392e985b929SDavid van Moolenbroek static void
test_loopexit_multiple(void)1393e985b929SDavid van Moolenbroek test_loopexit_multiple(void)
1394e985b929SDavid van Moolenbroek {
1395e985b929SDavid van Moolenbroek struct timeval tv;
1396e985b929SDavid van Moolenbroek struct event_base *base;
1397e985b929SDavid van Moolenbroek
1398e985b929SDavid van Moolenbroek setup_test("Loop Multiple exit: ");
1399e985b929SDavid van Moolenbroek
1400e985b929SDavid van Moolenbroek base = event_base_new();
1401e985b929SDavid van Moolenbroek
1402e985b929SDavid van Moolenbroek tv.tv_usec = 0;
1403e985b929SDavid van Moolenbroek tv.tv_sec = 1;
1404e985b929SDavid van Moolenbroek event_base_loopexit(base, &tv);
1405e985b929SDavid van Moolenbroek
1406e985b929SDavid van Moolenbroek tv.tv_usec = 0;
1407e985b929SDavid van Moolenbroek tv.tv_sec = 2;
1408e985b929SDavid van Moolenbroek event_base_loopexit(base, &tv);
1409e985b929SDavid van Moolenbroek
1410e985b929SDavid van Moolenbroek event_base_dispatch(base);
1411e985b929SDavid van Moolenbroek
1412e985b929SDavid van Moolenbroek tt_assert(event_base_got_exit(base));
1413e985b929SDavid van Moolenbroek tt_assert(!event_base_got_break(base));
1414e985b929SDavid van Moolenbroek
1415e985b929SDavid van Moolenbroek event_base_free(base);
1416e985b929SDavid van Moolenbroek
1417e985b929SDavid van Moolenbroek test_ok = 1;
1418e985b929SDavid van Moolenbroek
1419e985b929SDavid van Moolenbroek end:
1420e985b929SDavid van Moolenbroek cleanup_test();
1421e985b929SDavid van Moolenbroek }
1422e985b929SDavid van Moolenbroek
1423e985b929SDavid van Moolenbroek static void
break_cb(evutil_socket_t fd,short events,void * arg)1424e985b929SDavid van Moolenbroek break_cb(evutil_socket_t fd, short events, void *arg)
1425e985b929SDavid van Moolenbroek {
1426e985b929SDavid van Moolenbroek test_ok = 1;
1427e985b929SDavid van Moolenbroek event_loopbreak();
1428e985b929SDavid van Moolenbroek }
1429e985b929SDavid van Moolenbroek
1430e985b929SDavid van Moolenbroek static void
fail_cb(evutil_socket_t fd,short events,void * arg)1431e985b929SDavid van Moolenbroek fail_cb(evutil_socket_t fd, short events, void *arg)
1432e985b929SDavid van Moolenbroek {
1433e985b929SDavid van Moolenbroek test_ok = 0;
1434e985b929SDavid van Moolenbroek }
1435e985b929SDavid van Moolenbroek
1436e985b929SDavid van Moolenbroek static void
test_loopbreak(void)1437e985b929SDavid van Moolenbroek test_loopbreak(void)
1438e985b929SDavid van Moolenbroek {
1439e985b929SDavid van Moolenbroek struct event ev1, ev2;
1440e985b929SDavid van Moolenbroek struct timeval tv;
1441e985b929SDavid van Moolenbroek
1442e985b929SDavid van Moolenbroek setup_test("Loop break: ");
1443e985b929SDavid van Moolenbroek
1444e985b929SDavid van Moolenbroek tv.tv_sec = 0;
1445e985b929SDavid van Moolenbroek tv.tv_usec = 0;
1446e985b929SDavid van Moolenbroek evtimer_set(&ev1, break_cb, NULL);
1447e985b929SDavid van Moolenbroek evtimer_add(&ev1, &tv);
1448e985b929SDavid van Moolenbroek evtimer_set(&ev2, fail_cb, NULL);
1449e985b929SDavid van Moolenbroek evtimer_add(&ev2, &tv);
1450e985b929SDavid van Moolenbroek
1451e985b929SDavid van Moolenbroek event_dispatch();
1452e985b929SDavid van Moolenbroek
1453e985b929SDavid van Moolenbroek tt_assert(!event_base_got_exit(global_base));
1454e985b929SDavid van Moolenbroek tt_assert(event_base_got_break(global_base));
1455e985b929SDavid van Moolenbroek
1456e985b929SDavid van Moolenbroek evtimer_del(&ev1);
1457e985b929SDavid van Moolenbroek evtimer_del(&ev2);
1458e985b929SDavid van Moolenbroek
1459e985b929SDavid van Moolenbroek end:
1460e985b929SDavid van Moolenbroek cleanup_test();
1461e985b929SDavid van Moolenbroek }
1462e985b929SDavid van Moolenbroek
1463e985b929SDavid van Moolenbroek static struct event *readd_test_event_last_added = NULL;
1464e985b929SDavid van Moolenbroek static void
re_add_read_cb(evutil_socket_t fd,short event,void * arg)1465e985b929SDavid van Moolenbroek re_add_read_cb(evutil_socket_t fd, short event, void *arg)
1466e985b929SDavid van Moolenbroek {
1467e985b929SDavid van Moolenbroek char buf[256];
1468e985b929SDavid van Moolenbroek struct event *ev_other = arg;
1469e985b929SDavid van Moolenbroek readd_test_event_last_added = ev_other;
1470e985b929SDavid van Moolenbroek
1471e985b929SDavid van Moolenbroek if (read(fd, buf, sizeof(buf)) < 0) {
1472e985b929SDavid van Moolenbroek tt_fail_perror("read");
1473e985b929SDavid van Moolenbroek }
1474e985b929SDavid van Moolenbroek
1475e985b929SDavid van Moolenbroek event_add(ev_other, NULL);
1476e985b929SDavid van Moolenbroek ++test_ok;
1477e985b929SDavid van Moolenbroek }
1478e985b929SDavid van Moolenbroek
1479e985b929SDavid van Moolenbroek static void
test_nonpersist_readd(void)1480e985b929SDavid van Moolenbroek test_nonpersist_readd(void)
1481e985b929SDavid van Moolenbroek {
1482e985b929SDavid van Moolenbroek struct event ev1, ev2;
1483e985b929SDavid van Moolenbroek
1484e985b929SDavid van Moolenbroek setup_test("Re-add nonpersistent events: ");
1485e985b929SDavid van Moolenbroek event_set(&ev1, pair[0], EV_READ, re_add_read_cb, &ev2);
1486e985b929SDavid van Moolenbroek event_set(&ev2, pair[1], EV_READ, re_add_read_cb, &ev1);
1487e985b929SDavid van Moolenbroek
1488e985b929SDavid van Moolenbroek if (write(pair[0], "Hello", 5) < 0) {
1489e985b929SDavid van Moolenbroek tt_fail_perror("write(pair[0])");
1490e985b929SDavid van Moolenbroek }
1491e985b929SDavid van Moolenbroek
1492e985b929SDavid van Moolenbroek if (write(pair[1], "Hello", 5) < 0) {
1493e985b929SDavid van Moolenbroek tt_fail_perror("write(pair[1])\n");
1494e985b929SDavid van Moolenbroek }
1495e985b929SDavid van Moolenbroek
1496e985b929SDavid van Moolenbroek if (event_add(&ev1, NULL) == -1 ||
1497e985b929SDavid van Moolenbroek event_add(&ev2, NULL) == -1) {
1498e985b929SDavid van Moolenbroek test_ok = 0;
1499e985b929SDavid van Moolenbroek }
1500e985b929SDavid van Moolenbroek if (test_ok != 0)
1501e985b929SDavid van Moolenbroek exit(1);
1502e985b929SDavid van Moolenbroek event_loop(EVLOOP_ONCE);
1503e985b929SDavid van Moolenbroek if (test_ok != 2)
1504e985b929SDavid van Moolenbroek exit(1);
1505e985b929SDavid van Moolenbroek /* At this point, we executed both callbacks. Whichever one got
1506e985b929SDavid van Moolenbroek * called first added the second, but the second then immediately got
1507e985b929SDavid van Moolenbroek * deleted before its callback was called. At this point, though, it
1508e985b929SDavid van Moolenbroek * re-added the first.
1509e985b929SDavid van Moolenbroek */
1510e985b929SDavid van Moolenbroek if (!readd_test_event_last_added) {
1511e985b929SDavid van Moolenbroek test_ok = 0;
1512e985b929SDavid van Moolenbroek } else if (readd_test_event_last_added == &ev1) {
1513e985b929SDavid van Moolenbroek if (!event_pending(&ev1, EV_READ, NULL) ||
1514e985b929SDavid van Moolenbroek event_pending(&ev2, EV_READ, NULL))
1515e985b929SDavid van Moolenbroek test_ok = 0;
1516e985b929SDavid van Moolenbroek } else {
1517e985b929SDavid van Moolenbroek if (event_pending(&ev1, EV_READ, NULL) ||
1518e985b929SDavid van Moolenbroek !event_pending(&ev2, EV_READ, NULL))
1519e985b929SDavid van Moolenbroek test_ok = 0;
1520e985b929SDavid van Moolenbroek }
1521e985b929SDavid van Moolenbroek
1522e985b929SDavid van Moolenbroek event_del(&ev1);
1523e985b929SDavid van Moolenbroek event_del(&ev2);
1524e985b929SDavid van Moolenbroek
1525e985b929SDavid van Moolenbroek cleanup_test();
1526e985b929SDavid van Moolenbroek }
1527e985b929SDavid van Moolenbroek
1528e985b929SDavid van Moolenbroek struct test_pri_event {
1529e985b929SDavid van Moolenbroek struct event ev;
1530e985b929SDavid van Moolenbroek int count;
1531e985b929SDavid van Moolenbroek };
1532e985b929SDavid van Moolenbroek
1533e985b929SDavid van Moolenbroek static void
test_priorities_cb(evutil_socket_t fd,short what,void * arg)1534e985b929SDavid van Moolenbroek test_priorities_cb(evutil_socket_t fd, short what, void *arg)
1535e985b929SDavid van Moolenbroek {
1536e985b929SDavid van Moolenbroek struct test_pri_event *pri = arg;
1537e985b929SDavid van Moolenbroek struct timeval tv;
1538e985b929SDavid van Moolenbroek
1539e985b929SDavid van Moolenbroek if (pri->count == 3) {
1540e985b929SDavid van Moolenbroek event_loopexit(NULL);
1541e985b929SDavid van Moolenbroek return;
1542e985b929SDavid van Moolenbroek }
1543e985b929SDavid van Moolenbroek
1544e985b929SDavid van Moolenbroek pri->count++;
1545e985b929SDavid van Moolenbroek
1546e985b929SDavid van Moolenbroek evutil_timerclear(&tv);
1547e985b929SDavid van Moolenbroek event_add(&pri->ev, &tv);
1548e985b929SDavid van Moolenbroek }
1549e985b929SDavid van Moolenbroek
1550e985b929SDavid van Moolenbroek static void
test_priorities_impl(int npriorities)1551e985b929SDavid van Moolenbroek test_priorities_impl(int npriorities)
1552e985b929SDavid van Moolenbroek {
1553e985b929SDavid van Moolenbroek struct test_pri_event one, two;
1554e985b929SDavid van Moolenbroek struct timeval tv;
1555e985b929SDavid van Moolenbroek
1556e985b929SDavid van Moolenbroek TT_BLATHER(("Testing Priorities %d: ", npriorities));
1557e985b929SDavid van Moolenbroek
1558e985b929SDavid van Moolenbroek event_base_priority_init(global_base, npriorities);
1559e985b929SDavid van Moolenbroek
1560e985b929SDavid van Moolenbroek memset(&one, 0, sizeof(one));
1561e985b929SDavid van Moolenbroek memset(&two, 0, sizeof(two));
1562e985b929SDavid van Moolenbroek
1563e985b929SDavid van Moolenbroek timeout_set(&one.ev, test_priorities_cb, &one);
1564e985b929SDavid van Moolenbroek if (event_priority_set(&one.ev, 0) == -1) {
1565e985b929SDavid van Moolenbroek fprintf(stderr, "%s: failed to set priority", __func__);
1566e985b929SDavid van Moolenbroek exit(1);
1567e985b929SDavid van Moolenbroek }
1568e985b929SDavid van Moolenbroek
1569e985b929SDavid van Moolenbroek timeout_set(&two.ev, test_priorities_cb, &two);
1570e985b929SDavid van Moolenbroek if (event_priority_set(&two.ev, npriorities - 1) == -1) {
1571e985b929SDavid van Moolenbroek fprintf(stderr, "%s: failed to set priority", __func__);
1572e985b929SDavid van Moolenbroek exit(1);
1573e985b929SDavid van Moolenbroek }
1574e985b929SDavid van Moolenbroek
1575e985b929SDavid van Moolenbroek evutil_timerclear(&tv);
1576e985b929SDavid van Moolenbroek
1577e985b929SDavid van Moolenbroek if (event_add(&one.ev, &tv) == -1)
1578e985b929SDavid van Moolenbroek exit(1);
1579e985b929SDavid van Moolenbroek if (event_add(&two.ev, &tv) == -1)
1580e985b929SDavid van Moolenbroek exit(1);
1581e985b929SDavid van Moolenbroek
1582e985b929SDavid van Moolenbroek event_dispatch();
1583e985b929SDavid van Moolenbroek
1584e985b929SDavid van Moolenbroek event_del(&one.ev);
1585e985b929SDavid van Moolenbroek event_del(&two.ev);
1586e985b929SDavid van Moolenbroek
1587e985b929SDavid van Moolenbroek if (npriorities == 1) {
1588e985b929SDavid van Moolenbroek if (one.count == 3 && two.count == 3)
1589e985b929SDavid van Moolenbroek test_ok = 1;
1590e985b929SDavid van Moolenbroek } else if (npriorities == 2) {
1591e985b929SDavid van Moolenbroek /* Two is called once because event_loopexit is priority 1 */
1592e985b929SDavid van Moolenbroek if (one.count == 3 && two.count == 1)
1593e985b929SDavid van Moolenbroek test_ok = 1;
1594e985b929SDavid van Moolenbroek } else {
1595e985b929SDavid van Moolenbroek if (one.count == 3 && two.count == 0)
1596e985b929SDavid van Moolenbroek test_ok = 1;
1597e985b929SDavid van Moolenbroek }
1598e985b929SDavid van Moolenbroek }
1599e985b929SDavid van Moolenbroek
1600e985b929SDavid van Moolenbroek static void
test_priorities(void)1601e985b929SDavid van Moolenbroek test_priorities(void)
1602e985b929SDavid van Moolenbroek {
1603e985b929SDavid van Moolenbroek test_priorities_impl(1);
1604e985b929SDavid van Moolenbroek if (test_ok)
1605e985b929SDavid van Moolenbroek test_priorities_impl(2);
1606e985b929SDavid van Moolenbroek if (test_ok)
1607e985b929SDavid van Moolenbroek test_priorities_impl(3);
1608e985b929SDavid van Moolenbroek }
1609e985b929SDavid van Moolenbroek
1610e985b929SDavid van Moolenbroek /* priority-active-inversion: activate a higher-priority event, and make sure
1611e985b929SDavid van Moolenbroek * it keeps us from running a lower-priority event first. */
1612e985b929SDavid van Moolenbroek static int n_pai_calls = 0;
1613e985b929SDavid van Moolenbroek static struct event pai_events[3];
1614e985b929SDavid van Moolenbroek
1615e985b929SDavid van Moolenbroek static void
prio_active_inversion_cb(evutil_socket_t fd,short what,void * arg)1616e985b929SDavid van Moolenbroek prio_active_inversion_cb(evutil_socket_t fd, short what, void *arg)
1617e985b929SDavid van Moolenbroek {
1618e985b929SDavid van Moolenbroek int *call_order = arg;
1619e985b929SDavid van Moolenbroek *call_order = n_pai_calls++;
1620e985b929SDavid van Moolenbroek if (n_pai_calls == 1) {
1621e985b929SDavid van Moolenbroek /* This should activate later, even though it shares a
1622e985b929SDavid van Moolenbroek priority with us. */
1623e985b929SDavid van Moolenbroek event_active(&pai_events[1], EV_READ, 1);
1624e985b929SDavid van Moolenbroek /* This should activate next, since its priority is higher,
1625e985b929SDavid van Moolenbroek even though we activated it second. */
1626e985b929SDavid van Moolenbroek event_active(&pai_events[2], EV_TIMEOUT, 1);
1627e985b929SDavid van Moolenbroek }
1628e985b929SDavid van Moolenbroek }
1629e985b929SDavid van Moolenbroek
1630e985b929SDavid van Moolenbroek static void
test_priority_active_inversion(void * data_)1631e985b929SDavid van Moolenbroek test_priority_active_inversion(void *data_)
1632e985b929SDavid van Moolenbroek {
1633e985b929SDavid van Moolenbroek struct basic_test_data *data = data_;
1634e985b929SDavid van Moolenbroek struct event_base *base = data->base;
1635e985b929SDavid van Moolenbroek int call_order[3];
1636e985b929SDavid van Moolenbroek int i;
1637e985b929SDavid van Moolenbroek tt_int_op(event_base_priority_init(base, 8), ==, 0);
1638e985b929SDavid van Moolenbroek
1639e985b929SDavid van Moolenbroek n_pai_calls = 0;
1640e985b929SDavid van Moolenbroek memset(call_order, 0, sizeof(call_order));
1641e985b929SDavid van Moolenbroek
1642e985b929SDavid van Moolenbroek for (i=0;i<3;++i) {
1643e985b929SDavid van Moolenbroek event_assign(&pai_events[i], data->base, -1, 0,
1644e985b929SDavid van Moolenbroek prio_active_inversion_cb, &call_order[i]);
1645e985b929SDavid van Moolenbroek }
1646e985b929SDavid van Moolenbroek
1647e985b929SDavid van Moolenbroek event_priority_set(&pai_events[0], 4);
1648e985b929SDavid van Moolenbroek event_priority_set(&pai_events[1], 4);
1649e985b929SDavid van Moolenbroek event_priority_set(&pai_events[2], 0);
1650e985b929SDavid van Moolenbroek
1651e985b929SDavid van Moolenbroek event_active(&pai_events[0], EV_WRITE, 1);
1652e985b929SDavid van Moolenbroek
1653e985b929SDavid van Moolenbroek event_base_dispatch(base);
1654e985b929SDavid van Moolenbroek tt_int_op(n_pai_calls, ==, 3);
1655e985b929SDavid van Moolenbroek tt_int_op(call_order[0], ==, 0);
1656e985b929SDavid van Moolenbroek tt_int_op(call_order[1], ==, 2);
1657e985b929SDavid van Moolenbroek tt_int_op(call_order[2], ==, 1);
1658e985b929SDavid van Moolenbroek end:
1659e985b929SDavid van Moolenbroek ;
1660e985b929SDavid van Moolenbroek }
1661e985b929SDavid van Moolenbroek
1662e985b929SDavid van Moolenbroek
1663e985b929SDavid van Moolenbroek static void
test_multiple_cb(evutil_socket_t fd,short event,void * arg)1664e985b929SDavid van Moolenbroek test_multiple_cb(evutil_socket_t fd, short event, void *arg)
1665e985b929SDavid van Moolenbroek {
1666e985b929SDavid van Moolenbroek if (event & EV_READ)
1667e985b929SDavid van Moolenbroek test_ok |= 1;
1668e985b929SDavid van Moolenbroek else if (event & EV_WRITE)
1669e985b929SDavid van Moolenbroek test_ok |= 2;
1670e985b929SDavid van Moolenbroek }
1671e985b929SDavid van Moolenbroek
1672e985b929SDavid van Moolenbroek static void
test_multiple_events_for_same_fd(void)1673e985b929SDavid van Moolenbroek test_multiple_events_for_same_fd(void)
1674e985b929SDavid van Moolenbroek {
1675e985b929SDavid van Moolenbroek struct event e1, e2;
1676e985b929SDavid van Moolenbroek
1677e985b929SDavid van Moolenbroek setup_test("Multiple events for same fd: ");
1678e985b929SDavid van Moolenbroek
1679e985b929SDavid van Moolenbroek event_set(&e1, pair[0], EV_READ, test_multiple_cb, NULL);
1680e985b929SDavid van Moolenbroek event_add(&e1, NULL);
1681e985b929SDavid van Moolenbroek event_set(&e2, pair[0], EV_WRITE, test_multiple_cb, NULL);
1682e985b929SDavid van Moolenbroek event_add(&e2, NULL);
1683e985b929SDavid van Moolenbroek event_loop(EVLOOP_ONCE);
1684e985b929SDavid van Moolenbroek event_del(&e2);
1685e985b929SDavid van Moolenbroek
1686e985b929SDavid van Moolenbroek if (write(pair[1], TEST1, strlen(TEST1)+1) < 0) {
1687e985b929SDavid van Moolenbroek tt_fail_perror("write");
1688e985b929SDavid van Moolenbroek }
1689e985b929SDavid van Moolenbroek
1690e985b929SDavid van Moolenbroek event_loop(EVLOOP_ONCE);
1691e985b929SDavid van Moolenbroek event_del(&e1);
1692e985b929SDavid van Moolenbroek
1693e985b929SDavid van Moolenbroek if (test_ok != 3)
1694e985b929SDavid van Moolenbroek test_ok = 0;
1695e985b929SDavid van Moolenbroek
1696e985b929SDavid van Moolenbroek cleanup_test();
1697e985b929SDavid van Moolenbroek }
1698e985b929SDavid van Moolenbroek
1699e985b929SDavid van Moolenbroek int evtag_decode_int(ev_uint32_t *pnumber, struct evbuffer *evbuf);
1700e985b929SDavid van Moolenbroek int evtag_decode_int64(ev_uint64_t *pnumber, struct evbuffer *evbuf);
1701e985b929SDavid van Moolenbroek int evtag_encode_tag(struct evbuffer *evbuf, ev_uint32_t number);
1702e985b929SDavid van Moolenbroek int evtag_decode_tag(ev_uint32_t *pnumber, struct evbuffer *evbuf);
1703e985b929SDavid van Moolenbroek
1704e985b929SDavid van Moolenbroek static void
read_once_cb(evutil_socket_t fd,short event,void * arg)1705e985b929SDavid van Moolenbroek read_once_cb(evutil_socket_t fd, short event, void *arg)
1706e985b929SDavid van Moolenbroek {
1707e985b929SDavid van Moolenbroek char buf[256];
1708e985b929SDavid van Moolenbroek int len;
1709e985b929SDavid van Moolenbroek
1710e985b929SDavid van Moolenbroek len = read(fd, buf, sizeof(buf));
1711e985b929SDavid van Moolenbroek
1712e985b929SDavid van Moolenbroek if (called) {
1713e985b929SDavid van Moolenbroek test_ok = 0;
1714e985b929SDavid van Moolenbroek } else if (len) {
1715e985b929SDavid van Moolenbroek /* Assumes global pair[0] can be used for writing */
1716e985b929SDavid van Moolenbroek if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) {
1717e985b929SDavid van Moolenbroek tt_fail_perror("write");
1718e985b929SDavid van Moolenbroek test_ok = 0;
1719e985b929SDavid van Moolenbroek } else {
1720e985b929SDavid van Moolenbroek test_ok = 1;
1721e985b929SDavid van Moolenbroek }
1722e985b929SDavid van Moolenbroek }
1723e985b929SDavid van Moolenbroek
1724e985b929SDavid van Moolenbroek called++;
1725e985b929SDavid van Moolenbroek }
1726e985b929SDavid van Moolenbroek
1727e985b929SDavid van Moolenbroek static void
test_want_only_once(void)1728e985b929SDavid van Moolenbroek test_want_only_once(void)
1729e985b929SDavid van Moolenbroek {
1730e985b929SDavid van Moolenbroek struct event ev;
1731e985b929SDavid van Moolenbroek struct timeval tv;
1732e985b929SDavid van Moolenbroek
1733e985b929SDavid van Moolenbroek /* Very simple read test */
1734e985b929SDavid van Moolenbroek setup_test("Want read only once: ");
1735e985b929SDavid van Moolenbroek
1736e985b929SDavid van Moolenbroek if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) {
1737e985b929SDavid van Moolenbroek tt_fail_perror("write");
1738e985b929SDavid van Moolenbroek }
1739e985b929SDavid van Moolenbroek
1740e985b929SDavid van Moolenbroek /* Setup the loop termination */
1741e985b929SDavid van Moolenbroek evutil_timerclear(&tv);
1742e985b929SDavid van Moolenbroek tv.tv_sec = 1;
1743e985b929SDavid van Moolenbroek event_loopexit(&tv);
1744e985b929SDavid van Moolenbroek
1745e985b929SDavid van Moolenbroek event_set(&ev, pair[1], EV_READ, read_once_cb, &ev);
1746e985b929SDavid van Moolenbroek if (event_add(&ev, NULL) == -1)
1747e985b929SDavid van Moolenbroek exit(1);
1748e985b929SDavid van Moolenbroek event_dispatch();
1749e985b929SDavid van Moolenbroek
1750e985b929SDavid van Moolenbroek cleanup_test();
1751e985b929SDavid van Moolenbroek }
1752e985b929SDavid van Moolenbroek
1753e985b929SDavid van Moolenbroek #define TEST_MAX_INT 6
1754e985b929SDavid van Moolenbroek
1755e985b929SDavid van Moolenbroek static void
evtag_int_test(void * ptr)1756e985b929SDavid van Moolenbroek evtag_int_test(void *ptr)
1757e985b929SDavid van Moolenbroek {
1758e985b929SDavid van Moolenbroek struct evbuffer *tmp = evbuffer_new();
1759e985b929SDavid van Moolenbroek ev_uint32_t integers[TEST_MAX_INT] = {
1760e985b929SDavid van Moolenbroek 0xaf0, 0x1000, 0x1, 0xdeadbeef, 0x00, 0xbef000
1761e985b929SDavid van Moolenbroek };
1762e985b929SDavid van Moolenbroek ev_uint32_t integer;
1763e985b929SDavid van Moolenbroek ev_uint64_t big_int;
1764e985b929SDavid van Moolenbroek int i;
1765e985b929SDavid van Moolenbroek
1766e985b929SDavid van Moolenbroek evtag_init();
1767e985b929SDavid van Moolenbroek
1768e985b929SDavid van Moolenbroek for (i = 0; i < TEST_MAX_INT; i++) {
1769e985b929SDavid van Moolenbroek int oldlen, newlen;
1770e985b929SDavid van Moolenbroek oldlen = (int)EVBUFFER_LENGTH(tmp);
1771e985b929SDavid van Moolenbroek evtag_encode_int(tmp, integers[i]);
1772e985b929SDavid van Moolenbroek newlen = (int)EVBUFFER_LENGTH(tmp);
1773e985b929SDavid van Moolenbroek TT_BLATHER(("encoded 0x%08x with %d bytes",
1774e985b929SDavid van Moolenbroek (unsigned)integers[i], newlen - oldlen));
1775e985b929SDavid van Moolenbroek big_int = integers[i];
1776e985b929SDavid van Moolenbroek big_int *= 1000000000; /* 1 billion */
1777e985b929SDavid van Moolenbroek evtag_encode_int64(tmp, big_int);
1778e985b929SDavid van Moolenbroek }
1779e985b929SDavid van Moolenbroek
1780e985b929SDavid van Moolenbroek for (i = 0; i < TEST_MAX_INT; i++) {
1781e985b929SDavid van Moolenbroek tt_int_op(evtag_decode_int(&integer, tmp), !=, -1);
1782e985b929SDavid van Moolenbroek tt_uint_op(integer, ==, integers[i]);
1783e985b929SDavid van Moolenbroek tt_int_op(evtag_decode_int64(&big_int, tmp), !=, -1);
1784e985b929SDavid van Moolenbroek tt_assert((big_int / 1000000000) == integers[i]);
1785e985b929SDavid van Moolenbroek }
1786e985b929SDavid van Moolenbroek
1787e985b929SDavid van Moolenbroek tt_uint_op(EVBUFFER_LENGTH(tmp), ==, 0);
1788e985b929SDavid van Moolenbroek end:
1789e985b929SDavid van Moolenbroek evbuffer_free(tmp);
1790e985b929SDavid van Moolenbroek }
1791e985b929SDavid van Moolenbroek
1792e985b929SDavid van Moolenbroek static void
evtag_fuzz(void * ptr)1793e985b929SDavid van Moolenbroek evtag_fuzz(void *ptr)
1794e985b929SDavid van Moolenbroek {
1795e985b929SDavid van Moolenbroek u_char buffer[4096];
1796e985b929SDavid van Moolenbroek struct evbuffer *tmp = evbuffer_new();
1797e985b929SDavid van Moolenbroek struct timeval tv;
1798e985b929SDavid van Moolenbroek int i, j;
1799e985b929SDavid van Moolenbroek
1800e985b929SDavid van Moolenbroek int not_failed = 0;
1801e985b929SDavid van Moolenbroek
1802e985b929SDavid van Moolenbroek evtag_init();
1803e985b929SDavid van Moolenbroek
1804e985b929SDavid van Moolenbroek for (j = 0; j < 100; j++) {
1805e985b929SDavid van Moolenbroek for (i = 0; i < (int)sizeof(buffer); i++)
1806e985b929SDavid van Moolenbroek buffer[i] = rand();
1807e985b929SDavid van Moolenbroek evbuffer_drain(tmp, -1);
1808e985b929SDavid van Moolenbroek evbuffer_add(tmp, buffer, sizeof(buffer));
1809e985b929SDavid van Moolenbroek
1810e985b929SDavid van Moolenbroek if (evtag_unmarshal_timeval(tmp, 0, &tv) != -1)
1811e985b929SDavid van Moolenbroek not_failed++;
1812e985b929SDavid van Moolenbroek }
1813e985b929SDavid van Moolenbroek
1814e985b929SDavid van Moolenbroek /* The majority of decodes should fail */
1815e985b929SDavid van Moolenbroek tt_int_op(not_failed, <, 10);
1816e985b929SDavid van Moolenbroek
1817e985b929SDavid van Moolenbroek /* Now insert some corruption into the tag length field */
1818e985b929SDavid van Moolenbroek evbuffer_drain(tmp, -1);
1819e985b929SDavid van Moolenbroek evutil_timerclear(&tv);
1820e985b929SDavid van Moolenbroek tv.tv_sec = 1;
1821e985b929SDavid van Moolenbroek evtag_marshal_timeval(tmp, 0, &tv);
1822e985b929SDavid van Moolenbroek evbuffer_add(tmp, buffer, sizeof(buffer));
1823e985b929SDavid van Moolenbroek
1824e985b929SDavid van Moolenbroek ((char *)EVBUFFER_DATA(tmp))[1] = '\xff';
1825e985b929SDavid van Moolenbroek if (evtag_unmarshal_timeval(tmp, 0, &tv) != -1) {
1826e985b929SDavid van Moolenbroek tt_abort_msg("evtag_unmarshal_timeval should have failed");
1827e985b929SDavid van Moolenbroek }
1828e985b929SDavid van Moolenbroek
1829e985b929SDavid van Moolenbroek end:
1830e985b929SDavid van Moolenbroek evbuffer_free(tmp);
1831e985b929SDavid van Moolenbroek }
1832e985b929SDavid van Moolenbroek
1833e985b929SDavid van Moolenbroek static void
evtag_tag_encoding(void * ptr)1834e985b929SDavid van Moolenbroek evtag_tag_encoding(void *ptr)
1835e985b929SDavid van Moolenbroek {
1836e985b929SDavid van Moolenbroek struct evbuffer *tmp = evbuffer_new();
1837e985b929SDavid van Moolenbroek ev_uint32_t integers[TEST_MAX_INT] = {
1838e985b929SDavid van Moolenbroek 0xaf0, 0x1000, 0x1, 0xdeadbeef, 0x00, 0xbef000
1839e985b929SDavid van Moolenbroek };
1840e985b929SDavid van Moolenbroek ev_uint32_t integer;
1841e985b929SDavid van Moolenbroek int i;
1842e985b929SDavid van Moolenbroek
1843e985b929SDavid van Moolenbroek evtag_init();
1844e985b929SDavid van Moolenbroek
1845e985b929SDavid van Moolenbroek for (i = 0; i < TEST_MAX_INT; i++) {
1846e985b929SDavid van Moolenbroek int oldlen, newlen;
1847e985b929SDavid van Moolenbroek oldlen = (int)EVBUFFER_LENGTH(tmp);
1848e985b929SDavid van Moolenbroek evtag_encode_tag(tmp, integers[i]);
1849e985b929SDavid van Moolenbroek newlen = (int)EVBUFFER_LENGTH(tmp);
1850e985b929SDavid van Moolenbroek TT_BLATHER(("encoded 0x%08x with %d bytes",
1851e985b929SDavid van Moolenbroek (unsigned)integers[i], newlen - oldlen));
1852e985b929SDavid van Moolenbroek }
1853e985b929SDavid van Moolenbroek
1854e985b929SDavid van Moolenbroek for (i = 0; i < TEST_MAX_INT; i++) {
1855e985b929SDavid van Moolenbroek tt_int_op(evtag_decode_tag(&integer, tmp), !=, -1);
1856e985b929SDavid van Moolenbroek tt_uint_op(integer, ==, integers[i]);
1857e985b929SDavid van Moolenbroek }
1858e985b929SDavid van Moolenbroek
1859e985b929SDavid van Moolenbroek tt_uint_op(EVBUFFER_LENGTH(tmp), ==, 0);
1860e985b929SDavid van Moolenbroek
1861e985b929SDavid van Moolenbroek end:
1862e985b929SDavid van Moolenbroek evbuffer_free(tmp);
1863e985b929SDavid van Moolenbroek }
1864e985b929SDavid van Moolenbroek
1865e985b929SDavid van Moolenbroek static void
evtag_test_peek(void * ptr)1866e985b929SDavid van Moolenbroek evtag_test_peek(void *ptr)
1867e985b929SDavid van Moolenbroek {
1868e985b929SDavid van Moolenbroek struct evbuffer *tmp = evbuffer_new();
1869e985b929SDavid van Moolenbroek ev_uint32_t u32;
1870e985b929SDavid van Moolenbroek
1871e985b929SDavid van Moolenbroek evtag_marshal_int(tmp, 30, 0);
1872e985b929SDavid van Moolenbroek evtag_marshal_string(tmp, 40, "Hello world");
1873e985b929SDavid van Moolenbroek
1874e985b929SDavid van Moolenbroek tt_int_op(evtag_peek(tmp, &u32), ==, 1);
1875e985b929SDavid van Moolenbroek tt_int_op(u32, ==, 30);
1876e985b929SDavid van Moolenbroek tt_int_op(evtag_peek_length(tmp, &u32), ==, 0);
1877e985b929SDavid van Moolenbroek tt_int_op(u32, ==, 1+1+1);
1878e985b929SDavid van Moolenbroek tt_int_op(evtag_consume(tmp), ==, 0);
1879e985b929SDavid van Moolenbroek
1880e985b929SDavid van Moolenbroek tt_int_op(evtag_peek(tmp, &u32), ==, 1);
1881e985b929SDavid van Moolenbroek tt_int_op(u32, ==, 40);
1882e985b929SDavid van Moolenbroek tt_int_op(evtag_peek_length(tmp, &u32), ==, 0);
1883e985b929SDavid van Moolenbroek tt_int_op(u32, ==, 1+1+11);
1884e985b929SDavid van Moolenbroek tt_int_op(evtag_payload_length(tmp, &u32), ==, 0);
1885e985b929SDavid van Moolenbroek tt_int_op(u32, ==, 11);
1886e985b929SDavid van Moolenbroek
1887e985b929SDavid van Moolenbroek end:
1888e985b929SDavid van Moolenbroek evbuffer_free(tmp);
1889e985b929SDavid van Moolenbroek }
1890e985b929SDavid van Moolenbroek
1891e985b929SDavid van Moolenbroek
1892e985b929SDavid van Moolenbroek static void
test_methods(void * ptr)1893e985b929SDavid van Moolenbroek test_methods(void *ptr)
1894e985b929SDavid van Moolenbroek {
1895e985b929SDavid van Moolenbroek const char **methods = event_get_supported_methods();
1896e985b929SDavid van Moolenbroek struct event_config *cfg = NULL;
1897e985b929SDavid van Moolenbroek struct event_base *base = NULL;
1898e985b929SDavid van Moolenbroek const char *backend;
1899e985b929SDavid van Moolenbroek int n_methods = 0;
1900e985b929SDavid van Moolenbroek
1901e985b929SDavid van Moolenbroek tt_assert(methods);
1902e985b929SDavid van Moolenbroek
1903e985b929SDavid van Moolenbroek backend = methods[0];
1904e985b929SDavid van Moolenbroek while (*methods != NULL) {
1905e985b929SDavid van Moolenbroek TT_BLATHER(("Support method: %s", *methods));
1906e985b929SDavid van Moolenbroek ++methods;
1907e985b929SDavid van Moolenbroek ++n_methods;
1908e985b929SDavid van Moolenbroek }
1909e985b929SDavid van Moolenbroek
1910e985b929SDavid van Moolenbroek cfg = event_config_new();
1911e985b929SDavid van Moolenbroek assert(cfg != NULL);
1912e985b929SDavid van Moolenbroek
1913e985b929SDavid van Moolenbroek tt_int_op(event_config_avoid_method(cfg, backend), ==, 0);
1914e985b929SDavid van Moolenbroek event_config_set_flag(cfg, EVENT_BASE_FLAG_IGNORE_ENV);
1915e985b929SDavid van Moolenbroek
1916e985b929SDavid van Moolenbroek base = event_base_new_with_config(cfg);
1917e985b929SDavid van Moolenbroek if (n_methods > 1) {
1918e985b929SDavid van Moolenbroek tt_assert(base);
1919e985b929SDavid van Moolenbroek tt_str_op(backend, !=, event_base_get_method(base));
1920e985b929SDavid van Moolenbroek } else {
1921e985b929SDavid van Moolenbroek tt_assert(base == NULL);
1922e985b929SDavid van Moolenbroek }
1923e985b929SDavid van Moolenbroek
1924e985b929SDavid van Moolenbroek end:
1925e985b929SDavid van Moolenbroek if (base)
1926e985b929SDavid van Moolenbroek event_base_free(base);
1927e985b929SDavid van Moolenbroek if (cfg)
1928e985b929SDavid van Moolenbroek event_config_free(cfg);
1929e985b929SDavid van Moolenbroek }
1930e985b929SDavid van Moolenbroek
1931e985b929SDavid van Moolenbroek static void
test_version(void * arg)1932e985b929SDavid van Moolenbroek test_version(void *arg)
1933e985b929SDavid van Moolenbroek {
1934e985b929SDavid van Moolenbroek const char *vstr;
1935e985b929SDavid van Moolenbroek ev_uint32_t vint;
1936e985b929SDavid van Moolenbroek int major, minor, patch, n;
1937e985b929SDavid van Moolenbroek
1938e985b929SDavid van Moolenbroek vstr = event_get_version();
1939e985b929SDavid van Moolenbroek vint = event_get_version_number();
1940e985b929SDavid van Moolenbroek
1941e985b929SDavid van Moolenbroek tt_assert(vstr);
1942e985b929SDavid van Moolenbroek tt_assert(vint);
1943e985b929SDavid van Moolenbroek
1944e985b929SDavid van Moolenbroek tt_str_op(vstr, ==, LIBEVENT_VERSION);
1945e985b929SDavid van Moolenbroek tt_int_op(vint, ==, LIBEVENT_VERSION_NUMBER);
1946e985b929SDavid van Moolenbroek
1947e985b929SDavid van Moolenbroek n = sscanf(vstr, "%d.%d.%d", &major, &minor, &patch);
1948e985b929SDavid van Moolenbroek tt_assert(3 == n);
1949e985b929SDavid van Moolenbroek tt_int_op((vint&0xffffff00), ==, ((major<<24)|(minor<<16)|(patch<<8)));
1950e985b929SDavid van Moolenbroek end:
1951e985b929SDavid van Moolenbroek ;
1952e985b929SDavid van Moolenbroek }
1953e985b929SDavid van Moolenbroek
1954e985b929SDavid van Moolenbroek static void
test_base_features(void * arg)1955e985b929SDavid van Moolenbroek test_base_features(void *arg)
1956e985b929SDavid van Moolenbroek {
1957e985b929SDavid van Moolenbroek struct event_base *base = NULL;
1958e985b929SDavid van Moolenbroek struct event_config *cfg = NULL;
1959e985b929SDavid van Moolenbroek
1960e985b929SDavid van Moolenbroek cfg = event_config_new();
1961e985b929SDavid van Moolenbroek
1962e985b929SDavid van Moolenbroek tt_assert(0 == event_config_require_features(cfg, EV_FEATURE_ET));
1963e985b929SDavid van Moolenbroek
1964e985b929SDavid van Moolenbroek base = event_base_new_with_config(cfg);
1965e985b929SDavid van Moolenbroek if (base) {
1966e985b929SDavid van Moolenbroek tt_int_op(EV_FEATURE_ET, ==,
1967e985b929SDavid van Moolenbroek event_base_get_features(base) & EV_FEATURE_ET);
1968e985b929SDavid van Moolenbroek } else {
1969e985b929SDavid van Moolenbroek base = event_base_new();
1970e985b929SDavid van Moolenbroek tt_int_op(0, ==, event_base_get_features(base) & EV_FEATURE_ET);
1971e985b929SDavid van Moolenbroek }
1972e985b929SDavid van Moolenbroek
1973e985b929SDavid van Moolenbroek end:
1974e985b929SDavid van Moolenbroek if (base)
1975e985b929SDavid van Moolenbroek event_base_free(base);
1976e985b929SDavid van Moolenbroek if (cfg)
1977e985b929SDavid van Moolenbroek event_config_free(cfg);
1978e985b929SDavid van Moolenbroek }
1979e985b929SDavid van Moolenbroek
1980e985b929SDavid van Moolenbroek #ifdef _EVENT_HAVE_SETENV
1981e985b929SDavid van Moolenbroek #define SETENV_OK
1982e985b929SDavid van Moolenbroek #elif !defined(_EVENT_HAVE_SETENV) && defined(_EVENT_HAVE_PUTENV)
setenv(const char * k,const char * v,int _o)1983e985b929SDavid van Moolenbroek static void setenv(const char *k, const char *v, int _o)
1984e985b929SDavid van Moolenbroek {
1985e985b929SDavid van Moolenbroek char b[256];
1986e985b929SDavid van Moolenbroek evutil_snprintf(b, sizeof(b), "%s=%s",k,v);
1987e985b929SDavid van Moolenbroek putenv(b);
1988e985b929SDavid van Moolenbroek }
1989e985b929SDavid van Moolenbroek #define SETENV_OK
1990e985b929SDavid van Moolenbroek #endif
1991e985b929SDavid van Moolenbroek
1992e985b929SDavid van Moolenbroek #ifdef _EVENT_HAVE_UNSETENV
1993e985b929SDavid van Moolenbroek #define UNSETENV_OK
1994e985b929SDavid van Moolenbroek #elif !defined(_EVENT_HAVE_UNSETENV) && defined(_EVENT_HAVE_PUTENV)
unsetenv(const char * k)1995e985b929SDavid van Moolenbroek static void unsetenv(const char *k)
1996e985b929SDavid van Moolenbroek {
1997e985b929SDavid van Moolenbroek char b[256];
1998e985b929SDavid van Moolenbroek evutil_snprintf(b, sizeof(b), "%s=",k);
1999e985b929SDavid van Moolenbroek putenv(b);
2000e985b929SDavid van Moolenbroek }
2001e985b929SDavid van Moolenbroek #define UNSETENV_OK
2002e985b929SDavid van Moolenbroek #endif
2003e985b929SDavid van Moolenbroek
2004e985b929SDavid van Moolenbroek #if defined(SETENV_OK) && defined(UNSETENV_OK)
2005e985b929SDavid van Moolenbroek static void
methodname_to_envvar(const char * mname,char * buf,size_t buflen)2006e985b929SDavid van Moolenbroek methodname_to_envvar(const char *mname, char *buf, size_t buflen)
2007e985b929SDavid van Moolenbroek {
2008e985b929SDavid van Moolenbroek char *cp;
2009e985b929SDavid van Moolenbroek evutil_snprintf(buf, buflen, "EVENT_NO%s", mname);
2010e985b929SDavid van Moolenbroek for (cp = buf; *cp; ++cp) {
2011e985b929SDavid van Moolenbroek *cp = EVUTIL_TOUPPER(*cp);
2012e985b929SDavid van Moolenbroek }
2013e985b929SDavid van Moolenbroek }
2014e985b929SDavid van Moolenbroek #endif
2015e985b929SDavid van Moolenbroek
2016e985b929SDavid van Moolenbroek static void
test_base_environ(void * arg)2017e985b929SDavid van Moolenbroek test_base_environ(void *arg)
2018e985b929SDavid van Moolenbroek {
2019e985b929SDavid van Moolenbroek struct event_base *base = NULL;
2020e985b929SDavid van Moolenbroek struct event_config *cfg = NULL;
2021e985b929SDavid van Moolenbroek
2022e985b929SDavid van Moolenbroek #if defined(SETENV_OK) && defined(UNSETENV_OK)
2023e985b929SDavid van Moolenbroek const char **basenames;
2024e985b929SDavid van Moolenbroek int i, n_methods=0;
2025e985b929SDavid van Moolenbroek char varbuf[128];
2026e985b929SDavid van Moolenbroek const char *defaultname, *ignoreenvname;
2027e985b929SDavid van Moolenbroek
2028e985b929SDavid van Moolenbroek /* See if unsetenv works before we rely on it. */
2029e985b929SDavid van Moolenbroek setenv("EVENT_NOWAFFLES", "1", 1);
2030e985b929SDavid van Moolenbroek unsetenv("EVENT_NOWAFFLES");
2031e985b929SDavid van Moolenbroek if (getenv("EVENT_NOWAFFLES") != NULL) {
2032e985b929SDavid van Moolenbroek #ifndef _EVENT_HAVE_UNSETENV
2033e985b929SDavid van Moolenbroek TT_DECLARE("NOTE", ("Can't fake unsetenv; skipping test"));
2034e985b929SDavid van Moolenbroek #else
2035e985b929SDavid van Moolenbroek TT_DECLARE("NOTE", ("unsetenv doesn't work; skipping test"));
2036e985b929SDavid van Moolenbroek #endif
2037e985b929SDavid van Moolenbroek tt_skip();
2038e985b929SDavid van Moolenbroek }
2039e985b929SDavid van Moolenbroek
2040e985b929SDavid van Moolenbroek basenames = event_get_supported_methods();
2041e985b929SDavid van Moolenbroek for (i = 0; basenames[i]; ++i) {
2042e985b929SDavid van Moolenbroek methodname_to_envvar(basenames[i], varbuf, sizeof(varbuf));
2043e985b929SDavid van Moolenbroek unsetenv(varbuf);
2044e985b929SDavid van Moolenbroek ++n_methods;
2045e985b929SDavid van Moolenbroek }
2046e985b929SDavid van Moolenbroek
2047e985b929SDavid van Moolenbroek base = event_base_new();
2048e985b929SDavid van Moolenbroek tt_assert(base);
2049e985b929SDavid van Moolenbroek
2050e985b929SDavid van Moolenbroek defaultname = event_base_get_method(base);
2051e985b929SDavid van Moolenbroek TT_BLATHER(("default is <%s>", defaultname));
2052e985b929SDavid van Moolenbroek event_base_free(base);
2053e985b929SDavid van Moolenbroek base = NULL;
2054e985b929SDavid van Moolenbroek
2055e985b929SDavid van Moolenbroek /* Can we disable the method with EVENT_NOfoo ? */
2056e985b929SDavid van Moolenbroek if (!strcmp(defaultname, "epoll (with changelist)")) {
2057e985b929SDavid van Moolenbroek setenv("EVENT_NOEPOLL", "1", 1);
2058e985b929SDavid van Moolenbroek ignoreenvname = "epoll";
2059e985b929SDavid van Moolenbroek } else {
2060e985b929SDavid van Moolenbroek methodname_to_envvar(defaultname, varbuf, sizeof(varbuf));
2061e985b929SDavid van Moolenbroek setenv(varbuf, "1", 1);
2062e985b929SDavid van Moolenbroek ignoreenvname = defaultname;
2063e985b929SDavid van Moolenbroek }
2064e985b929SDavid van Moolenbroek
2065e985b929SDavid van Moolenbroek /* Use an empty cfg rather than NULL so a failure doesn't exit() */
2066e985b929SDavid van Moolenbroek cfg = event_config_new();
2067e985b929SDavid van Moolenbroek base = event_base_new_with_config(cfg);
2068e985b929SDavid van Moolenbroek event_config_free(cfg);
2069e985b929SDavid van Moolenbroek cfg = NULL;
2070e985b929SDavid van Moolenbroek if (n_methods == 1) {
2071e985b929SDavid van Moolenbroek tt_assert(!base);
2072e985b929SDavid van Moolenbroek } else {
2073e985b929SDavid van Moolenbroek tt_assert(base);
2074e985b929SDavid van Moolenbroek tt_str_op(defaultname, !=, event_base_get_method(base));
2075e985b929SDavid van Moolenbroek event_base_free(base);
2076e985b929SDavid van Moolenbroek base = NULL;
2077e985b929SDavid van Moolenbroek }
2078e985b929SDavid van Moolenbroek
2079e985b929SDavid van Moolenbroek /* Can we disable looking at the environment with IGNORE_ENV ? */
2080e985b929SDavid van Moolenbroek cfg = event_config_new();
2081e985b929SDavid van Moolenbroek event_config_set_flag(cfg, EVENT_BASE_FLAG_IGNORE_ENV);
2082e985b929SDavid van Moolenbroek base = event_base_new_with_config(cfg);
2083e985b929SDavid van Moolenbroek tt_assert(base);
2084e985b929SDavid van Moolenbroek tt_str_op(ignoreenvname, ==, event_base_get_method(base));
2085e985b929SDavid van Moolenbroek #else
2086e985b929SDavid van Moolenbroek tt_skip();
2087e985b929SDavid van Moolenbroek #endif
2088e985b929SDavid van Moolenbroek
2089e985b929SDavid van Moolenbroek end:
2090e985b929SDavid van Moolenbroek if (base)
2091e985b929SDavid van Moolenbroek event_base_free(base);
2092e985b929SDavid van Moolenbroek if (cfg)
2093e985b929SDavid van Moolenbroek event_config_free(cfg);
2094e985b929SDavid van Moolenbroek }
2095e985b929SDavid van Moolenbroek
2096e985b929SDavid van Moolenbroek static void
read_called_once_cb(evutil_socket_t fd,short event,void * arg)2097e985b929SDavid van Moolenbroek read_called_once_cb(evutil_socket_t fd, short event, void *arg)
2098e985b929SDavid van Moolenbroek {
2099e985b929SDavid van Moolenbroek tt_int_op(event, ==, EV_READ);
2100e985b929SDavid van Moolenbroek called += 1;
2101e985b929SDavid van Moolenbroek end:
2102e985b929SDavid van Moolenbroek ;
2103e985b929SDavid van Moolenbroek }
2104e985b929SDavid van Moolenbroek
2105e985b929SDavid van Moolenbroek static void
timeout_called_once_cb(evutil_socket_t fd,short event,void * arg)2106e985b929SDavid van Moolenbroek timeout_called_once_cb(evutil_socket_t fd, short event, void *arg)
2107e985b929SDavid van Moolenbroek {
2108e985b929SDavid van Moolenbroek tt_int_op(event, ==, EV_TIMEOUT);
2109e985b929SDavid van Moolenbroek called += 100;
2110e985b929SDavid van Moolenbroek end:
2111e985b929SDavid van Moolenbroek ;
2112e985b929SDavid van Moolenbroek }
2113e985b929SDavid van Moolenbroek
2114e985b929SDavid van Moolenbroek static void
test_event_once(void * ptr)2115e985b929SDavid van Moolenbroek test_event_once(void *ptr)
2116e985b929SDavid van Moolenbroek {
2117e985b929SDavid van Moolenbroek struct basic_test_data *data = ptr;
2118e985b929SDavid van Moolenbroek struct timeval tv;
2119e985b929SDavid van Moolenbroek int r;
2120e985b929SDavid van Moolenbroek
2121e985b929SDavid van Moolenbroek tv.tv_sec = 0;
2122e985b929SDavid van Moolenbroek tv.tv_usec = 50*1000;
2123e985b929SDavid van Moolenbroek called = 0;
2124e985b929SDavid van Moolenbroek r = event_base_once(data->base, data->pair[0], EV_READ,
2125e985b929SDavid van Moolenbroek read_called_once_cb, NULL, NULL);
2126e985b929SDavid van Moolenbroek tt_int_op(r, ==, 0);
2127e985b929SDavid van Moolenbroek r = event_base_once(data->base, -1, EV_TIMEOUT,
2128e985b929SDavid van Moolenbroek timeout_called_once_cb, NULL, &tv);
2129e985b929SDavid van Moolenbroek tt_int_op(r, ==, 0);
2130e985b929SDavid van Moolenbroek r = event_base_once(data->base, -1, 0, NULL, NULL, NULL);
2131e985b929SDavid van Moolenbroek tt_int_op(r, <, 0);
2132e985b929SDavid van Moolenbroek
2133e985b929SDavid van Moolenbroek if (write(data->pair[1], TEST1, strlen(TEST1)+1) < 0) {
2134e985b929SDavid van Moolenbroek tt_fail_perror("write");
2135e985b929SDavid van Moolenbroek }
2136e985b929SDavid van Moolenbroek
2137e985b929SDavid van Moolenbroek shutdown(data->pair[1], SHUT_WR);
2138e985b929SDavid van Moolenbroek
2139e985b929SDavid van Moolenbroek event_base_dispatch(data->base);
2140e985b929SDavid van Moolenbroek
2141e985b929SDavid van Moolenbroek tt_int_op(called, ==, 101);
2142e985b929SDavid van Moolenbroek end:
2143e985b929SDavid van Moolenbroek ;
2144e985b929SDavid van Moolenbroek }
2145e985b929SDavid van Moolenbroek
2146e985b929SDavid van Moolenbroek static void
test_event_pending(void * ptr)2147e985b929SDavid van Moolenbroek test_event_pending(void *ptr)
2148e985b929SDavid van Moolenbroek {
2149e985b929SDavid van Moolenbroek struct basic_test_data *data = ptr;
2150e985b929SDavid van Moolenbroek struct event *r=NULL, *w=NULL, *t=NULL;
2151e985b929SDavid van Moolenbroek struct timeval tv, now, tv2, diff;
2152e985b929SDavid van Moolenbroek
2153e985b929SDavid van Moolenbroek tv.tv_sec = 0;
2154e985b929SDavid van Moolenbroek tv.tv_usec = 500 * 1000;
2155e985b929SDavid van Moolenbroek r = event_new(data->base, data->pair[0], EV_READ, simple_read_cb,
2156e985b929SDavid van Moolenbroek NULL);
2157e985b929SDavid van Moolenbroek w = event_new(data->base, data->pair[1], EV_WRITE, simple_write_cb,
2158e985b929SDavid van Moolenbroek NULL);
2159e985b929SDavid van Moolenbroek t = evtimer_new(data->base, timeout_cb, NULL);
2160e985b929SDavid van Moolenbroek
2161e985b929SDavid van Moolenbroek tt_assert(r);
2162e985b929SDavid van Moolenbroek tt_assert(w);
2163e985b929SDavid van Moolenbroek tt_assert(t);
2164e985b929SDavid van Moolenbroek
2165e985b929SDavid van Moolenbroek evutil_gettimeofday(&now, NULL);
2166e985b929SDavid van Moolenbroek event_add(r, NULL);
2167e985b929SDavid van Moolenbroek event_add(t, &tv);
2168e985b929SDavid van Moolenbroek
2169e985b929SDavid van Moolenbroek tt_assert( event_pending(r, EV_READ, NULL));
2170e985b929SDavid van Moolenbroek tt_assert(!event_pending(w, EV_WRITE, NULL));
2171e985b929SDavid van Moolenbroek tt_assert(!event_pending(r, EV_WRITE, NULL));
2172e985b929SDavid van Moolenbroek tt_assert( event_pending(r, EV_READ|EV_WRITE, NULL));
2173e985b929SDavid van Moolenbroek tt_assert(!event_pending(r, EV_TIMEOUT, NULL));
2174e985b929SDavid van Moolenbroek tt_assert( event_pending(t, EV_TIMEOUT, NULL));
2175e985b929SDavid van Moolenbroek tt_assert( event_pending(t, EV_TIMEOUT, &tv2));
2176e985b929SDavid van Moolenbroek
2177e985b929SDavid van Moolenbroek tt_assert(evutil_timercmp(&tv2, &now, >));
2178e985b929SDavid van Moolenbroek evutil_timeradd(&now, &tv, &tv);
2179e985b929SDavid van Moolenbroek evutil_timersub(&tv2, &tv, &diff);
2180e985b929SDavid van Moolenbroek tt_int_op(diff.tv_sec, ==, 0);
2181e985b929SDavid van Moolenbroek tt_int_op(labs(diff.tv_usec), <, 1000);
2182e985b929SDavid van Moolenbroek
2183e985b929SDavid van Moolenbroek end:
2184e985b929SDavid van Moolenbroek if (r) {
2185e985b929SDavid van Moolenbroek event_del(r);
2186e985b929SDavid van Moolenbroek event_free(r);
2187e985b929SDavid van Moolenbroek }
2188e985b929SDavid van Moolenbroek if (w) {
2189e985b929SDavid van Moolenbroek event_del(w);
2190e985b929SDavid van Moolenbroek event_free(w);
2191e985b929SDavid van Moolenbroek }
2192e985b929SDavid van Moolenbroek if (t) {
2193e985b929SDavid van Moolenbroek event_del(t);
2194e985b929SDavid van Moolenbroek event_free(t);
2195e985b929SDavid van Moolenbroek }
2196e985b929SDavid van Moolenbroek }
2197e985b929SDavid van Moolenbroek
2198e985b929SDavid van Moolenbroek #ifndef WIN32
2199e985b929SDavid van Moolenbroek /* You can't do this test on windows, since dup2 doesn't work on sockets */
2200e985b929SDavid van Moolenbroek
2201e985b929SDavid van Moolenbroek static void
dfd_cb(evutil_socket_t fd,short e,void * data)2202e985b929SDavid van Moolenbroek dfd_cb(evutil_socket_t fd, short e, void *data)
2203e985b929SDavid van Moolenbroek {
2204e985b929SDavid van Moolenbroek *(int*)data = (int)e;
2205e985b929SDavid van Moolenbroek }
2206e985b929SDavid van Moolenbroek
2207e985b929SDavid van Moolenbroek /* Regression test for our workaround for a fun epoll/linux related bug
2208e985b929SDavid van Moolenbroek * where fd2 = dup(fd1); add(fd2); close(fd2); dup2(fd1,fd2); add(fd2)
2209e985b929SDavid van Moolenbroek * will get you an EEXIST */
2210e985b929SDavid van Moolenbroek static void
test_dup_fd(void * arg)2211e985b929SDavid van Moolenbroek test_dup_fd(void *arg)
2212e985b929SDavid van Moolenbroek {
2213e985b929SDavid van Moolenbroek struct basic_test_data *data = arg;
2214e985b929SDavid van Moolenbroek struct event_base *base = data->base;
2215e985b929SDavid van Moolenbroek struct event *ev1=NULL, *ev2=NULL;
2216e985b929SDavid van Moolenbroek int fd, dfd=-1;
2217e985b929SDavid van Moolenbroek int ev1_got, ev2_got;
2218e985b929SDavid van Moolenbroek
2219e985b929SDavid van Moolenbroek tt_int_op(write(data->pair[0], "Hello world",
2220e985b929SDavid van Moolenbroek strlen("Hello world")), >, 0);
2221e985b929SDavid van Moolenbroek fd = data->pair[1];
2222e985b929SDavid van Moolenbroek
2223e985b929SDavid van Moolenbroek dfd = dup(fd);
2224e985b929SDavid van Moolenbroek tt_int_op(dfd, >=, 0);
2225e985b929SDavid van Moolenbroek
2226e985b929SDavid van Moolenbroek ev1 = event_new(base, fd, EV_READ|EV_PERSIST, dfd_cb, &ev1_got);
2227e985b929SDavid van Moolenbroek ev2 = event_new(base, dfd, EV_READ|EV_PERSIST, dfd_cb, &ev2_got);
2228e985b929SDavid van Moolenbroek ev1_got = ev2_got = 0;
2229e985b929SDavid van Moolenbroek event_add(ev1, NULL);
2230e985b929SDavid van Moolenbroek event_add(ev2, NULL);
2231e985b929SDavid van Moolenbroek event_base_loop(base, EVLOOP_ONCE);
2232e985b929SDavid van Moolenbroek tt_int_op(ev1_got, ==, EV_READ);
2233e985b929SDavid van Moolenbroek tt_int_op(ev2_got, ==, EV_READ);
2234e985b929SDavid van Moolenbroek
2235e985b929SDavid van Moolenbroek /* Now close and delete dfd then dispatch. We need to do the
2236e985b929SDavid van Moolenbroek * dispatch here so that when we add it later, we think there
2237e985b929SDavid van Moolenbroek * was an intermediate delete. */
2238e985b929SDavid van Moolenbroek close(dfd);
2239e985b929SDavid van Moolenbroek event_del(ev2);
2240e985b929SDavid van Moolenbroek ev1_got = ev2_got = 0;
2241e985b929SDavid van Moolenbroek event_base_loop(base, EVLOOP_ONCE);
2242e985b929SDavid van Moolenbroek tt_want_int_op(ev1_got, ==, EV_READ);
2243e985b929SDavid van Moolenbroek tt_int_op(ev2_got, ==, 0);
2244e985b929SDavid van Moolenbroek
2245e985b929SDavid van Moolenbroek /* Re-duplicate the fd. We need to get the same duplicated
2246e985b929SDavid van Moolenbroek * value that we closed to provoke the epoll quirk. Also, we
2247e985b929SDavid van Moolenbroek * need to change the events to write, or else the old lingering
2248e985b929SDavid van Moolenbroek * read event will make the test pass whether the change was
2249e985b929SDavid van Moolenbroek * successful or not. */
2250e985b929SDavid van Moolenbroek tt_int_op(dup2(fd, dfd), ==, dfd);
2251e985b929SDavid van Moolenbroek event_free(ev2);
2252e985b929SDavid van Moolenbroek ev2 = event_new(base, dfd, EV_WRITE|EV_PERSIST, dfd_cb, &ev2_got);
2253e985b929SDavid van Moolenbroek event_add(ev2, NULL);
2254e985b929SDavid van Moolenbroek ev1_got = ev2_got = 0;
2255e985b929SDavid van Moolenbroek event_base_loop(base, EVLOOP_ONCE);
2256e985b929SDavid van Moolenbroek tt_want_int_op(ev1_got, ==, EV_READ);
2257e985b929SDavid van Moolenbroek tt_int_op(ev2_got, ==, EV_WRITE);
2258e985b929SDavid van Moolenbroek
2259e985b929SDavid van Moolenbroek end:
2260e985b929SDavid van Moolenbroek if (ev1)
2261e985b929SDavid van Moolenbroek event_free(ev1);
2262e985b929SDavid van Moolenbroek if (ev2)
2263e985b929SDavid van Moolenbroek event_free(ev2);
2264e985b929SDavid van Moolenbroek if (dfd >= 0)
2265e985b929SDavid van Moolenbroek close(dfd);
2266e985b929SDavid van Moolenbroek }
2267e985b929SDavid van Moolenbroek #endif
2268e985b929SDavid van Moolenbroek
2269e985b929SDavid van Moolenbroek #ifdef _EVENT_DISABLE_MM_REPLACEMENT
2270e985b929SDavid van Moolenbroek static void
test_mm_functions(void * arg)2271e985b929SDavid van Moolenbroek test_mm_functions(void *arg)
2272e985b929SDavid van Moolenbroek {
2273e985b929SDavid van Moolenbroek _tinytest_set_test_skipped();
2274e985b929SDavid van Moolenbroek }
2275e985b929SDavid van Moolenbroek #else
2276e985b929SDavid van Moolenbroek static int
check_dummy_mem_ok(void * _mem)2277e985b929SDavid van Moolenbroek check_dummy_mem_ok(void *_mem)
2278e985b929SDavid van Moolenbroek {
2279e985b929SDavid van Moolenbroek char *mem = _mem;
2280e985b929SDavid van Moolenbroek mem -= 16;
2281e985b929SDavid van Moolenbroek return !memcmp(mem, "{[<guardedram>]}", 16);
2282e985b929SDavid van Moolenbroek }
2283e985b929SDavid van Moolenbroek
2284e985b929SDavid van Moolenbroek static void *
dummy_malloc(size_t len)2285e985b929SDavid van Moolenbroek dummy_malloc(size_t len)
2286e985b929SDavid van Moolenbroek {
2287e985b929SDavid van Moolenbroek char *mem = malloc(len+16);
2288e985b929SDavid van Moolenbroek memcpy(mem, "{[<guardedram>]}", 16);
2289e985b929SDavid van Moolenbroek return mem+16;
2290e985b929SDavid van Moolenbroek }
2291e985b929SDavid van Moolenbroek
2292e985b929SDavid van Moolenbroek static void *
dummy_realloc(void * _mem,size_t len)2293e985b929SDavid van Moolenbroek dummy_realloc(void *_mem, size_t len)
2294e985b929SDavid van Moolenbroek {
2295e985b929SDavid van Moolenbroek char *mem = _mem;
2296e985b929SDavid van Moolenbroek if (!mem)
2297e985b929SDavid van Moolenbroek return dummy_malloc(len);
2298e985b929SDavid van Moolenbroek tt_want(check_dummy_mem_ok(_mem));
2299e985b929SDavid van Moolenbroek mem -= 16;
2300e985b929SDavid van Moolenbroek mem = realloc(mem, len+16);
2301e985b929SDavid van Moolenbroek return mem+16;
2302e985b929SDavid van Moolenbroek }
2303e985b929SDavid van Moolenbroek
2304e985b929SDavid van Moolenbroek static void
dummy_free(void * _mem)2305e985b929SDavid van Moolenbroek dummy_free(void *_mem)
2306e985b929SDavid van Moolenbroek {
2307e985b929SDavid van Moolenbroek char *mem = _mem;
2308e985b929SDavid van Moolenbroek tt_want(check_dummy_mem_ok(_mem));
2309e985b929SDavid van Moolenbroek mem -= 16;
2310e985b929SDavid van Moolenbroek free(mem);
2311e985b929SDavid van Moolenbroek }
2312e985b929SDavid van Moolenbroek
2313e985b929SDavid van Moolenbroek static void
test_mm_functions(void * arg)2314e985b929SDavid van Moolenbroek test_mm_functions(void *arg)
2315e985b929SDavid van Moolenbroek {
2316e985b929SDavid van Moolenbroek struct event_base *b = NULL;
2317e985b929SDavid van Moolenbroek struct event_config *cfg = NULL;
2318e985b929SDavid van Moolenbroek event_set_mem_functions(dummy_malloc, dummy_realloc, dummy_free);
2319e985b929SDavid van Moolenbroek cfg = event_config_new();
2320e985b929SDavid van Moolenbroek event_config_avoid_method(cfg, "Nonesuch");
2321e985b929SDavid van Moolenbroek b = event_base_new_with_config(cfg);
2322e985b929SDavid van Moolenbroek tt_assert(b);
2323e985b929SDavid van Moolenbroek tt_assert(check_dummy_mem_ok(b));
2324e985b929SDavid van Moolenbroek end:
2325e985b929SDavid van Moolenbroek if (cfg)
2326e985b929SDavid van Moolenbroek event_config_free(cfg);
2327e985b929SDavid van Moolenbroek if (b)
2328e985b929SDavid van Moolenbroek event_base_free(b);
2329e985b929SDavid van Moolenbroek }
2330e985b929SDavid van Moolenbroek #endif
2331e985b929SDavid van Moolenbroek
2332e985b929SDavid van Moolenbroek static void
many_event_cb(evutil_socket_t fd,short event,void * arg)2333e985b929SDavid van Moolenbroek many_event_cb(evutil_socket_t fd, short event, void *arg)
2334e985b929SDavid van Moolenbroek {
2335e985b929SDavid van Moolenbroek int *calledp = arg;
2336e985b929SDavid van Moolenbroek *calledp += 1;
2337e985b929SDavid van Moolenbroek }
2338e985b929SDavid van Moolenbroek
2339e985b929SDavid van Moolenbroek static void
test_many_events(void * arg)2340e985b929SDavid van Moolenbroek test_many_events(void *arg)
2341e985b929SDavid van Moolenbroek {
2342e985b929SDavid van Moolenbroek /* Try 70 events that should all be ready at once. This will
2343e985b929SDavid van Moolenbroek * exercise the "resize" code on most of the backends, and will make
2344e985b929SDavid van Moolenbroek * sure that we can get past the 64-handle limit of some windows
2345e985b929SDavid van Moolenbroek * functions. */
2346e985b929SDavid van Moolenbroek #define MANY 70
2347e985b929SDavid van Moolenbroek
2348e985b929SDavid van Moolenbroek struct basic_test_data *data = arg;
2349e985b929SDavid van Moolenbroek struct event_base *base = data->base;
2350e985b929SDavid van Moolenbroek int one_at_a_time = data->setup_data != NULL;
2351e985b929SDavid van Moolenbroek evutil_socket_t sock[MANY];
2352e985b929SDavid van Moolenbroek struct event *ev[MANY];
2353e985b929SDavid van Moolenbroek int xcalled[MANY];
2354e985b929SDavid van Moolenbroek int i;
2355e985b929SDavid van Moolenbroek int loopflags = EVLOOP_NONBLOCK, evflags=0;
2356e985b929SDavid van Moolenbroek const int is_evport = !strcmp(event_base_get_method(base),"evport");
2357e985b929SDavid van Moolenbroek if (one_at_a_time) {
2358e985b929SDavid van Moolenbroek loopflags |= EVLOOP_ONCE;
2359e985b929SDavid van Moolenbroek evflags = EV_PERSIST;
2360e985b929SDavid van Moolenbroek }
2361e985b929SDavid van Moolenbroek
2362e985b929SDavid van Moolenbroek memset(sock, 0xff, sizeof(sock));
2363e985b929SDavid van Moolenbroek memset(ev, 0, sizeof(ev));
2364e985b929SDavid van Moolenbroek memset(xcalled, 0, sizeof(xcalled));
2365e985b929SDavid van Moolenbroek if (is_evport && one_at_a_time) {
2366e985b929SDavid van Moolenbroek TT_DECLARE("NOTE", ("evport can't pass this in 2.0; skipping\n"));
2367e985b929SDavid van Moolenbroek tt_skip();
2368e985b929SDavid van Moolenbroek }
2369e985b929SDavid van Moolenbroek
2370e985b929SDavid van Moolenbroek for (i = 0; i < MANY; ++i) {
2371e985b929SDavid van Moolenbroek /* We need an event that will hit the backend, and that will
2372e985b929SDavid van Moolenbroek * be ready immediately. "Send a datagram" is an easy
2373e985b929SDavid van Moolenbroek * instance of that. */
2374e985b929SDavid van Moolenbroek sock[i] = socket(AF_INET, SOCK_DGRAM, 0);
2375e985b929SDavid van Moolenbroek tt_assert(sock[i] >= 0);
2376e985b929SDavid van Moolenbroek xcalled[i] = 0;
2377e985b929SDavid van Moolenbroek ev[i] = event_new(base, sock[i], EV_WRITE|evflags,
2378e985b929SDavid van Moolenbroek many_event_cb, &xcalled[i]);
2379e985b929SDavid van Moolenbroek event_add(ev[i], NULL);
2380e985b929SDavid van Moolenbroek if (one_at_a_time)
2381e985b929SDavid van Moolenbroek event_base_loop(base, EVLOOP_NONBLOCK|EVLOOP_ONCE);
2382e985b929SDavid van Moolenbroek }
2383e985b929SDavid van Moolenbroek
2384e985b929SDavid van Moolenbroek event_base_loop(base, loopflags);
2385e985b929SDavid van Moolenbroek
2386e985b929SDavid van Moolenbroek for (i = 0; i < MANY; ++i) {
2387e985b929SDavid van Moolenbroek if (one_at_a_time)
2388e985b929SDavid van Moolenbroek tt_int_op(xcalled[i], ==, MANY - i + 1);
2389e985b929SDavid van Moolenbroek else
2390e985b929SDavid van Moolenbroek tt_int_op(xcalled[i], ==, 1);
2391e985b929SDavid van Moolenbroek }
2392e985b929SDavid van Moolenbroek
2393e985b929SDavid van Moolenbroek end:
2394e985b929SDavid van Moolenbroek for (i = 0; i < MANY; ++i) {
2395e985b929SDavid van Moolenbroek if (ev[i])
2396e985b929SDavid van Moolenbroek event_free(ev[i]);
2397e985b929SDavid van Moolenbroek if (sock[i] >= 0)
2398e985b929SDavid van Moolenbroek evutil_closesocket(sock[i]);
2399e985b929SDavid van Moolenbroek }
2400e985b929SDavid van Moolenbroek #undef MANY
2401e985b929SDavid van Moolenbroek }
2402e985b929SDavid van Moolenbroek
2403e985b929SDavid van Moolenbroek static void
test_struct_event_size(void * arg)2404e985b929SDavid van Moolenbroek test_struct_event_size(void *arg)
2405e985b929SDavid van Moolenbroek {
2406e985b929SDavid van Moolenbroek tt_int_op(event_get_struct_event_size(), <=, sizeof(struct event));
2407e985b929SDavid van Moolenbroek end:
2408e985b929SDavid van Moolenbroek ;
2409e985b929SDavid van Moolenbroek }
2410e985b929SDavid van Moolenbroek
2411e985b929SDavid van Moolenbroek struct testcase_t main_testcases[] = {
2412e985b929SDavid van Moolenbroek /* Some converted-over tests */
2413e985b929SDavid van Moolenbroek { "methods", test_methods, TT_FORK, NULL, NULL },
2414e985b929SDavid van Moolenbroek { "version", test_version, 0, NULL, NULL },
2415e985b929SDavid van Moolenbroek BASIC(base_features, TT_FORK|TT_NO_LOGS),
2416e985b929SDavid van Moolenbroek { "base_environ", test_base_environ, TT_FORK, NULL, NULL },
2417e985b929SDavid van Moolenbroek
2418e985b929SDavid van Moolenbroek BASIC(event_base_new, TT_FORK|TT_NEED_SOCKETPAIR),
2419e985b929SDavid van Moolenbroek BASIC(free_active_base, TT_FORK|TT_NEED_SOCKETPAIR),
2420e985b929SDavid van Moolenbroek
2421e985b929SDavid van Moolenbroek BASIC(manipulate_active_events, TT_FORK|TT_NEED_BASE),
2422e985b929SDavid van Moolenbroek
2423e985b929SDavid van Moolenbroek BASIC(bad_assign, TT_FORK|TT_NEED_BASE|TT_NO_LOGS),
2424e985b929SDavid van Moolenbroek BASIC(bad_reentrant, TT_FORK|TT_NEED_BASE|TT_NO_LOGS),
2425e985b929SDavid van Moolenbroek
2426e985b929SDavid van Moolenbroek LEGACY(persistent_timeout, TT_FORK|TT_NEED_BASE),
2427e985b929SDavid van Moolenbroek { "persistent_timeout_jump", test_persistent_timeout_jump, TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
2428e985b929SDavid van Moolenbroek { "persistent_active_timeout", test_persistent_active_timeout,
2429e985b929SDavid van Moolenbroek TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
2430e985b929SDavid van Moolenbroek LEGACY(priorities, TT_FORK|TT_NEED_BASE),
2431e985b929SDavid van Moolenbroek BASIC(priority_active_inversion, TT_FORK|TT_NEED_BASE),
2432e985b929SDavid van Moolenbroek { "common_timeout", test_common_timeout, TT_FORK|TT_NEED_BASE,
2433e985b929SDavid van Moolenbroek &basic_setup, NULL },
2434e985b929SDavid van Moolenbroek
2435e985b929SDavid van Moolenbroek /* These legacy tests may not all need all of these flags. */
2436e985b929SDavid van Moolenbroek LEGACY(simpleread, TT_ISOLATED),
2437e985b929SDavid van Moolenbroek LEGACY(simpleread_multiple, TT_ISOLATED),
2438e985b929SDavid van Moolenbroek LEGACY(simplewrite, TT_ISOLATED),
2439e985b929SDavid van Moolenbroek { "simpleclose", test_simpleclose, TT_FORK, &basic_setup,
2440e985b929SDavid van Moolenbroek NULL },
2441e985b929SDavid van Moolenbroek LEGACY(multiple, TT_ISOLATED),
2442e985b929SDavid van Moolenbroek LEGACY(persistent, TT_ISOLATED),
2443e985b929SDavid van Moolenbroek LEGACY(combined, TT_ISOLATED),
2444e985b929SDavid van Moolenbroek LEGACY(simpletimeout, TT_ISOLATED),
2445e985b929SDavid van Moolenbroek LEGACY(loopbreak, TT_ISOLATED),
2446e985b929SDavid van Moolenbroek LEGACY(loopexit, TT_ISOLATED),
2447e985b929SDavid van Moolenbroek LEGACY(loopexit_multiple, TT_ISOLATED),
2448e985b929SDavid van Moolenbroek LEGACY(nonpersist_readd, TT_ISOLATED),
2449e985b929SDavid van Moolenbroek LEGACY(multiple_events_for_same_fd, TT_ISOLATED),
2450e985b929SDavid van Moolenbroek LEGACY(want_only_once, TT_ISOLATED),
2451e985b929SDavid van Moolenbroek { "event_once", test_event_once, TT_ISOLATED, &basic_setup, NULL },
2452e985b929SDavid van Moolenbroek { "event_pending", test_event_pending, TT_ISOLATED, &basic_setup,
2453e985b929SDavid van Moolenbroek NULL },
2454e985b929SDavid van Moolenbroek #ifndef WIN32
2455e985b929SDavid van Moolenbroek { "dup_fd", test_dup_fd, TT_ISOLATED, &basic_setup, NULL },
2456e985b929SDavid van Moolenbroek #endif
2457e985b929SDavid van Moolenbroek { "mm_functions", test_mm_functions, TT_FORK, NULL, NULL },
2458e985b929SDavid van Moolenbroek { "many_events", test_many_events, TT_ISOLATED, &basic_setup, NULL },
2459e985b929SDavid van Moolenbroek { "many_events_slow_add", test_many_events, TT_ISOLATED, &basic_setup, (void*)1 },
2460e985b929SDavid van Moolenbroek
2461e985b929SDavid van Moolenbroek { "struct_event_size", test_struct_event_size, 0, NULL, NULL },
2462e985b929SDavid van Moolenbroek
2463e985b929SDavid van Moolenbroek #ifndef WIN32
2464e985b929SDavid van Moolenbroek LEGACY(fork, TT_ISOLATED),
2465e985b929SDavid van Moolenbroek #endif
2466e985b929SDavid van Moolenbroek END_OF_TESTCASES
2467e985b929SDavid van Moolenbroek };
2468e985b929SDavid van Moolenbroek
2469e985b929SDavid van Moolenbroek struct testcase_t evtag_testcases[] = {
2470e985b929SDavid van Moolenbroek { "int", evtag_int_test, TT_FORK, NULL, NULL },
2471e985b929SDavid van Moolenbroek { "fuzz", evtag_fuzz, TT_FORK, NULL, NULL },
2472e985b929SDavid van Moolenbroek { "encoding", evtag_tag_encoding, TT_FORK, NULL, NULL },
2473e985b929SDavid van Moolenbroek { "peek", evtag_test_peek, 0, NULL, NULL },
2474e985b929SDavid van Moolenbroek
2475e985b929SDavid van Moolenbroek END_OF_TESTCASES
2476e985b929SDavid van Moolenbroek };
2477e985b929SDavid van Moolenbroek
2478e985b929SDavid van Moolenbroek struct testcase_t signal_testcases[] = {
2479e985b929SDavid van Moolenbroek #ifndef WIN32
2480e985b929SDavid van Moolenbroek LEGACY(simplesignal, TT_ISOLATED),
2481e985b929SDavid van Moolenbroek LEGACY(multiplesignal, TT_ISOLATED),
2482e985b929SDavid van Moolenbroek LEGACY(immediatesignal, TT_ISOLATED),
2483e985b929SDavid van Moolenbroek LEGACY(signal_dealloc, TT_ISOLATED),
2484e985b929SDavid van Moolenbroek LEGACY(signal_pipeloss, TT_ISOLATED),
2485e985b929SDavid van Moolenbroek LEGACY(signal_switchbase, TT_ISOLATED|TT_NO_LOGS),
2486e985b929SDavid van Moolenbroek LEGACY(signal_restore, TT_ISOLATED),
2487e985b929SDavid van Moolenbroek LEGACY(signal_assert, TT_ISOLATED),
2488e985b929SDavid van Moolenbroek LEGACY(signal_while_processing, TT_ISOLATED),
2489e985b929SDavid van Moolenbroek #endif
2490e985b929SDavid van Moolenbroek END_OF_TESTCASES
2491e985b929SDavid van Moolenbroek };
2492e985b929SDavid van Moolenbroek
2493