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