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