1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/third_party/libevent/test/regress.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,2489 @@ 1.4 +/* 1.5 + * Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu> 1.6 + * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson 1.7 + * 1.8 + * Redistribution and use in source and binary forms, with or without 1.9 + * modification, are permitted provided that the following conditions 1.10 + * are met: 1.11 + * 1. Redistributions of source code must retain the above copyright 1.12 + * notice, this list of conditions and the following disclaimer. 1.13 + * 2. Redistributions in binary form must reproduce the above copyright 1.14 + * notice, this list of conditions and the following disclaimer in the 1.15 + * documentation and/or other materials provided with the distribution. 1.16 + * 3. The name of the author may not be used to endorse or promote products 1.17 + * derived from this software without specific prior written permission. 1.18 + * 1.19 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1.20 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1.21 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1.22 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1.23 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 1.24 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.25 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.26 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.27 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 1.28 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.29 + */ 1.30 + 1.31 +#ifdef WIN32 1.32 +#include <winsock2.h> 1.33 +#include <windows.h> 1.34 +#endif 1.35 + 1.36 +#include "event2/event-config.h" 1.37 + 1.38 +#include <sys/types.h> 1.39 +#include <sys/stat.h> 1.40 +#ifdef _EVENT_HAVE_SYS_TIME_H 1.41 +#include <sys/time.h> 1.42 +#endif 1.43 +#include <sys/queue.h> 1.44 +#ifndef WIN32 1.45 +#include <sys/socket.h> 1.46 +#include <sys/wait.h> 1.47 +#include <signal.h> 1.48 +#include <unistd.h> 1.49 +#include <netdb.h> 1.50 +#endif 1.51 +#include <fcntl.h> 1.52 +#include <signal.h> 1.53 +#include <stdlib.h> 1.54 +#include <stdio.h> 1.55 +#include <string.h> 1.56 +#include <errno.h> 1.57 +#include <assert.h> 1.58 +#include <ctype.h> 1.59 + 1.60 +#include "event2/event.h" 1.61 +#include "event2/event_struct.h" 1.62 +#include "event2/event_compat.h" 1.63 +#include "event2/tag.h" 1.64 +#include "event2/buffer.h" 1.65 +#include "event2/buffer_compat.h" 1.66 +#include "event2/util.h" 1.67 +#include "event-internal.h" 1.68 +#include "evthread-internal.h" 1.69 +#include "util-internal.h" 1.70 +#include "log-internal.h" 1.71 + 1.72 +#include "regress.h" 1.73 + 1.74 +#ifndef WIN32 1.75 +#include "regress.gen.h" 1.76 +#endif 1.77 + 1.78 +evutil_socket_t pair[2]; 1.79 +int test_ok; 1.80 +int called; 1.81 +struct event_base *global_base; 1.82 + 1.83 +static char wbuf[4096]; 1.84 +static char rbuf[4096]; 1.85 +static int woff; 1.86 +static int roff; 1.87 +static int usepersist; 1.88 +static struct timeval tset; 1.89 +static struct timeval tcalled; 1.90 + 1.91 + 1.92 +#define TEST1 "this is a test" 1.93 +#define SECONDS 1 1.94 + 1.95 +#ifndef SHUT_WR 1.96 +#define SHUT_WR 1 1.97 +#endif 1.98 + 1.99 +#ifdef WIN32 1.100 +#define write(fd,buf,len) send((fd),(buf),(int)(len),0) 1.101 +#define read(fd,buf,len) recv((fd),(buf),(int)(len),0) 1.102 +#endif 1.103 + 1.104 +struct basic_cb_args 1.105 +{ 1.106 + struct event_base *eb; 1.107 + struct event *ev; 1.108 + unsigned int callcount; 1.109 +}; 1.110 + 1.111 +static void 1.112 +simple_read_cb(evutil_socket_t fd, short event, void *arg) 1.113 +{ 1.114 + char buf[256]; 1.115 + int len; 1.116 + 1.117 + len = read(fd, buf, sizeof(buf)); 1.118 + 1.119 + if (len) { 1.120 + if (!called) { 1.121 + if (event_add(arg, NULL) == -1) 1.122 + exit(1); 1.123 + } 1.124 + } else if (called == 1) 1.125 + test_ok = 1; 1.126 + 1.127 + called++; 1.128 +} 1.129 + 1.130 +static void 1.131 +basic_read_cb(evutil_socket_t fd, short event, void *data) 1.132 +{ 1.133 + char buf[256]; 1.134 + int len; 1.135 + struct basic_cb_args *arg = data; 1.136 + 1.137 + len = read(fd, buf, sizeof(buf)); 1.138 + 1.139 + if (len < 0) { 1.140 + tt_fail_perror("read (callback)"); 1.141 + } else { 1.142 + switch (arg->callcount++) { 1.143 + case 0: /* first call: expect to read data; cycle */ 1.144 + if (len > 0) 1.145 + return; 1.146 + 1.147 + tt_fail_msg("EOF before data read"); 1.148 + break; 1.149 + 1.150 + case 1: /* second call: expect EOF; stop */ 1.151 + if (len > 0) 1.152 + tt_fail_msg("not all data read on first cycle"); 1.153 + break; 1.154 + 1.155 + default: /* third call: should not happen */ 1.156 + tt_fail_msg("too many cycles"); 1.157 + } 1.158 + } 1.159 + 1.160 + event_del(arg->ev); 1.161 + event_base_loopexit(arg->eb, NULL); 1.162 +} 1.163 + 1.164 +static void 1.165 +dummy_read_cb(evutil_socket_t fd, short event, void *arg) 1.166 +{ 1.167 +} 1.168 + 1.169 +static void 1.170 +simple_write_cb(evutil_socket_t fd, short event, void *arg) 1.171 +{ 1.172 + int len; 1.173 + 1.174 + len = write(fd, TEST1, strlen(TEST1) + 1); 1.175 + if (len == -1) 1.176 + test_ok = 0; 1.177 + else 1.178 + test_ok = 1; 1.179 +} 1.180 + 1.181 +static void 1.182 +multiple_write_cb(evutil_socket_t fd, short event, void *arg) 1.183 +{ 1.184 + struct event *ev = arg; 1.185 + int len; 1.186 + 1.187 + len = 128; 1.188 + if (woff + len >= (int)sizeof(wbuf)) 1.189 + len = sizeof(wbuf) - woff; 1.190 + 1.191 + len = write(fd, wbuf + woff, len); 1.192 + if (len == -1) { 1.193 + fprintf(stderr, "%s: write\n", __func__); 1.194 + if (usepersist) 1.195 + event_del(ev); 1.196 + return; 1.197 + } 1.198 + 1.199 + woff += len; 1.200 + 1.201 + if (woff >= (int)sizeof(wbuf)) { 1.202 + shutdown(fd, SHUT_WR); 1.203 + if (usepersist) 1.204 + event_del(ev); 1.205 + return; 1.206 + } 1.207 + 1.208 + if (!usepersist) { 1.209 + if (event_add(ev, NULL) == -1) 1.210 + exit(1); 1.211 + } 1.212 +} 1.213 + 1.214 +static void 1.215 +multiple_read_cb(evutil_socket_t fd, short event, void *arg) 1.216 +{ 1.217 + struct event *ev = arg; 1.218 + int len; 1.219 + 1.220 + len = read(fd, rbuf + roff, sizeof(rbuf) - roff); 1.221 + if (len == -1) 1.222 + fprintf(stderr, "%s: read\n", __func__); 1.223 + if (len <= 0) { 1.224 + if (usepersist) 1.225 + event_del(ev); 1.226 + return; 1.227 + } 1.228 + 1.229 + roff += len; 1.230 + if (!usepersist) { 1.231 + if (event_add(ev, NULL) == -1) 1.232 + exit(1); 1.233 + } 1.234 +} 1.235 + 1.236 +static void 1.237 +timeout_cb(evutil_socket_t fd, short event, void *arg) 1.238 +{ 1.239 + struct timeval tv; 1.240 + int diff; 1.241 + 1.242 + evutil_gettimeofday(&tcalled, NULL); 1.243 + if (evutil_timercmp(&tcalled, &tset, >)) 1.244 + evutil_timersub(&tcalled, &tset, &tv); 1.245 + else 1.246 + evutil_timersub(&tset, &tcalled, &tv); 1.247 + 1.248 + diff = tv.tv_sec*1000 + tv.tv_usec/1000 - SECONDS * 1000; 1.249 + if (diff < 0) 1.250 + diff = -diff; 1.251 + 1.252 + if (diff < 100) 1.253 + test_ok = 1; 1.254 +} 1.255 + 1.256 +struct both { 1.257 + struct event ev; 1.258 + int nread; 1.259 +}; 1.260 + 1.261 +static void 1.262 +combined_read_cb(evutil_socket_t fd, short event, void *arg) 1.263 +{ 1.264 + struct both *both = arg; 1.265 + char buf[128]; 1.266 + int len; 1.267 + 1.268 + len = read(fd, buf, sizeof(buf)); 1.269 + if (len == -1) 1.270 + fprintf(stderr, "%s: read\n", __func__); 1.271 + if (len <= 0) 1.272 + return; 1.273 + 1.274 + both->nread += len; 1.275 + if (event_add(&both->ev, NULL) == -1) 1.276 + exit(1); 1.277 +} 1.278 + 1.279 +static void 1.280 +combined_write_cb(evutil_socket_t fd, short event, void *arg) 1.281 +{ 1.282 + struct both *both = arg; 1.283 + char buf[128]; 1.284 + int len; 1.285 + 1.286 + len = sizeof(buf); 1.287 + if (len > both->nread) 1.288 + len = both->nread; 1.289 + 1.290 + memset(buf, 'q', len); 1.291 + 1.292 + len = write(fd, buf, len); 1.293 + if (len == -1) 1.294 + fprintf(stderr, "%s: write\n", __func__); 1.295 + if (len <= 0) { 1.296 + shutdown(fd, SHUT_WR); 1.297 + return; 1.298 + } 1.299 + 1.300 + both->nread -= len; 1.301 + if (event_add(&both->ev, NULL) == -1) 1.302 + exit(1); 1.303 +} 1.304 + 1.305 +/* These macros used to replicate the work of the legacy test wrapper code */ 1.306 +#define setup_test(x) do { \ 1.307 + if (!in_legacy_test_wrapper) { \ 1.308 + TT_FAIL(("Legacy test %s not wrapped properly", x)); \ 1.309 + return; \ 1.310 + } \ 1.311 + } while (0) 1.312 +#define cleanup_test() setup_test("cleanup") 1.313 + 1.314 +static void 1.315 +test_simpleread(void) 1.316 +{ 1.317 + struct event ev; 1.318 + 1.319 + /* Very simple read test */ 1.320 + setup_test("Simple read: "); 1.321 + 1.322 + if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) { 1.323 + tt_fail_perror("write"); 1.324 + } 1.325 + 1.326 + shutdown(pair[0], SHUT_WR); 1.327 + 1.328 + event_set(&ev, pair[1], EV_READ, simple_read_cb, &ev); 1.329 + if (event_add(&ev, NULL) == -1) 1.330 + exit(1); 1.331 + event_dispatch(); 1.332 + 1.333 + cleanup_test(); 1.334 +} 1.335 + 1.336 +static void 1.337 +test_simplewrite(void) 1.338 +{ 1.339 + struct event ev; 1.340 + 1.341 + /* Very simple write test */ 1.342 + setup_test("Simple write: "); 1.343 + 1.344 + event_set(&ev, pair[0], EV_WRITE, simple_write_cb, &ev); 1.345 + if (event_add(&ev, NULL) == -1) 1.346 + exit(1); 1.347 + event_dispatch(); 1.348 + 1.349 + cleanup_test(); 1.350 +} 1.351 + 1.352 +static void 1.353 +simpleread_multiple_cb(evutil_socket_t fd, short event, void *arg) 1.354 +{ 1.355 + if (++called == 2) 1.356 + test_ok = 1; 1.357 +} 1.358 + 1.359 +static void 1.360 +test_simpleread_multiple(void) 1.361 +{ 1.362 + struct event one, two; 1.363 + 1.364 + /* Very simple read test */ 1.365 + setup_test("Simple read to multiple evens: "); 1.366 + 1.367 + if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) { 1.368 + tt_fail_perror("write"); 1.369 + } 1.370 + 1.371 + shutdown(pair[0], SHUT_WR); 1.372 + 1.373 + event_set(&one, pair[1], EV_READ, simpleread_multiple_cb, NULL); 1.374 + if (event_add(&one, NULL) == -1) 1.375 + exit(1); 1.376 + event_set(&two, pair[1], EV_READ, simpleread_multiple_cb, NULL); 1.377 + if (event_add(&two, NULL) == -1) 1.378 + exit(1); 1.379 + event_dispatch(); 1.380 + 1.381 + cleanup_test(); 1.382 +} 1.383 + 1.384 +static int have_closed = 0; 1.385 +static int premature_event = 0; 1.386 +static void 1.387 +simpleclose_close_fd_cb(evutil_socket_t s, short what, void *ptr) 1.388 +{ 1.389 + evutil_socket_t **fds = ptr; 1.390 + TT_BLATHER(("Closing")); 1.391 + evutil_closesocket(*fds[0]); 1.392 + evutil_closesocket(*fds[1]); 1.393 + *fds[0] = -1; 1.394 + *fds[1] = -1; 1.395 + have_closed = 1; 1.396 +} 1.397 + 1.398 +static void 1.399 +record_event_cb(evutil_socket_t s, short what, void *ptr) 1.400 +{ 1.401 + short *whatp = ptr; 1.402 + if (!have_closed) 1.403 + premature_event = 1; 1.404 + *whatp = what; 1.405 + TT_BLATHER(("Recorded %d on socket %d", (int)what, (int)s)); 1.406 +} 1.407 + 1.408 +static void 1.409 +test_simpleclose(void *ptr) 1.410 +{ 1.411 + /* Test that a close of FD is detected as a read and as a write. */ 1.412 + struct event_base *base = event_base_new(); 1.413 + evutil_socket_t pair1[2]={-1,-1}, pair2[2] = {-1, -1}; 1.414 + evutil_socket_t *to_close[2]; 1.415 + struct event *rev=NULL, *wev=NULL, *closeev=NULL; 1.416 + struct timeval tv; 1.417 + short got_read_on_close = 0, got_write_on_close = 0; 1.418 + char buf[1024]; 1.419 + memset(buf, 99, sizeof(buf)); 1.420 +#ifdef WIN32 1.421 +#define LOCAL_SOCKETPAIR_AF AF_INET 1.422 +#else 1.423 +#define LOCAL_SOCKETPAIR_AF AF_UNIX 1.424 +#endif 1.425 + if (evutil_socketpair(LOCAL_SOCKETPAIR_AF, SOCK_STREAM, 0, pair1)<0) 1.426 + TT_DIE(("socketpair: %s", strerror(errno))); 1.427 + if (evutil_socketpair(LOCAL_SOCKETPAIR_AF, SOCK_STREAM, 0, pair2)<0) 1.428 + TT_DIE(("socketpair: %s", strerror(errno))); 1.429 + if (evutil_make_socket_nonblocking(pair1[1]) < 0) 1.430 + TT_DIE(("make_socket_nonblocking")); 1.431 + if (evutil_make_socket_nonblocking(pair2[1]) < 0) 1.432 + TT_DIE(("make_socket_nonblocking")); 1.433 + 1.434 + /** Stuff pair2[1] full of data, until write fails */ 1.435 + while (1) { 1.436 + int r = write(pair2[1], buf, sizeof(buf)); 1.437 + if (r<0) { 1.438 + int err = evutil_socket_geterror(pair2[1]); 1.439 + if (! EVUTIL_ERR_RW_RETRIABLE(err)) 1.440 + TT_DIE(("write failed strangely: %s", 1.441 + evutil_socket_error_to_string(err))); 1.442 + break; 1.443 + } 1.444 + } 1.445 + to_close[0] = &pair1[0]; 1.446 + to_close[1] = &pair2[0]; 1.447 + 1.448 + closeev = event_new(base, -1, EV_TIMEOUT, simpleclose_close_fd_cb, 1.449 + to_close); 1.450 + rev = event_new(base, pair1[1], EV_READ, record_event_cb, 1.451 + &got_read_on_close); 1.452 + TT_BLATHER(("Waiting for read on %d", (int)pair1[1])); 1.453 + wev = event_new(base, pair2[1], EV_WRITE, record_event_cb, 1.454 + &got_write_on_close); 1.455 + TT_BLATHER(("Waiting for write on %d", (int)pair2[1])); 1.456 + tv.tv_sec = 0; 1.457 + tv.tv_usec = 100*1000; /* Close pair1[0] after a little while, and make 1.458 + * sure we get a read event. */ 1.459 + event_add(closeev, &tv); 1.460 + event_add(rev, NULL); 1.461 + event_add(wev, NULL); 1.462 + /* Don't let the test go on too long. */ 1.463 + tv.tv_sec = 0; 1.464 + tv.tv_usec = 200*1000; 1.465 + event_base_loopexit(base, &tv); 1.466 + event_base_loop(base, 0); 1.467 + 1.468 + tt_int_op(got_read_on_close, ==, EV_READ); 1.469 + tt_int_op(got_write_on_close, ==, EV_WRITE); 1.470 + tt_int_op(premature_event, ==, 0); 1.471 + 1.472 +end: 1.473 + if (pair1[0] >= 0) 1.474 + evutil_closesocket(pair1[0]); 1.475 + if (pair1[1] >= 0) 1.476 + evutil_closesocket(pair1[1]); 1.477 + if (pair2[0] >= 0) 1.478 + evutil_closesocket(pair2[0]); 1.479 + if (pair2[1] >= 0) 1.480 + evutil_closesocket(pair2[1]); 1.481 + if (rev) 1.482 + event_free(rev); 1.483 + if (wev) 1.484 + event_free(wev); 1.485 + if (closeev) 1.486 + event_free(closeev); 1.487 + if (base) 1.488 + event_base_free(base); 1.489 +} 1.490 + 1.491 + 1.492 +static void 1.493 +test_multiple(void) 1.494 +{ 1.495 + struct event ev, ev2; 1.496 + int i; 1.497 + 1.498 + /* Multiple read and write test */ 1.499 + setup_test("Multiple read/write: "); 1.500 + memset(rbuf, 0, sizeof(rbuf)); 1.501 + for (i = 0; i < (int)sizeof(wbuf); i++) 1.502 + wbuf[i] = i; 1.503 + 1.504 + roff = woff = 0; 1.505 + usepersist = 0; 1.506 + 1.507 + event_set(&ev, pair[0], EV_WRITE, multiple_write_cb, &ev); 1.508 + if (event_add(&ev, NULL) == -1) 1.509 + exit(1); 1.510 + event_set(&ev2, pair[1], EV_READ, multiple_read_cb, &ev2); 1.511 + if (event_add(&ev2, NULL) == -1) 1.512 + exit(1); 1.513 + event_dispatch(); 1.514 + 1.515 + if (roff == woff) 1.516 + test_ok = memcmp(rbuf, wbuf, sizeof(wbuf)) == 0; 1.517 + 1.518 + cleanup_test(); 1.519 +} 1.520 + 1.521 +static void 1.522 +test_persistent(void) 1.523 +{ 1.524 + struct event ev, ev2; 1.525 + int i; 1.526 + 1.527 + /* Multiple read and write test with persist */ 1.528 + setup_test("Persist read/write: "); 1.529 + memset(rbuf, 0, sizeof(rbuf)); 1.530 + for (i = 0; i < (int)sizeof(wbuf); i++) 1.531 + wbuf[i] = i; 1.532 + 1.533 + roff = woff = 0; 1.534 + usepersist = 1; 1.535 + 1.536 + event_set(&ev, pair[0], EV_WRITE|EV_PERSIST, multiple_write_cb, &ev); 1.537 + if (event_add(&ev, NULL) == -1) 1.538 + exit(1); 1.539 + event_set(&ev2, pair[1], EV_READ|EV_PERSIST, multiple_read_cb, &ev2); 1.540 + if (event_add(&ev2, NULL) == -1) 1.541 + exit(1); 1.542 + event_dispatch(); 1.543 + 1.544 + if (roff == woff) 1.545 + test_ok = memcmp(rbuf, wbuf, sizeof(wbuf)) == 0; 1.546 + 1.547 + cleanup_test(); 1.548 +} 1.549 + 1.550 +static void 1.551 +test_combined(void) 1.552 +{ 1.553 + struct both r1, r2, w1, w2; 1.554 + 1.555 + setup_test("Combined read/write: "); 1.556 + memset(&r1, 0, sizeof(r1)); 1.557 + memset(&r2, 0, sizeof(r2)); 1.558 + memset(&w1, 0, sizeof(w1)); 1.559 + memset(&w2, 0, sizeof(w2)); 1.560 + 1.561 + w1.nread = 4096; 1.562 + w2.nread = 8192; 1.563 + 1.564 + event_set(&r1.ev, pair[0], EV_READ, combined_read_cb, &r1); 1.565 + event_set(&w1.ev, pair[0], EV_WRITE, combined_write_cb, &w1); 1.566 + event_set(&r2.ev, pair[1], EV_READ, combined_read_cb, &r2); 1.567 + event_set(&w2.ev, pair[1], EV_WRITE, combined_write_cb, &w2); 1.568 + tt_assert(event_add(&r1.ev, NULL) != -1); 1.569 + tt_assert(!event_add(&w1.ev, NULL)); 1.570 + tt_assert(!event_add(&r2.ev, NULL)); 1.571 + tt_assert(!event_add(&w2.ev, NULL)); 1.572 + event_dispatch(); 1.573 + 1.574 + if (r1.nread == 8192 && r2.nread == 4096) 1.575 + test_ok = 1; 1.576 + 1.577 +end: 1.578 + cleanup_test(); 1.579 +} 1.580 + 1.581 +static void 1.582 +test_simpletimeout(void) 1.583 +{ 1.584 + struct timeval tv; 1.585 + struct event ev; 1.586 + 1.587 + setup_test("Simple timeout: "); 1.588 + 1.589 + tv.tv_usec = 0; 1.590 + tv.tv_sec = SECONDS; 1.591 + evtimer_set(&ev, timeout_cb, NULL); 1.592 + evtimer_add(&ev, &tv); 1.593 + 1.594 + evutil_gettimeofday(&tset, NULL); 1.595 + event_dispatch(); 1.596 + 1.597 + cleanup_test(); 1.598 +} 1.599 + 1.600 +static void 1.601 +periodic_timeout_cb(evutil_socket_t fd, short event, void *arg) 1.602 +{ 1.603 + int *count = arg; 1.604 + 1.605 + (*count)++; 1.606 + if (*count == 6) { 1.607 + /* call loopexit only once - on slow machines(?), it is 1.608 + * apparently possible for this to get called twice. */ 1.609 + test_ok = 1; 1.610 + event_base_loopexit(global_base, NULL); 1.611 + } 1.612 +} 1.613 + 1.614 +static void 1.615 +test_persistent_timeout(void) 1.616 +{ 1.617 + struct timeval tv; 1.618 + struct event ev; 1.619 + int count = 0; 1.620 + 1.621 + evutil_timerclear(&tv); 1.622 + tv.tv_usec = 10000; 1.623 + 1.624 + event_assign(&ev, global_base, -1, EV_TIMEOUT|EV_PERSIST, 1.625 + periodic_timeout_cb, &count); 1.626 + event_add(&ev, &tv); 1.627 + 1.628 + event_dispatch(); 1.629 + 1.630 + event_del(&ev); 1.631 +} 1.632 + 1.633 +static void 1.634 +test_persistent_timeout_jump(void *ptr) 1.635 +{ 1.636 + struct basic_test_data *data = ptr; 1.637 + struct event ev; 1.638 + int count = 0; 1.639 + struct timeval msec100 = { 0, 100 * 1000 }; 1.640 + struct timeval msec50 = { 0, 50 * 1000 }; 1.641 + 1.642 + event_assign(&ev, data->base, -1, EV_PERSIST, periodic_timeout_cb, &count); 1.643 + event_add(&ev, &msec100); 1.644 + /* Wait for a bit */ 1.645 +#ifdef _WIN32 1.646 + Sleep(1000); 1.647 +#else 1.648 + sleep(1); 1.649 +#endif 1.650 + event_base_loopexit(data->base, &msec50); 1.651 + event_base_dispatch(data->base); 1.652 + tt_int_op(count, ==, 1); 1.653 + 1.654 +end: 1.655 + event_del(&ev); 1.656 +} 1.657 + 1.658 +struct persist_active_timeout_called { 1.659 + int n; 1.660 + short events[16]; 1.661 + struct timeval tvs[16]; 1.662 +}; 1.663 + 1.664 +static void 1.665 +activate_cb(evutil_socket_t fd, short event, void *arg) 1.666 +{ 1.667 + struct event *ev = arg; 1.668 + event_active(ev, EV_READ, 1); 1.669 +} 1.670 + 1.671 +static void 1.672 +persist_active_timeout_cb(evutil_socket_t fd, short event, void *arg) 1.673 +{ 1.674 + struct persist_active_timeout_called *c = arg; 1.675 + if (c->n < 15) { 1.676 + c->events[c->n] = event; 1.677 + evutil_gettimeofday(&c->tvs[c->n], NULL); 1.678 + ++c->n; 1.679 + } 1.680 +} 1.681 + 1.682 +static void 1.683 +test_persistent_active_timeout(void *ptr) 1.684 +{ 1.685 + struct timeval tv, tv2, tv_exit, start; 1.686 + struct event ev; 1.687 + struct persist_active_timeout_called res; 1.688 + 1.689 + struct basic_test_data *data = ptr; 1.690 + struct event_base *base = data->base; 1.691 + 1.692 + memset(&res, 0, sizeof(res)); 1.693 + 1.694 + tv.tv_sec = 0; 1.695 + tv.tv_usec = 200 * 1000; 1.696 + event_assign(&ev, base, -1, EV_TIMEOUT|EV_PERSIST, 1.697 + persist_active_timeout_cb, &res); 1.698 + event_add(&ev, &tv); 1.699 + 1.700 + tv2.tv_sec = 0; 1.701 + tv2.tv_usec = 100 * 1000; 1.702 + event_base_once(base, -1, EV_TIMEOUT, activate_cb, &ev, &tv2); 1.703 + 1.704 + tv_exit.tv_sec = 0; 1.705 + tv_exit.tv_usec = 600 * 1000; 1.706 + event_base_loopexit(base, &tv_exit); 1.707 + 1.708 + event_base_assert_ok(base); 1.709 + evutil_gettimeofday(&start, NULL); 1.710 + 1.711 + event_base_dispatch(base); 1.712 + event_base_assert_ok(base); 1.713 + 1.714 + tt_int_op(res.n, ==, 3); 1.715 + tt_int_op(res.events[0], ==, EV_READ); 1.716 + tt_int_op(res.events[1], ==, EV_TIMEOUT); 1.717 + tt_int_op(res.events[2], ==, EV_TIMEOUT); 1.718 + test_timeval_diff_eq(&start, &res.tvs[0], 100); 1.719 + test_timeval_diff_eq(&start, &res.tvs[1], 300); 1.720 + test_timeval_diff_eq(&start, &res.tvs[2], 500); 1.721 +end: 1.722 + event_del(&ev); 1.723 +} 1.724 + 1.725 +struct common_timeout_info { 1.726 + struct event ev; 1.727 + struct timeval called_at; 1.728 + int which; 1.729 + int count; 1.730 +}; 1.731 + 1.732 +static void 1.733 +common_timeout_cb(evutil_socket_t fd, short event, void *arg) 1.734 +{ 1.735 + struct common_timeout_info *ti = arg; 1.736 + ++ti->count; 1.737 + evutil_gettimeofday(&ti->called_at, NULL); 1.738 + if (ti->count >= 6) 1.739 + event_del(&ti->ev); 1.740 +} 1.741 + 1.742 +static void 1.743 +test_common_timeout(void *ptr) 1.744 +{ 1.745 + struct basic_test_data *data = ptr; 1.746 + 1.747 + struct event_base *base = data->base; 1.748 + int i; 1.749 + struct common_timeout_info info[100]; 1.750 + 1.751 + struct timeval now; 1.752 + struct timeval tmp_100_ms = { 0, 100*1000 }; 1.753 + struct timeval tmp_200_ms = { 0, 200*1000 }; 1.754 + 1.755 + const struct timeval *ms_100, *ms_200; 1.756 + 1.757 + ms_100 = event_base_init_common_timeout(base, &tmp_100_ms); 1.758 + ms_200 = event_base_init_common_timeout(base, &tmp_200_ms); 1.759 + tt_assert(ms_100); 1.760 + tt_assert(ms_200); 1.761 + tt_ptr_op(event_base_init_common_timeout(base, &tmp_200_ms), 1.762 + ==, ms_200); 1.763 + tt_int_op(ms_100->tv_sec, ==, 0); 1.764 + tt_int_op(ms_200->tv_sec, ==, 0); 1.765 + tt_int_op(ms_100->tv_usec, ==, 100000|0x50000000); 1.766 + tt_int_op(ms_200->tv_usec, ==, 200000|0x50100000); 1.767 + 1.768 + memset(info, 0, sizeof(info)); 1.769 + 1.770 + for (i=0; i<100; ++i) { 1.771 + info[i].which = i; 1.772 + event_assign(&info[i].ev, base, -1, EV_TIMEOUT|EV_PERSIST, 1.773 + common_timeout_cb, &info[i]); 1.774 + if (i % 2) { 1.775 + event_add(&info[i].ev, ms_100); 1.776 + } else { 1.777 + event_add(&info[i].ev, ms_200); 1.778 + } 1.779 + } 1.780 + 1.781 + event_base_assert_ok(base); 1.782 + event_base_dispatch(base); 1.783 + 1.784 + evutil_gettimeofday(&now, NULL); 1.785 + event_base_assert_ok(base); 1.786 + 1.787 + for (i=0; i<10; ++i) { 1.788 + struct timeval tmp; 1.789 + int ms_diff; 1.790 + tt_int_op(info[i].count, ==, 6); 1.791 + evutil_timersub(&now, &info[i].called_at, &tmp); 1.792 + ms_diff = tmp.tv_usec/1000 + tmp.tv_sec*1000; 1.793 + if (i % 2) { 1.794 + tt_int_op(ms_diff, >, 500); 1.795 + tt_int_op(ms_diff, <, 700); 1.796 + } else { 1.797 + tt_int_op(ms_diff, >, -100); 1.798 + tt_int_op(ms_diff, <, 100); 1.799 + } 1.800 + } 1.801 + 1.802 + /* Make sure we can free the base with some events in. */ 1.803 + for (i=0; i<100; ++i) { 1.804 + if (i % 2) { 1.805 + event_add(&info[i].ev, ms_100); 1.806 + } else { 1.807 + event_add(&info[i].ev, ms_200); 1.808 + } 1.809 + } 1.810 + 1.811 +end: 1.812 + event_base_free(data->base); /* need to do this here before info is 1.813 + * out-of-scope */ 1.814 + data->base = NULL; 1.815 +} 1.816 + 1.817 +#ifndef WIN32 1.818 +static void signal_cb(evutil_socket_t fd, short event, void *arg); 1.819 + 1.820 +#define current_base event_global_current_base_ 1.821 +extern struct event_base *current_base; 1.822 + 1.823 +static void 1.824 +child_signal_cb(evutil_socket_t fd, short event, void *arg) 1.825 +{ 1.826 + struct timeval tv; 1.827 + int *pint = arg; 1.828 + 1.829 + *pint = 1; 1.830 + 1.831 + tv.tv_usec = 500000; 1.832 + tv.tv_sec = 0; 1.833 + event_loopexit(&tv); 1.834 +} 1.835 + 1.836 +static void 1.837 +test_fork(void) 1.838 +{ 1.839 + int status, got_sigchld = 0; 1.840 + struct event ev, sig_ev; 1.841 + pid_t pid; 1.842 + 1.843 + setup_test("After fork: "); 1.844 + 1.845 + tt_assert(current_base); 1.846 + evthread_make_base_notifiable(current_base); 1.847 + 1.848 + if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) { 1.849 + tt_fail_perror("write"); 1.850 + } 1.851 + 1.852 + event_set(&ev, pair[1], EV_READ, simple_read_cb, &ev); 1.853 + if (event_add(&ev, NULL) == -1) 1.854 + exit(1); 1.855 + 1.856 + evsignal_set(&sig_ev, SIGCHLD, child_signal_cb, &got_sigchld); 1.857 + evsignal_add(&sig_ev, NULL); 1.858 + 1.859 + event_base_assert_ok(current_base); 1.860 + TT_BLATHER(("Before fork")); 1.861 + if ((pid = regress_fork()) == 0) { 1.862 + /* in the child */ 1.863 + TT_BLATHER(("In child, before reinit")); 1.864 + event_base_assert_ok(current_base); 1.865 + if (event_reinit(current_base) == -1) { 1.866 + fprintf(stdout, "FAILED (reinit)\n"); 1.867 + exit(1); 1.868 + } 1.869 + TT_BLATHER(("After reinit")); 1.870 + event_base_assert_ok(current_base); 1.871 + TT_BLATHER(("After assert-ok")); 1.872 + 1.873 + evsignal_del(&sig_ev); 1.874 + 1.875 + called = 0; 1.876 + 1.877 + event_dispatch(); 1.878 + 1.879 + event_base_free(current_base); 1.880 + 1.881 + /* we do not send an EOF; simple_read_cb requires an EOF 1.882 + * to set test_ok. we just verify that the callback was 1.883 + * called. */ 1.884 + exit(test_ok != 0 || called != 2 ? -2 : 76); 1.885 + } 1.886 + 1.887 + /* wait for the child to read the data */ 1.888 + sleep(1); 1.889 + 1.890 + if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) { 1.891 + tt_fail_perror("write"); 1.892 + } 1.893 + 1.894 + TT_BLATHER(("Before waitpid")); 1.895 + if (waitpid(pid, &status, 0) == -1) { 1.896 + fprintf(stdout, "FAILED (fork)\n"); 1.897 + exit(1); 1.898 + } 1.899 + TT_BLATHER(("After waitpid")); 1.900 + 1.901 + if (WEXITSTATUS(status) != 76) { 1.902 + fprintf(stdout, "FAILED (exit): %d\n", WEXITSTATUS(status)); 1.903 + exit(1); 1.904 + } 1.905 + 1.906 + /* test that the current event loop still works */ 1.907 + if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) { 1.908 + fprintf(stderr, "%s: write\n", __func__); 1.909 + } 1.910 + 1.911 + shutdown(pair[0], SHUT_WR); 1.912 + 1.913 + event_dispatch(); 1.914 + 1.915 + if (!got_sigchld) { 1.916 + fprintf(stdout, "FAILED (sigchld)\n"); 1.917 + exit(1); 1.918 + } 1.919 + 1.920 + evsignal_del(&sig_ev); 1.921 + 1.922 + end: 1.923 + cleanup_test(); 1.924 +} 1.925 + 1.926 +static void 1.927 +signal_cb_sa(int sig) 1.928 +{ 1.929 + test_ok = 2; 1.930 +} 1.931 + 1.932 +static void 1.933 +signal_cb(evutil_socket_t fd, short event, void *arg) 1.934 +{ 1.935 + struct event *ev = arg; 1.936 + 1.937 + evsignal_del(ev); 1.938 + test_ok = 1; 1.939 +} 1.940 + 1.941 +static void 1.942 +test_simplesignal(void) 1.943 +{ 1.944 + struct event ev; 1.945 + struct itimerval itv; 1.946 + 1.947 + setup_test("Simple signal: "); 1.948 + evsignal_set(&ev, SIGALRM, signal_cb, &ev); 1.949 + evsignal_add(&ev, NULL); 1.950 + /* find bugs in which operations are re-ordered */ 1.951 + evsignal_del(&ev); 1.952 + evsignal_add(&ev, NULL); 1.953 + 1.954 + memset(&itv, 0, sizeof(itv)); 1.955 + itv.it_value.tv_sec = 1; 1.956 + if (setitimer(ITIMER_REAL, &itv, NULL) == -1) 1.957 + goto skip_simplesignal; 1.958 + 1.959 + event_dispatch(); 1.960 + skip_simplesignal: 1.961 + if (evsignal_del(&ev) == -1) 1.962 + test_ok = 0; 1.963 + 1.964 + cleanup_test(); 1.965 +} 1.966 + 1.967 +static void 1.968 +test_multiplesignal(void) 1.969 +{ 1.970 + struct event ev_one, ev_two; 1.971 + struct itimerval itv; 1.972 + 1.973 + setup_test("Multiple signal: "); 1.974 + 1.975 + evsignal_set(&ev_one, SIGALRM, signal_cb, &ev_one); 1.976 + evsignal_add(&ev_one, NULL); 1.977 + 1.978 + evsignal_set(&ev_two, SIGALRM, signal_cb, &ev_two); 1.979 + evsignal_add(&ev_two, NULL); 1.980 + 1.981 + memset(&itv, 0, sizeof(itv)); 1.982 + itv.it_value.tv_sec = 1; 1.983 + if (setitimer(ITIMER_REAL, &itv, NULL) == -1) 1.984 + goto skip_simplesignal; 1.985 + 1.986 + event_dispatch(); 1.987 + 1.988 + skip_simplesignal: 1.989 + if (evsignal_del(&ev_one) == -1) 1.990 + test_ok = 0; 1.991 + if (evsignal_del(&ev_two) == -1) 1.992 + test_ok = 0; 1.993 + 1.994 + cleanup_test(); 1.995 +} 1.996 + 1.997 +static void 1.998 +test_immediatesignal(void) 1.999 +{ 1.1000 + struct event ev; 1.1001 + 1.1002 + test_ok = 0; 1.1003 + evsignal_set(&ev, SIGUSR1, signal_cb, &ev); 1.1004 + evsignal_add(&ev, NULL); 1.1005 + raise(SIGUSR1); 1.1006 + event_loop(EVLOOP_NONBLOCK); 1.1007 + evsignal_del(&ev); 1.1008 + cleanup_test(); 1.1009 +} 1.1010 + 1.1011 +static void 1.1012 +test_signal_dealloc(void) 1.1013 +{ 1.1014 + /* make sure that evsignal_event is event_del'ed and pipe closed */ 1.1015 + struct event ev; 1.1016 + struct event_base *base = event_init(); 1.1017 + evsignal_set(&ev, SIGUSR1, signal_cb, &ev); 1.1018 + evsignal_add(&ev, NULL); 1.1019 + evsignal_del(&ev); 1.1020 + event_base_free(base); 1.1021 + /* If we got here without asserting, we're fine. */ 1.1022 + test_ok = 1; 1.1023 + cleanup_test(); 1.1024 +} 1.1025 + 1.1026 +static void 1.1027 +test_signal_pipeloss(void) 1.1028 +{ 1.1029 + /* make sure that the base1 pipe is closed correctly. */ 1.1030 + struct event_base *base1, *base2; 1.1031 + int pipe1; 1.1032 + test_ok = 0; 1.1033 + base1 = event_init(); 1.1034 + pipe1 = base1->sig.ev_signal_pair[0]; 1.1035 + base2 = event_init(); 1.1036 + event_base_free(base2); 1.1037 + event_base_free(base1); 1.1038 + if (close(pipe1) != -1 || errno!=EBADF) { 1.1039 + /* fd must be closed, so second close gives -1, EBADF */ 1.1040 + printf("signal pipe not closed. "); 1.1041 + test_ok = 0; 1.1042 + } else { 1.1043 + test_ok = 1; 1.1044 + } 1.1045 + cleanup_test(); 1.1046 +} 1.1047 + 1.1048 +/* 1.1049 + * make two bases to catch signals, use both of them. this only works 1.1050 + * for event mechanisms that use our signal pipe trick. kqueue handles 1.1051 + * signals internally, and all interested kqueues get all the signals. 1.1052 + */ 1.1053 +static void 1.1054 +test_signal_switchbase(void) 1.1055 +{ 1.1056 + struct event ev1, ev2; 1.1057 + struct event_base *base1, *base2; 1.1058 + int is_kqueue; 1.1059 + test_ok = 0; 1.1060 + base1 = event_init(); 1.1061 + base2 = event_init(); 1.1062 + is_kqueue = !strcmp(event_get_method(),"kqueue"); 1.1063 + evsignal_set(&ev1, SIGUSR1, signal_cb, &ev1); 1.1064 + evsignal_set(&ev2, SIGUSR1, signal_cb, &ev2); 1.1065 + if (event_base_set(base1, &ev1) || 1.1066 + event_base_set(base2, &ev2) || 1.1067 + event_add(&ev1, NULL) || 1.1068 + event_add(&ev2, NULL)) { 1.1069 + fprintf(stderr, "%s: cannot set base, add\n", __func__); 1.1070 + exit(1); 1.1071 + } 1.1072 + 1.1073 + tt_ptr_op(event_get_base(&ev1), ==, base1); 1.1074 + tt_ptr_op(event_get_base(&ev2), ==, base2); 1.1075 + 1.1076 + test_ok = 0; 1.1077 + /* can handle signal before loop is called */ 1.1078 + raise(SIGUSR1); 1.1079 + event_base_loop(base2, EVLOOP_NONBLOCK); 1.1080 + if (is_kqueue) { 1.1081 + if (!test_ok) 1.1082 + goto end; 1.1083 + test_ok = 0; 1.1084 + } 1.1085 + event_base_loop(base1, EVLOOP_NONBLOCK); 1.1086 + if (test_ok && !is_kqueue) { 1.1087 + test_ok = 0; 1.1088 + 1.1089 + /* set base1 to handle signals */ 1.1090 + event_base_loop(base1, EVLOOP_NONBLOCK); 1.1091 + raise(SIGUSR1); 1.1092 + event_base_loop(base1, EVLOOP_NONBLOCK); 1.1093 + event_base_loop(base2, EVLOOP_NONBLOCK); 1.1094 + } 1.1095 +end: 1.1096 + event_base_free(base1); 1.1097 + event_base_free(base2); 1.1098 + cleanup_test(); 1.1099 +} 1.1100 + 1.1101 +/* 1.1102 + * assert that a signal event removed from the event queue really is 1.1103 + * removed - with no possibility of it's parent handler being fired. 1.1104 + */ 1.1105 +static void 1.1106 +test_signal_assert(void) 1.1107 +{ 1.1108 + struct event ev; 1.1109 + struct event_base *base = event_init(); 1.1110 + test_ok = 0; 1.1111 + /* use SIGCONT so we don't kill ourselves when we signal to nowhere */ 1.1112 + evsignal_set(&ev, SIGCONT, signal_cb, &ev); 1.1113 + evsignal_add(&ev, NULL); 1.1114 + /* 1.1115 + * if evsignal_del() fails to reset the handler, it's current handler 1.1116 + * will still point to evsig_handler(). 1.1117 + */ 1.1118 + evsignal_del(&ev); 1.1119 + 1.1120 + raise(SIGCONT); 1.1121 +#if 0 1.1122 + /* only way to verify we were in evsig_handler() */ 1.1123 + /* XXXX Now there's no longer a good way. */ 1.1124 + if (base->sig.evsig_caught) 1.1125 + test_ok = 0; 1.1126 + else 1.1127 + test_ok = 1; 1.1128 +#else 1.1129 + test_ok = 1; 1.1130 +#endif 1.1131 + 1.1132 + event_base_free(base); 1.1133 + cleanup_test(); 1.1134 + return; 1.1135 +} 1.1136 + 1.1137 +/* 1.1138 + * assert that we restore our previous signal handler properly. 1.1139 + */ 1.1140 +static void 1.1141 +test_signal_restore(void) 1.1142 +{ 1.1143 + struct event ev; 1.1144 + struct event_base *base = event_init(); 1.1145 +#ifdef _EVENT_HAVE_SIGACTION 1.1146 + struct sigaction sa; 1.1147 +#endif 1.1148 + 1.1149 + test_ok = 0; 1.1150 +#ifdef _EVENT_HAVE_SIGACTION 1.1151 + sa.sa_handler = signal_cb_sa; 1.1152 + sa.sa_flags = 0x0; 1.1153 + sigemptyset(&sa.sa_mask); 1.1154 + if (sigaction(SIGUSR1, &sa, NULL) == -1) 1.1155 + goto out; 1.1156 +#else 1.1157 + if (signal(SIGUSR1, signal_cb_sa) == SIG_ERR) 1.1158 + goto out; 1.1159 +#endif 1.1160 + evsignal_set(&ev, SIGUSR1, signal_cb, &ev); 1.1161 + evsignal_add(&ev, NULL); 1.1162 + evsignal_del(&ev); 1.1163 + 1.1164 + raise(SIGUSR1); 1.1165 + /* 1 == signal_cb, 2 == signal_cb_sa, we want our previous handler */ 1.1166 + if (test_ok != 2) 1.1167 + test_ok = 0; 1.1168 +out: 1.1169 + event_base_free(base); 1.1170 + cleanup_test(); 1.1171 + return; 1.1172 +} 1.1173 + 1.1174 +static void 1.1175 +signal_cb_swp(int sig, short event, void *arg) 1.1176 +{ 1.1177 + called++; 1.1178 + if (called < 5) 1.1179 + raise(sig); 1.1180 + else 1.1181 + event_loopexit(NULL); 1.1182 +} 1.1183 +static void 1.1184 +timeout_cb_swp(evutil_socket_t fd, short event, void *arg) 1.1185 +{ 1.1186 + if (called == -1) { 1.1187 + struct timeval tv = {5, 0}; 1.1188 + 1.1189 + called = 0; 1.1190 + evtimer_add((struct event *)arg, &tv); 1.1191 + raise(SIGUSR1); 1.1192 + return; 1.1193 + } 1.1194 + test_ok = 0; 1.1195 + event_loopexit(NULL); 1.1196 +} 1.1197 + 1.1198 +static void 1.1199 +test_signal_while_processing(void) 1.1200 +{ 1.1201 + struct event_base *base = event_init(); 1.1202 + struct event ev, ev_timer; 1.1203 + struct timeval tv = {0, 0}; 1.1204 + 1.1205 + setup_test("Receiving a signal while processing other signal: "); 1.1206 + 1.1207 + called = -1; 1.1208 + test_ok = 1; 1.1209 + signal_set(&ev, SIGUSR1, signal_cb_swp, NULL); 1.1210 + signal_add(&ev, NULL); 1.1211 + evtimer_set(&ev_timer, timeout_cb_swp, &ev_timer); 1.1212 + evtimer_add(&ev_timer, &tv); 1.1213 + event_dispatch(); 1.1214 + 1.1215 + event_base_free(base); 1.1216 + cleanup_test(); 1.1217 + return; 1.1218 +} 1.1219 +#endif 1.1220 + 1.1221 +static void 1.1222 +test_free_active_base(void *ptr) 1.1223 +{ 1.1224 + struct basic_test_data *data = ptr; 1.1225 + struct event_base *base1; 1.1226 + struct event ev1; 1.1227 + 1.1228 + base1 = event_init(); 1.1229 + if (base1) { 1.1230 + event_assign(&ev1, base1, data->pair[1], EV_READ, 1.1231 + dummy_read_cb, NULL); 1.1232 + event_add(&ev1, NULL); 1.1233 + event_base_free(base1); /* should not crash */ 1.1234 + } else { 1.1235 + tt_fail_msg("failed to create event_base for test"); 1.1236 + } 1.1237 + 1.1238 + base1 = event_init(); 1.1239 + tt_assert(base1); 1.1240 + event_assign(&ev1, base1, 0, 0, dummy_read_cb, NULL); 1.1241 + event_active(&ev1, EV_READ, 1); 1.1242 + event_base_free(base1); 1.1243 +end: 1.1244 + ; 1.1245 +} 1.1246 + 1.1247 +static void 1.1248 +test_manipulate_active_events(void *ptr) 1.1249 +{ 1.1250 + struct basic_test_data *data = ptr; 1.1251 + struct event_base *base = data->base; 1.1252 + struct event ev1; 1.1253 + 1.1254 + event_assign(&ev1, base, -1, EV_TIMEOUT, dummy_read_cb, NULL); 1.1255 + 1.1256 + /* Make sure an active event is pending. */ 1.1257 + event_active(&ev1, EV_READ, 1); 1.1258 + tt_int_op(event_pending(&ev1, EV_READ|EV_TIMEOUT|EV_WRITE, NULL), 1.1259 + ==, EV_READ); 1.1260 + 1.1261 + /* Make sure that activating an event twice works. */ 1.1262 + event_active(&ev1, EV_WRITE, 1); 1.1263 + tt_int_op(event_pending(&ev1, EV_READ|EV_TIMEOUT|EV_WRITE, NULL), 1.1264 + ==, EV_READ|EV_WRITE); 1.1265 + 1.1266 +end: 1.1267 + event_del(&ev1); 1.1268 +} 1.1269 + 1.1270 +static void 1.1271 +test_bad_assign(void *ptr) 1.1272 +{ 1.1273 + struct event ev; 1.1274 + int r; 1.1275 + /* READ|SIGNAL is not allowed */ 1.1276 + r = event_assign(&ev, NULL, -1, EV_SIGNAL|EV_READ, dummy_read_cb, NULL); 1.1277 + tt_int_op(r,==,-1); 1.1278 + 1.1279 +end: 1.1280 + ; 1.1281 +} 1.1282 + 1.1283 +static int reentrant_cb_run = 0; 1.1284 + 1.1285 +static void 1.1286 +bad_reentrant_run_loop_cb(evutil_socket_t fd, short what, void *ptr) 1.1287 +{ 1.1288 + struct event_base *base = ptr; 1.1289 + int r; 1.1290 + reentrant_cb_run = 1; 1.1291 + /* This reentrant call to event_base_loop should be detected and 1.1292 + * should fail */ 1.1293 + r = event_base_loop(base, 0); 1.1294 + tt_int_op(r, ==, -1); 1.1295 +end: 1.1296 + ; 1.1297 +} 1.1298 + 1.1299 +static void 1.1300 +test_bad_reentrant(void *ptr) 1.1301 +{ 1.1302 + struct basic_test_data *data = ptr; 1.1303 + struct event_base *base = data->base; 1.1304 + struct event ev; 1.1305 + int r; 1.1306 + event_assign(&ev, base, -1, 1.1307 + 0, bad_reentrant_run_loop_cb, base); 1.1308 + 1.1309 + event_active(&ev, EV_WRITE, 1); 1.1310 + r = event_base_loop(base, 0); 1.1311 + tt_int_op(r, ==, 1); 1.1312 + tt_int_op(reentrant_cb_run, ==, 1); 1.1313 +end: 1.1314 + ; 1.1315 +} 1.1316 + 1.1317 +static void 1.1318 +test_event_base_new(void *ptr) 1.1319 +{ 1.1320 + struct basic_test_data *data = ptr; 1.1321 + struct event_base *base = 0; 1.1322 + struct event ev1; 1.1323 + struct basic_cb_args args; 1.1324 + 1.1325 + int towrite = (int)strlen(TEST1)+1; 1.1326 + int len = write(data->pair[0], TEST1, towrite); 1.1327 + 1.1328 + if (len < 0) 1.1329 + tt_abort_perror("initial write"); 1.1330 + else if (len != towrite) 1.1331 + tt_abort_printf(("initial write fell short (%d of %d bytes)", 1.1332 + len, towrite)); 1.1333 + 1.1334 + if (shutdown(data->pair[0], SHUT_WR)) 1.1335 + tt_abort_perror("initial write shutdown"); 1.1336 + 1.1337 + base = event_base_new(); 1.1338 + if (!base) 1.1339 + tt_abort_msg("failed to create event base"); 1.1340 + 1.1341 + args.eb = base; 1.1342 + args.ev = &ev1; 1.1343 + args.callcount = 0; 1.1344 + event_assign(&ev1, base, data->pair[1], 1.1345 + EV_READ|EV_PERSIST, basic_read_cb, &args); 1.1346 + 1.1347 + if (event_add(&ev1, NULL)) 1.1348 + tt_abort_perror("initial event_add"); 1.1349 + 1.1350 + if (event_base_loop(base, 0)) 1.1351 + tt_abort_msg("unsuccessful exit from event loop"); 1.1352 + 1.1353 +end: 1.1354 + if (base) 1.1355 + event_base_free(base); 1.1356 +} 1.1357 + 1.1358 +static void 1.1359 +test_loopexit(void) 1.1360 +{ 1.1361 + struct timeval tv, tv_start, tv_end; 1.1362 + struct event ev; 1.1363 + 1.1364 + setup_test("Loop exit: "); 1.1365 + 1.1366 + tv.tv_usec = 0; 1.1367 + tv.tv_sec = 60*60*24; 1.1368 + evtimer_set(&ev, timeout_cb, NULL); 1.1369 + evtimer_add(&ev, &tv); 1.1370 + 1.1371 + tv.tv_usec = 0; 1.1372 + tv.tv_sec = 1; 1.1373 + event_loopexit(&tv); 1.1374 + 1.1375 + evutil_gettimeofday(&tv_start, NULL); 1.1376 + event_dispatch(); 1.1377 + evutil_gettimeofday(&tv_end, NULL); 1.1378 + evutil_timersub(&tv_end, &tv_start, &tv_end); 1.1379 + 1.1380 + evtimer_del(&ev); 1.1381 + 1.1382 + tt_assert(event_base_got_exit(global_base)); 1.1383 + tt_assert(!event_base_got_break(global_base)); 1.1384 + 1.1385 + if (tv.tv_sec < 2) 1.1386 + test_ok = 1; 1.1387 + 1.1388 +end: 1.1389 + cleanup_test(); 1.1390 +} 1.1391 + 1.1392 +static void 1.1393 +test_loopexit_multiple(void) 1.1394 +{ 1.1395 + struct timeval tv; 1.1396 + struct event_base *base; 1.1397 + 1.1398 + setup_test("Loop Multiple exit: "); 1.1399 + 1.1400 + base = event_base_new(); 1.1401 + 1.1402 + tv.tv_usec = 0; 1.1403 + tv.tv_sec = 1; 1.1404 + event_base_loopexit(base, &tv); 1.1405 + 1.1406 + tv.tv_usec = 0; 1.1407 + tv.tv_sec = 2; 1.1408 + event_base_loopexit(base, &tv); 1.1409 + 1.1410 + event_base_dispatch(base); 1.1411 + 1.1412 + tt_assert(event_base_got_exit(base)); 1.1413 + tt_assert(!event_base_got_break(base)); 1.1414 + 1.1415 + event_base_free(base); 1.1416 + 1.1417 + test_ok = 1; 1.1418 + 1.1419 +end: 1.1420 + cleanup_test(); 1.1421 +} 1.1422 + 1.1423 +static void 1.1424 +break_cb(evutil_socket_t fd, short events, void *arg) 1.1425 +{ 1.1426 + test_ok = 1; 1.1427 + event_loopbreak(); 1.1428 +} 1.1429 + 1.1430 +static void 1.1431 +fail_cb(evutil_socket_t fd, short events, void *arg) 1.1432 +{ 1.1433 + test_ok = 0; 1.1434 +} 1.1435 + 1.1436 +static void 1.1437 +test_loopbreak(void) 1.1438 +{ 1.1439 + struct event ev1, ev2; 1.1440 + struct timeval tv; 1.1441 + 1.1442 + setup_test("Loop break: "); 1.1443 + 1.1444 + tv.tv_sec = 0; 1.1445 + tv.tv_usec = 0; 1.1446 + evtimer_set(&ev1, break_cb, NULL); 1.1447 + evtimer_add(&ev1, &tv); 1.1448 + evtimer_set(&ev2, fail_cb, NULL); 1.1449 + evtimer_add(&ev2, &tv); 1.1450 + 1.1451 + event_dispatch(); 1.1452 + 1.1453 + tt_assert(!event_base_got_exit(global_base)); 1.1454 + tt_assert(event_base_got_break(global_base)); 1.1455 + 1.1456 + evtimer_del(&ev1); 1.1457 + evtimer_del(&ev2); 1.1458 + 1.1459 +end: 1.1460 + cleanup_test(); 1.1461 +} 1.1462 + 1.1463 +static struct event *readd_test_event_last_added = NULL; 1.1464 +static void 1.1465 +re_add_read_cb(evutil_socket_t fd, short event, void *arg) 1.1466 +{ 1.1467 + char buf[256]; 1.1468 + struct event *ev_other = arg; 1.1469 + readd_test_event_last_added = ev_other; 1.1470 + 1.1471 + if (read(fd, buf, sizeof(buf)) < 0) { 1.1472 + tt_fail_perror("read"); 1.1473 + } 1.1474 + 1.1475 + event_add(ev_other, NULL); 1.1476 + ++test_ok; 1.1477 +} 1.1478 + 1.1479 +static void 1.1480 +test_nonpersist_readd(void) 1.1481 +{ 1.1482 + struct event ev1, ev2; 1.1483 + 1.1484 + setup_test("Re-add nonpersistent events: "); 1.1485 + event_set(&ev1, pair[0], EV_READ, re_add_read_cb, &ev2); 1.1486 + event_set(&ev2, pair[1], EV_READ, re_add_read_cb, &ev1); 1.1487 + 1.1488 + if (write(pair[0], "Hello", 5) < 0) { 1.1489 + tt_fail_perror("write(pair[0])"); 1.1490 + } 1.1491 + 1.1492 + if (write(pair[1], "Hello", 5) < 0) { 1.1493 + tt_fail_perror("write(pair[1])\n"); 1.1494 + } 1.1495 + 1.1496 + if (event_add(&ev1, NULL) == -1 || 1.1497 + event_add(&ev2, NULL) == -1) { 1.1498 + test_ok = 0; 1.1499 + } 1.1500 + if (test_ok != 0) 1.1501 + exit(1); 1.1502 + event_loop(EVLOOP_ONCE); 1.1503 + if (test_ok != 2) 1.1504 + exit(1); 1.1505 + /* At this point, we executed both callbacks. Whichever one got 1.1506 + * called first added the second, but the second then immediately got 1.1507 + * deleted before its callback was called. At this point, though, it 1.1508 + * re-added the first. 1.1509 + */ 1.1510 + if (!readd_test_event_last_added) { 1.1511 + test_ok = 0; 1.1512 + } else if (readd_test_event_last_added == &ev1) { 1.1513 + if (!event_pending(&ev1, EV_READ, NULL) || 1.1514 + event_pending(&ev2, EV_READ, NULL)) 1.1515 + test_ok = 0; 1.1516 + } else { 1.1517 + if (event_pending(&ev1, EV_READ, NULL) || 1.1518 + !event_pending(&ev2, EV_READ, NULL)) 1.1519 + test_ok = 0; 1.1520 + } 1.1521 + 1.1522 + event_del(&ev1); 1.1523 + event_del(&ev2); 1.1524 + 1.1525 + cleanup_test(); 1.1526 +} 1.1527 + 1.1528 +struct test_pri_event { 1.1529 + struct event ev; 1.1530 + int count; 1.1531 +}; 1.1532 + 1.1533 +static void 1.1534 +test_priorities_cb(evutil_socket_t fd, short what, void *arg) 1.1535 +{ 1.1536 + struct test_pri_event *pri = arg; 1.1537 + struct timeval tv; 1.1538 + 1.1539 + if (pri->count == 3) { 1.1540 + event_loopexit(NULL); 1.1541 + return; 1.1542 + } 1.1543 + 1.1544 + pri->count++; 1.1545 + 1.1546 + evutil_timerclear(&tv); 1.1547 + event_add(&pri->ev, &tv); 1.1548 +} 1.1549 + 1.1550 +static void 1.1551 +test_priorities_impl(int npriorities) 1.1552 +{ 1.1553 + struct test_pri_event one, two; 1.1554 + struct timeval tv; 1.1555 + 1.1556 + TT_BLATHER(("Testing Priorities %d: ", npriorities)); 1.1557 + 1.1558 + event_base_priority_init(global_base, npriorities); 1.1559 + 1.1560 + memset(&one, 0, sizeof(one)); 1.1561 + memset(&two, 0, sizeof(two)); 1.1562 + 1.1563 + timeout_set(&one.ev, test_priorities_cb, &one); 1.1564 + if (event_priority_set(&one.ev, 0) == -1) { 1.1565 + fprintf(stderr, "%s: failed to set priority", __func__); 1.1566 + exit(1); 1.1567 + } 1.1568 + 1.1569 + timeout_set(&two.ev, test_priorities_cb, &two); 1.1570 + if (event_priority_set(&two.ev, npriorities - 1) == -1) { 1.1571 + fprintf(stderr, "%s: failed to set priority", __func__); 1.1572 + exit(1); 1.1573 + } 1.1574 + 1.1575 + evutil_timerclear(&tv); 1.1576 + 1.1577 + if (event_add(&one.ev, &tv) == -1) 1.1578 + exit(1); 1.1579 + if (event_add(&two.ev, &tv) == -1) 1.1580 + exit(1); 1.1581 + 1.1582 + event_dispatch(); 1.1583 + 1.1584 + event_del(&one.ev); 1.1585 + event_del(&two.ev); 1.1586 + 1.1587 + if (npriorities == 1) { 1.1588 + if (one.count == 3 && two.count == 3) 1.1589 + test_ok = 1; 1.1590 + } else if (npriorities == 2) { 1.1591 + /* Two is called once because event_loopexit is priority 1 */ 1.1592 + if (one.count == 3 && two.count == 1) 1.1593 + test_ok = 1; 1.1594 + } else { 1.1595 + if (one.count == 3 && two.count == 0) 1.1596 + test_ok = 1; 1.1597 + } 1.1598 +} 1.1599 + 1.1600 +static void 1.1601 +test_priorities(void) 1.1602 +{ 1.1603 + test_priorities_impl(1); 1.1604 + if (test_ok) 1.1605 + test_priorities_impl(2); 1.1606 + if (test_ok) 1.1607 + test_priorities_impl(3); 1.1608 +} 1.1609 + 1.1610 +/* priority-active-inversion: activate a higher-priority event, and make sure 1.1611 + * it keeps us from running a lower-priority event first. */ 1.1612 +static int n_pai_calls = 0; 1.1613 +static struct event pai_events[3]; 1.1614 + 1.1615 +static void 1.1616 +prio_active_inversion_cb(evutil_socket_t fd, short what, void *arg) 1.1617 +{ 1.1618 + int *call_order = arg; 1.1619 + *call_order = n_pai_calls++; 1.1620 + if (n_pai_calls == 1) { 1.1621 + /* This should activate later, even though it shares a 1.1622 + priority with us. */ 1.1623 + event_active(&pai_events[1], EV_READ, 1); 1.1624 + /* This should activate next, since its priority is higher, 1.1625 + even though we activated it second. */ 1.1626 + event_active(&pai_events[2], EV_TIMEOUT, 1); 1.1627 + } 1.1628 +} 1.1629 + 1.1630 +static void 1.1631 +test_priority_active_inversion(void *data_) 1.1632 +{ 1.1633 + struct basic_test_data *data = data_; 1.1634 + struct event_base *base = data->base; 1.1635 + int call_order[3]; 1.1636 + int i; 1.1637 + tt_int_op(event_base_priority_init(base, 8), ==, 0); 1.1638 + 1.1639 + n_pai_calls = 0; 1.1640 + memset(call_order, 0, sizeof(call_order)); 1.1641 + 1.1642 + for (i=0;i<3;++i) { 1.1643 + event_assign(&pai_events[i], data->base, -1, 0, 1.1644 + prio_active_inversion_cb, &call_order[i]); 1.1645 + } 1.1646 + 1.1647 + event_priority_set(&pai_events[0], 4); 1.1648 + event_priority_set(&pai_events[1], 4); 1.1649 + event_priority_set(&pai_events[2], 0); 1.1650 + 1.1651 + event_active(&pai_events[0], EV_WRITE, 1); 1.1652 + 1.1653 + event_base_dispatch(base); 1.1654 + tt_int_op(n_pai_calls, ==, 3); 1.1655 + tt_int_op(call_order[0], ==, 0); 1.1656 + tt_int_op(call_order[1], ==, 2); 1.1657 + tt_int_op(call_order[2], ==, 1); 1.1658 +end: 1.1659 + ; 1.1660 +} 1.1661 + 1.1662 + 1.1663 +static void 1.1664 +test_multiple_cb(evutil_socket_t fd, short event, void *arg) 1.1665 +{ 1.1666 + if (event & EV_READ) 1.1667 + test_ok |= 1; 1.1668 + else if (event & EV_WRITE) 1.1669 + test_ok |= 2; 1.1670 +} 1.1671 + 1.1672 +static void 1.1673 +test_multiple_events_for_same_fd(void) 1.1674 +{ 1.1675 + struct event e1, e2; 1.1676 + 1.1677 + setup_test("Multiple events for same fd: "); 1.1678 + 1.1679 + event_set(&e1, pair[0], EV_READ, test_multiple_cb, NULL); 1.1680 + event_add(&e1, NULL); 1.1681 + event_set(&e2, pair[0], EV_WRITE, test_multiple_cb, NULL); 1.1682 + event_add(&e2, NULL); 1.1683 + event_loop(EVLOOP_ONCE); 1.1684 + event_del(&e2); 1.1685 + 1.1686 + if (write(pair[1], TEST1, strlen(TEST1)+1) < 0) { 1.1687 + tt_fail_perror("write"); 1.1688 + } 1.1689 + 1.1690 + event_loop(EVLOOP_ONCE); 1.1691 + event_del(&e1); 1.1692 + 1.1693 + if (test_ok != 3) 1.1694 + test_ok = 0; 1.1695 + 1.1696 + cleanup_test(); 1.1697 +} 1.1698 + 1.1699 +int evtag_decode_int(ev_uint32_t *pnumber, struct evbuffer *evbuf); 1.1700 +int evtag_decode_int64(ev_uint64_t *pnumber, struct evbuffer *evbuf); 1.1701 +int evtag_encode_tag(struct evbuffer *evbuf, ev_uint32_t number); 1.1702 +int evtag_decode_tag(ev_uint32_t *pnumber, struct evbuffer *evbuf); 1.1703 + 1.1704 +static void 1.1705 +read_once_cb(evutil_socket_t fd, short event, void *arg) 1.1706 +{ 1.1707 + char buf[256]; 1.1708 + int len; 1.1709 + 1.1710 + len = read(fd, buf, sizeof(buf)); 1.1711 + 1.1712 + if (called) { 1.1713 + test_ok = 0; 1.1714 + } else if (len) { 1.1715 + /* Assumes global pair[0] can be used for writing */ 1.1716 + if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) { 1.1717 + tt_fail_perror("write"); 1.1718 + test_ok = 0; 1.1719 + } else { 1.1720 + test_ok = 1; 1.1721 + } 1.1722 + } 1.1723 + 1.1724 + called++; 1.1725 +} 1.1726 + 1.1727 +static void 1.1728 +test_want_only_once(void) 1.1729 +{ 1.1730 + struct event ev; 1.1731 + struct timeval tv; 1.1732 + 1.1733 + /* Very simple read test */ 1.1734 + setup_test("Want read only once: "); 1.1735 + 1.1736 + if (write(pair[0], TEST1, strlen(TEST1)+1) < 0) { 1.1737 + tt_fail_perror("write"); 1.1738 + } 1.1739 + 1.1740 + /* Setup the loop termination */ 1.1741 + evutil_timerclear(&tv); 1.1742 + tv.tv_sec = 1; 1.1743 + event_loopexit(&tv); 1.1744 + 1.1745 + event_set(&ev, pair[1], EV_READ, read_once_cb, &ev); 1.1746 + if (event_add(&ev, NULL) == -1) 1.1747 + exit(1); 1.1748 + event_dispatch(); 1.1749 + 1.1750 + cleanup_test(); 1.1751 +} 1.1752 + 1.1753 +#define TEST_MAX_INT 6 1.1754 + 1.1755 +static void 1.1756 +evtag_int_test(void *ptr) 1.1757 +{ 1.1758 + struct evbuffer *tmp = evbuffer_new(); 1.1759 + ev_uint32_t integers[TEST_MAX_INT] = { 1.1760 + 0xaf0, 0x1000, 0x1, 0xdeadbeef, 0x00, 0xbef000 1.1761 + }; 1.1762 + ev_uint32_t integer; 1.1763 + ev_uint64_t big_int; 1.1764 + int i; 1.1765 + 1.1766 + evtag_init(); 1.1767 + 1.1768 + for (i = 0; i < TEST_MAX_INT; i++) { 1.1769 + int oldlen, newlen; 1.1770 + oldlen = (int)EVBUFFER_LENGTH(tmp); 1.1771 + evtag_encode_int(tmp, integers[i]); 1.1772 + newlen = (int)EVBUFFER_LENGTH(tmp); 1.1773 + TT_BLATHER(("encoded 0x%08x with %d bytes", 1.1774 + (unsigned)integers[i], newlen - oldlen)); 1.1775 + big_int = integers[i]; 1.1776 + big_int *= 1000000000; /* 1 billion */ 1.1777 + evtag_encode_int64(tmp, big_int); 1.1778 + } 1.1779 + 1.1780 + for (i = 0; i < TEST_MAX_INT; i++) { 1.1781 + tt_int_op(evtag_decode_int(&integer, tmp), !=, -1); 1.1782 + tt_uint_op(integer, ==, integers[i]); 1.1783 + tt_int_op(evtag_decode_int64(&big_int, tmp), !=, -1); 1.1784 + tt_assert((big_int / 1000000000) == integers[i]); 1.1785 + } 1.1786 + 1.1787 + tt_uint_op(EVBUFFER_LENGTH(tmp), ==, 0); 1.1788 +end: 1.1789 + evbuffer_free(tmp); 1.1790 +} 1.1791 + 1.1792 +static void 1.1793 +evtag_fuzz(void *ptr) 1.1794 +{ 1.1795 + u_char buffer[4096]; 1.1796 + struct evbuffer *tmp = evbuffer_new(); 1.1797 + struct timeval tv; 1.1798 + int i, j; 1.1799 + 1.1800 + int not_failed = 0; 1.1801 + 1.1802 + evtag_init(); 1.1803 + 1.1804 + for (j = 0; j < 100; j++) { 1.1805 + for (i = 0; i < (int)sizeof(buffer); i++) 1.1806 + buffer[i] = rand(); 1.1807 + evbuffer_drain(tmp, -1); 1.1808 + evbuffer_add(tmp, buffer, sizeof(buffer)); 1.1809 + 1.1810 + if (evtag_unmarshal_timeval(tmp, 0, &tv) != -1) 1.1811 + not_failed++; 1.1812 + } 1.1813 + 1.1814 + /* The majority of decodes should fail */ 1.1815 + tt_int_op(not_failed, <, 10); 1.1816 + 1.1817 + /* Now insert some corruption into the tag length field */ 1.1818 + evbuffer_drain(tmp, -1); 1.1819 + evutil_timerclear(&tv); 1.1820 + tv.tv_sec = 1; 1.1821 + evtag_marshal_timeval(tmp, 0, &tv); 1.1822 + evbuffer_add(tmp, buffer, sizeof(buffer)); 1.1823 + 1.1824 + ((char *)EVBUFFER_DATA(tmp))[1] = '\xff'; 1.1825 + if (evtag_unmarshal_timeval(tmp, 0, &tv) != -1) { 1.1826 + tt_abort_msg("evtag_unmarshal_timeval should have failed"); 1.1827 + } 1.1828 + 1.1829 +end: 1.1830 + evbuffer_free(tmp); 1.1831 +} 1.1832 + 1.1833 +static void 1.1834 +evtag_tag_encoding(void *ptr) 1.1835 +{ 1.1836 + struct evbuffer *tmp = evbuffer_new(); 1.1837 + ev_uint32_t integers[TEST_MAX_INT] = { 1.1838 + 0xaf0, 0x1000, 0x1, 0xdeadbeef, 0x00, 0xbef000 1.1839 + }; 1.1840 + ev_uint32_t integer; 1.1841 + int i; 1.1842 + 1.1843 + evtag_init(); 1.1844 + 1.1845 + for (i = 0; i < TEST_MAX_INT; i++) { 1.1846 + int oldlen, newlen; 1.1847 + oldlen = (int)EVBUFFER_LENGTH(tmp); 1.1848 + evtag_encode_tag(tmp, integers[i]); 1.1849 + newlen = (int)EVBUFFER_LENGTH(tmp); 1.1850 + TT_BLATHER(("encoded 0x%08x with %d bytes", 1.1851 + (unsigned)integers[i], newlen - oldlen)); 1.1852 + } 1.1853 + 1.1854 + for (i = 0; i < TEST_MAX_INT; i++) { 1.1855 + tt_int_op(evtag_decode_tag(&integer, tmp), !=, -1); 1.1856 + tt_uint_op(integer, ==, integers[i]); 1.1857 + } 1.1858 + 1.1859 + tt_uint_op(EVBUFFER_LENGTH(tmp), ==, 0); 1.1860 + 1.1861 +end: 1.1862 + evbuffer_free(tmp); 1.1863 +} 1.1864 + 1.1865 +static void 1.1866 +evtag_test_peek(void *ptr) 1.1867 +{ 1.1868 + struct evbuffer *tmp = evbuffer_new(); 1.1869 + ev_uint32_t u32; 1.1870 + 1.1871 + evtag_marshal_int(tmp, 30, 0); 1.1872 + evtag_marshal_string(tmp, 40, "Hello world"); 1.1873 + 1.1874 + tt_int_op(evtag_peek(tmp, &u32), ==, 1); 1.1875 + tt_int_op(u32, ==, 30); 1.1876 + tt_int_op(evtag_peek_length(tmp, &u32), ==, 0); 1.1877 + tt_int_op(u32, ==, 1+1+1); 1.1878 + tt_int_op(evtag_consume(tmp), ==, 0); 1.1879 + 1.1880 + tt_int_op(evtag_peek(tmp, &u32), ==, 1); 1.1881 + tt_int_op(u32, ==, 40); 1.1882 + tt_int_op(evtag_peek_length(tmp, &u32), ==, 0); 1.1883 + tt_int_op(u32, ==, 1+1+11); 1.1884 + tt_int_op(evtag_payload_length(tmp, &u32), ==, 0); 1.1885 + tt_int_op(u32, ==, 11); 1.1886 + 1.1887 +end: 1.1888 + evbuffer_free(tmp); 1.1889 +} 1.1890 + 1.1891 + 1.1892 +static void 1.1893 +test_methods(void *ptr) 1.1894 +{ 1.1895 + const char **methods = event_get_supported_methods(); 1.1896 + struct event_config *cfg = NULL; 1.1897 + struct event_base *base = NULL; 1.1898 + const char *backend; 1.1899 + int n_methods = 0; 1.1900 + 1.1901 + tt_assert(methods); 1.1902 + 1.1903 + backend = methods[0]; 1.1904 + while (*methods != NULL) { 1.1905 + TT_BLATHER(("Support method: %s", *methods)); 1.1906 + ++methods; 1.1907 + ++n_methods; 1.1908 + } 1.1909 + 1.1910 + cfg = event_config_new(); 1.1911 + assert(cfg != NULL); 1.1912 + 1.1913 + tt_int_op(event_config_avoid_method(cfg, backend), ==, 0); 1.1914 + event_config_set_flag(cfg, EVENT_BASE_FLAG_IGNORE_ENV); 1.1915 + 1.1916 + base = event_base_new_with_config(cfg); 1.1917 + if (n_methods > 1) { 1.1918 + tt_assert(base); 1.1919 + tt_str_op(backend, !=, event_base_get_method(base)); 1.1920 + } else { 1.1921 + tt_assert(base == NULL); 1.1922 + } 1.1923 + 1.1924 +end: 1.1925 + if (base) 1.1926 + event_base_free(base); 1.1927 + if (cfg) 1.1928 + event_config_free(cfg); 1.1929 +} 1.1930 + 1.1931 +static void 1.1932 +test_version(void *arg) 1.1933 +{ 1.1934 + const char *vstr; 1.1935 + ev_uint32_t vint; 1.1936 + int major, minor, patch, n; 1.1937 + 1.1938 + vstr = event_get_version(); 1.1939 + vint = event_get_version_number(); 1.1940 + 1.1941 + tt_assert(vstr); 1.1942 + tt_assert(vint); 1.1943 + 1.1944 + tt_str_op(vstr, ==, LIBEVENT_VERSION); 1.1945 + tt_int_op(vint, ==, LIBEVENT_VERSION_NUMBER); 1.1946 + 1.1947 + n = sscanf(vstr, "%d.%d.%d", &major, &minor, &patch); 1.1948 + tt_assert(3 == n); 1.1949 + tt_int_op((vint&0xffffff00), ==, ((major<<24)|(minor<<16)|(patch<<8))); 1.1950 +end: 1.1951 + ; 1.1952 +} 1.1953 + 1.1954 +static void 1.1955 +test_base_features(void *arg) 1.1956 +{ 1.1957 + struct event_base *base = NULL; 1.1958 + struct event_config *cfg = NULL; 1.1959 + 1.1960 + cfg = event_config_new(); 1.1961 + 1.1962 + tt_assert(0 == event_config_require_features(cfg, EV_FEATURE_ET)); 1.1963 + 1.1964 + base = event_base_new_with_config(cfg); 1.1965 + if (base) { 1.1966 + tt_int_op(EV_FEATURE_ET, ==, 1.1967 + event_base_get_features(base) & EV_FEATURE_ET); 1.1968 + } else { 1.1969 + base = event_base_new(); 1.1970 + tt_int_op(0, ==, event_base_get_features(base) & EV_FEATURE_ET); 1.1971 + } 1.1972 + 1.1973 +end: 1.1974 + if (base) 1.1975 + event_base_free(base); 1.1976 + if (cfg) 1.1977 + event_config_free(cfg); 1.1978 +} 1.1979 + 1.1980 +#ifdef _EVENT_HAVE_SETENV 1.1981 +#define SETENV_OK 1.1982 +#elif !defined(_EVENT_HAVE_SETENV) && defined(_EVENT_HAVE_PUTENV) 1.1983 +static void setenv(const char *k, const char *v, int _o) 1.1984 +{ 1.1985 + char b[256]; 1.1986 + evutil_snprintf(b, sizeof(b), "%s=%s",k,v); 1.1987 + putenv(b); 1.1988 +} 1.1989 +#define SETENV_OK 1.1990 +#endif 1.1991 + 1.1992 +#ifdef _EVENT_HAVE_UNSETENV 1.1993 +#define UNSETENV_OK 1.1994 +#elif !defined(_EVENT_HAVE_UNSETENV) && defined(_EVENT_HAVE_PUTENV) 1.1995 +static void unsetenv(const char *k) 1.1996 +{ 1.1997 + char b[256]; 1.1998 + evutil_snprintf(b, sizeof(b), "%s=",k); 1.1999 + putenv(b); 1.2000 +} 1.2001 +#define UNSETENV_OK 1.2002 +#endif 1.2003 + 1.2004 +#if defined(SETENV_OK) && defined(UNSETENV_OK) 1.2005 +static void 1.2006 +methodname_to_envvar(const char *mname, char *buf, size_t buflen) 1.2007 +{ 1.2008 + char *cp; 1.2009 + evutil_snprintf(buf, buflen, "EVENT_NO%s", mname); 1.2010 + for (cp = buf; *cp; ++cp) { 1.2011 + *cp = EVUTIL_TOUPPER(*cp); 1.2012 + } 1.2013 +} 1.2014 +#endif 1.2015 + 1.2016 +static void 1.2017 +test_base_environ(void *arg) 1.2018 +{ 1.2019 + struct event_base *base = NULL; 1.2020 + struct event_config *cfg = NULL; 1.2021 + 1.2022 +#if defined(SETENV_OK) && defined(UNSETENV_OK) 1.2023 + const char **basenames; 1.2024 + int i, n_methods=0; 1.2025 + char varbuf[128]; 1.2026 + const char *defaultname, *ignoreenvname; 1.2027 + 1.2028 + /* See if unsetenv works before we rely on it. */ 1.2029 + setenv("EVENT_NOWAFFLES", "1", 1); 1.2030 + unsetenv("EVENT_NOWAFFLES"); 1.2031 + if (getenv("EVENT_NOWAFFLES") != NULL) { 1.2032 +#ifndef _EVENT_HAVE_UNSETENV 1.2033 + TT_DECLARE("NOTE", ("Can't fake unsetenv; skipping test")); 1.2034 +#else 1.2035 + TT_DECLARE("NOTE", ("unsetenv doesn't work; skipping test")); 1.2036 +#endif 1.2037 + tt_skip(); 1.2038 + } 1.2039 + 1.2040 + basenames = event_get_supported_methods(); 1.2041 + for (i = 0; basenames[i]; ++i) { 1.2042 + methodname_to_envvar(basenames[i], varbuf, sizeof(varbuf)); 1.2043 + unsetenv(varbuf); 1.2044 + ++n_methods; 1.2045 + } 1.2046 + 1.2047 + base = event_base_new(); 1.2048 + tt_assert(base); 1.2049 + 1.2050 + defaultname = event_base_get_method(base); 1.2051 + TT_BLATHER(("default is <%s>", defaultname)); 1.2052 + event_base_free(base); 1.2053 + base = NULL; 1.2054 + 1.2055 + /* Can we disable the method with EVENT_NOfoo ? */ 1.2056 + if (!strcmp(defaultname, "epoll (with changelist)")) { 1.2057 + setenv("EVENT_NOEPOLL", "1", 1); 1.2058 + ignoreenvname = "epoll"; 1.2059 + } else { 1.2060 + methodname_to_envvar(defaultname, varbuf, sizeof(varbuf)); 1.2061 + setenv(varbuf, "1", 1); 1.2062 + ignoreenvname = defaultname; 1.2063 + } 1.2064 + 1.2065 + /* Use an empty cfg rather than NULL so a failure doesn't exit() */ 1.2066 + cfg = event_config_new(); 1.2067 + base = event_base_new_with_config(cfg); 1.2068 + event_config_free(cfg); 1.2069 + cfg = NULL; 1.2070 + if (n_methods == 1) { 1.2071 + tt_assert(!base); 1.2072 + } else { 1.2073 + tt_assert(base); 1.2074 + tt_str_op(defaultname, !=, event_base_get_method(base)); 1.2075 + event_base_free(base); 1.2076 + base = NULL; 1.2077 + } 1.2078 + 1.2079 + /* Can we disable looking at the environment with IGNORE_ENV ? */ 1.2080 + cfg = event_config_new(); 1.2081 + event_config_set_flag(cfg, EVENT_BASE_FLAG_IGNORE_ENV); 1.2082 + base = event_base_new_with_config(cfg); 1.2083 + tt_assert(base); 1.2084 + tt_str_op(ignoreenvname, ==, event_base_get_method(base)); 1.2085 +#else 1.2086 + tt_skip(); 1.2087 +#endif 1.2088 + 1.2089 +end: 1.2090 + if (base) 1.2091 + event_base_free(base); 1.2092 + if (cfg) 1.2093 + event_config_free(cfg); 1.2094 +} 1.2095 + 1.2096 +static void 1.2097 +read_called_once_cb(evutil_socket_t fd, short event, void *arg) 1.2098 +{ 1.2099 + tt_int_op(event, ==, EV_READ); 1.2100 + called += 1; 1.2101 +end: 1.2102 + ; 1.2103 +} 1.2104 + 1.2105 +static void 1.2106 +timeout_called_once_cb(evutil_socket_t fd, short event, void *arg) 1.2107 +{ 1.2108 + tt_int_op(event, ==, EV_TIMEOUT); 1.2109 + called += 100; 1.2110 +end: 1.2111 + ; 1.2112 +} 1.2113 + 1.2114 +static void 1.2115 +test_event_once(void *ptr) 1.2116 +{ 1.2117 + struct basic_test_data *data = ptr; 1.2118 + struct timeval tv; 1.2119 + int r; 1.2120 + 1.2121 + tv.tv_sec = 0; 1.2122 + tv.tv_usec = 50*1000; 1.2123 + called = 0; 1.2124 + r = event_base_once(data->base, data->pair[0], EV_READ, 1.2125 + read_called_once_cb, NULL, NULL); 1.2126 + tt_int_op(r, ==, 0); 1.2127 + r = event_base_once(data->base, -1, EV_TIMEOUT, 1.2128 + timeout_called_once_cb, NULL, &tv); 1.2129 + tt_int_op(r, ==, 0); 1.2130 + r = event_base_once(data->base, -1, 0, NULL, NULL, NULL); 1.2131 + tt_int_op(r, <, 0); 1.2132 + 1.2133 + if (write(data->pair[1], TEST1, strlen(TEST1)+1) < 0) { 1.2134 + tt_fail_perror("write"); 1.2135 + } 1.2136 + 1.2137 + shutdown(data->pair[1], SHUT_WR); 1.2138 + 1.2139 + event_base_dispatch(data->base); 1.2140 + 1.2141 + tt_int_op(called, ==, 101); 1.2142 +end: 1.2143 + ; 1.2144 +} 1.2145 + 1.2146 +static void 1.2147 +test_event_pending(void *ptr) 1.2148 +{ 1.2149 + struct basic_test_data *data = ptr; 1.2150 + struct event *r=NULL, *w=NULL, *t=NULL; 1.2151 + struct timeval tv, now, tv2, diff; 1.2152 + 1.2153 + tv.tv_sec = 0; 1.2154 + tv.tv_usec = 500 * 1000; 1.2155 + r = event_new(data->base, data->pair[0], EV_READ, simple_read_cb, 1.2156 + NULL); 1.2157 + w = event_new(data->base, data->pair[1], EV_WRITE, simple_write_cb, 1.2158 + NULL); 1.2159 + t = evtimer_new(data->base, timeout_cb, NULL); 1.2160 + 1.2161 + tt_assert(r); 1.2162 + tt_assert(w); 1.2163 + tt_assert(t); 1.2164 + 1.2165 + evutil_gettimeofday(&now, NULL); 1.2166 + event_add(r, NULL); 1.2167 + event_add(t, &tv); 1.2168 + 1.2169 + tt_assert( event_pending(r, EV_READ, NULL)); 1.2170 + tt_assert(!event_pending(w, EV_WRITE, NULL)); 1.2171 + tt_assert(!event_pending(r, EV_WRITE, NULL)); 1.2172 + tt_assert( event_pending(r, EV_READ|EV_WRITE, NULL)); 1.2173 + tt_assert(!event_pending(r, EV_TIMEOUT, NULL)); 1.2174 + tt_assert( event_pending(t, EV_TIMEOUT, NULL)); 1.2175 + tt_assert( event_pending(t, EV_TIMEOUT, &tv2)); 1.2176 + 1.2177 + tt_assert(evutil_timercmp(&tv2, &now, >)); 1.2178 + evutil_timeradd(&now, &tv, &tv); 1.2179 + evutil_timersub(&tv2, &tv, &diff); 1.2180 + tt_int_op(diff.tv_sec, ==, 0); 1.2181 + tt_int_op(labs(diff.tv_usec), <, 1000); 1.2182 + 1.2183 +end: 1.2184 + if (r) { 1.2185 + event_del(r); 1.2186 + event_free(r); 1.2187 + } 1.2188 + if (w) { 1.2189 + event_del(w); 1.2190 + event_free(w); 1.2191 + } 1.2192 + if (t) { 1.2193 + event_del(t); 1.2194 + event_free(t); 1.2195 + } 1.2196 +} 1.2197 + 1.2198 +#ifndef WIN32 1.2199 +/* You can't do this test on windows, since dup2 doesn't work on sockets */ 1.2200 + 1.2201 +static void 1.2202 +dfd_cb(evutil_socket_t fd, short e, void *data) 1.2203 +{ 1.2204 + *(int*)data = (int)e; 1.2205 +} 1.2206 + 1.2207 +/* Regression test for our workaround for a fun epoll/linux related bug 1.2208 + * where fd2 = dup(fd1); add(fd2); close(fd2); dup2(fd1,fd2); add(fd2) 1.2209 + * will get you an EEXIST */ 1.2210 +static void 1.2211 +test_dup_fd(void *arg) 1.2212 +{ 1.2213 + struct basic_test_data *data = arg; 1.2214 + struct event_base *base = data->base; 1.2215 + struct event *ev1=NULL, *ev2=NULL; 1.2216 + int fd, dfd=-1; 1.2217 + int ev1_got, ev2_got; 1.2218 + 1.2219 + tt_int_op(write(data->pair[0], "Hello world", 1.2220 + strlen("Hello world")), >, 0); 1.2221 + fd = data->pair[1]; 1.2222 + 1.2223 + dfd = dup(fd); 1.2224 + tt_int_op(dfd, >=, 0); 1.2225 + 1.2226 + ev1 = event_new(base, fd, EV_READ|EV_PERSIST, dfd_cb, &ev1_got); 1.2227 + ev2 = event_new(base, dfd, EV_READ|EV_PERSIST, dfd_cb, &ev2_got); 1.2228 + ev1_got = ev2_got = 0; 1.2229 + event_add(ev1, NULL); 1.2230 + event_add(ev2, NULL); 1.2231 + event_base_loop(base, EVLOOP_ONCE); 1.2232 + tt_int_op(ev1_got, ==, EV_READ); 1.2233 + tt_int_op(ev2_got, ==, EV_READ); 1.2234 + 1.2235 + /* Now close and delete dfd then dispatch. We need to do the 1.2236 + * dispatch here so that when we add it later, we think there 1.2237 + * was an intermediate delete. */ 1.2238 + close(dfd); 1.2239 + event_del(ev2); 1.2240 + ev1_got = ev2_got = 0; 1.2241 + event_base_loop(base, EVLOOP_ONCE); 1.2242 + tt_want_int_op(ev1_got, ==, EV_READ); 1.2243 + tt_int_op(ev2_got, ==, 0); 1.2244 + 1.2245 + /* Re-duplicate the fd. We need to get the same duplicated 1.2246 + * value that we closed to provoke the epoll quirk. Also, we 1.2247 + * need to change the events to write, or else the old lingering 1.2248 + * read event will make the test pass whether the change was 1.2249 + * successful or not. */ 1.2250 + tt_int_op(dup2(fd, dfd), ==, dfd); 1.2251 + event_free(ev2); 1.2252 + ev2 = event_new(base, dfd, EV_WRITE|EV_PERSIST, dfd_cb, &ev2_got); 1.2253 + event_add(ev2, NULL); 1.2254 + ev1_got = ev2_got = 0; 1.2255 + event_base_loop(base, EVLOOP_ONCE); 1.2256 + tt_want_int_op(ev1_got, ==, EV_READ); 1.2257 + tt_int_op(ev2_got, ==, EV_WRITE); 1.2258 + 1.2259 +end: 1.2260 + if (ev1) 1.2261 + event_free(ev1); 1.2262 + if (ev2) 1.2263 + event_free(ev2); 1.2264 + if (dfd >= 0) 1.2265 + close(dfd); 1.2266 +} 1.2267 +#endif 1.2268 + 1.2269 +#ifdef _EVENT_DISABLE_MM_REPLACEMENT 1.2270 +static void 1.2271 +test_mm_functions(void *arg) 1.2272 +{ 1.2273 + _tinytest_set_test_skipped(); 1.2274 +} 1.2275 +#else 1.2276 +static int 1.2277 +check_dummy_mem_ok(void *_mem) 1.2278 +{ 1.2279 + char *mem = _mem; 1.2280 + mem -= 16; 1.2281 + return !memcmp(mem, "{[<guardedram>]}", 16); 1.2282 +} 1.2283 + 1.2284 +static void * 1.2285 +dummy_malloc(size_t len) 1.2286 +{ 1.2287 + char *mem = malloc(len+16); 1.2288 + memcpy(mem, "{[<guardedram>]}", 16); 1.2289 + return mem+16; 1.2290 +} 1.2291 + 1.2292 +static void * 1.2293 +dummy_realloc(void *_mem, size_t len) 1.2294 +{ 1.2295 + char *mem = _mem; 1.2296 + if (!mem) 1.2297 + return dummy_malloc(len); 1.2298 + tt_want(check_dummy_mem_ok(_mem)); 1.2299 + mem -= 16; 1.2300 + mem = realloc(mem, len+16); 1.2301 + return mem+16; 1.2302 +} 1.2303 + 1.2304 +static void 1.2305 +dummy_free(void *_mem) 1.2306 +{ 1.2307 + char *mem = _mem; 1.2308 + tt_want(check_dummy_mem_ok(_mem)); 1.2309 + mem -= 16; 1.2310 + free(mem); 1.2311 +} 1.2312 + 1.2313 +static void 1.2314 +test_mm_functions(void *arg) 1.2315 +{ 1.2316 + struct event_base *b = NULL; 1.2317 + struct event_config *cfg = NULL; 1.2318 + event_set_mem_functions(dummy_malloc, dummy_realloc, dummy_free); 1.2319 + cfg = event_config_new(); 1.2320 + event_config_avoid_method(cfg, "Nonesuch"); 1.2321 + b = event_base_new_with_config(cfg); 1.2322 + tt_assert(b); 1.2323 + tt_assert(check_dummy_mem_ok(b)); 1.2324 +end: 1.2325 + if (cfg) 1.2326 + event_config_free(cfg); 1.2327 + if (b) 1.2328 + event_base_free(b); 1.2329 +} 1.2330 +#endif 1.2331 + 1.2332 +static void 1.2333 +many_event_cb(evutil_socket_t fd, short event, void *arg) 1.2334 +{ 1.2335 + int *calledp = arg; 1.2336 + *calledp += 1; 1.2337 +} 1.2338 + 1.2339 +static void 1.2340 +test_many_events(void *arg) 1.2341 +{ 1.2342 + /* Try 70 events that should all be ready at once. This will 1.2343 + * exercise the "resize" code on most of the backends, and will make 1.2344 + * sure that we can get past the 64-handle limit of some windows 1.2345 + * functions. */ 1.2346 +#define MANY 70 1.2347 + 1.2348 + struct basic_test_data *data = arg; 1.2349 + struct event_base *base = data->base; 1.2350 + int one_at_a_time = data->setup_data != NULL; 1.2351 + evutil_socket_t sock[MANY]; 1.2352 + struct event *ev[MANY]; 1.2353 + int called[MANY]; 1.2354 + int i; 1.2355 + int loopflags = EVLOOP_NONBLOCK, evflags=0; 1.2356 + const int is_evport = !strcmp(event_base_get_method(base),"evport"); 1.2357 + if (one_at_a_time) { 1.2358 + loopflags |= EVLOOP_ONCE; 1.2359 + evflags = EV_PERSIST; 1.2360 + } 1.2361 + 1.2362 + memset(sock, 0xff, sizeof(sock)); 1.2363 + memset(ev, 0, sizeof(ev)); 1.2364 + memset(called, 0, sizeof(called)); 1.2365 + if (is_evport && one_at_a_time) { 1.2366 + TT_DECLARE("NOTE", ("evport can't pass this in 2.0; skipping\n")); 1.2367 + tt_skip(); 1.2368 + } 1.2369 + 1.2370 + for (i = 0; i < MANY; ++i) { 1.2371 + /* We need an event that will hit the backend, and that will 1.2372 + * be ready immediately. "Send a datagram" is an easy 1.2373 + * instance of that. */ 1.2374 + sock[i] = socket(AF_INET, SOCK_DGRAM, 0); 1.2375 + tt_assert(sock[i] >= 0); 1.2376 + called[i] = 0; 1.2377 + ev[i] = event_new(base, sock[i], EV_WRITE|evflags, 1.2378 + many_event_cb, &called[i]); 1.2379 + event_add(ev[i], NULL); 1.2380 + if (one_at_a_time) 1.2381 + event_base_loop(base, EVLOOP_NONBLOCK|EVLOOP_ONCE); 1.2382 + } 1.2383 + 1.2384 + event_base_loop(base, loopflags); 1.2385 + 1.2386 + for (i = 0; i < MANY; ++i) { 1.2387 + if (one_at_a_time) 1.2388 + tt_int_op(called[i], ==, MANY - i + 1); 1.2389 + else 1.2390 + tt_int_op(called[i], ==, 1); 1.2391 + } 1.2392 + 1.2393 +end: 1.2394 + for (i = 0; i < MANY; ++i) { 1.2395 + if (ev[i]) 1.2396 + event_free(ev[i]); 1.2397 + if (sock[i] >= 0) 1.2398 + evutil_closesocket(sock[i]); 1.2399 + } 1.2400 +#undef MANY 1.2401 +} 1.2402 + 1.2403 +static void 1.2404 +test_struct_event_size(void *arg) 1.2405 +{ 1.2406 + tt_int_op(event_get_struct_event_size(), <=, sizeof(struct event)); 1.2407 +end: 1.2408 + ; 1.2409 +} 1.2410 + 1.2411 +struct testcase_t main_testcases[] = { 1.2412 + /* Some converted-over tests */ 1.2413 + { "methods", test_methods, TT_FORK, NULL, NULL }, 1.2414 + { "version", test_version, 0, NULL, NULL }, 1.2415 + BASIC(base_features, TT_FORK|TT_NO_LOGS), 1.2416 + { "base_environ", test_base_environ, TT_FORK, NULL, NULL }, 1.2417 + 1.2418 + BASIC(event_base_new, TT_FORK|TT_NEED_SOCKETPAIR), 1.2419 + BASIC(free_active_base, TT_FORK|TT_NEED_SOCKETPAIR), 1.2420 + 1.2421 + BASIC(manipulate_active_events, TT_FORK|TT_NEED_BASE), 1.2422 + 1.2423 + BASIC(bad_assign, TT_FORK|TT_NEED_BASE|TT_NO_LOGS), 1.2424 + BASIC(bad_reentrant, TT_FORK|TT_NEED_BASE|TT_NO_LOGS), 1.2425 + 1.2426 + LEGACY(persistent_timeout, TT_FORK|TT_NEED_BASE), 1.2427 + { "persistent_timeout_jump", test_persistent_timeout_jump, TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, 1.2428 + { "persistent_active_timeout", test_persistent_active_timeout, 1.2429 + TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, 1.2430 + LEGACY(priorities, TT_FORK|TT_NEED_BASE), 1.2431 + BASIC(priority_active_inversion, TT_FORK|TT_NEED_BASE), 1.2432 + { "common_timeout", test_common_timeout, TT_FORK|TT_NEED_BASE, 1.2433 + &basic_setup, NULL }, 1.2434 + 1.2435 + /* These legacy tests may not all need all of these flags. */ 1.2436 + LEGACY(simpleread, TT_ISOLATED), 1.2437 + LEGACY(simpleread_multiple, TT_ISOLATED), 1.2438 + LEGACY(simplewrite, TT_ISOLATED), 1.2439 + { "simpleclose", test_simpleclose, TT_FORK, &basic_setup, 1.2440 + NULL }, 1.2441 + LEGACY(multiple, TT_ISOLATED), 1.2442 + LEGACY(persistent, TT_ISOLATED), 1.2443 + LEGACY(combined, TT_ISOLATED), 1.2444 + LEGACY(simpletimeout, TT_ISOLATED), 1.2445 + LEGACY(loopbreak, TT_ISOLATED), 1.2446 + LEGACY(loopexit, TT_ISOLATED), 1.2447 + LEGACY(loopexit_multiple, TT_ISOLATED), 1.2448 + LEGACY(nonpersist_readd, TT_ISOLATED), 1.2449 + LEGACY(multiple_events_for_same_fd, TT_ISOLATED), 1.2450 + LEGACY(want_only_once, TT_ISOLATED), 1.2451 + { "event_once", test_event_once, TT_ISOLATED, &basic_setup, NULL }, 1.2452 + { "event_pending", test_event_pending, TT_ISOLATED, &basic_setup, 1.2453 + NULL }, 1.2454 +#ifndef WIN32 1.2455 + { "dup_fd", test_dup_fd, TT_ISOLATED, &basic_setup, NULL }, 1.2456 +#endif 1.2457 + { "mm_functions", test_mm_functions, TT_FORK, NULL, NULL }, 1.2458 + { "many_events", test_many_events, TT_ISOLATED, &basic_setup, NULL }, 1.2459 + { "many_events_slow_add", test_many_events, TT_ISOLATED, &basic_setup, (void*)1 }, 1.2460 + 1.2461 + { "struct_event_size", test_struct_event_size, 0, NULL, NULL }, 1.2462 + 1.2463 +#ifndef WIN32 1.2464 + LEGACY(fork, TT_ISOLATED), 1.2465 +#endif 1.2466 + END_OF_TESTCASES 1.2467 +}; 1.2468 + 1.2469 +struct testcase_t evtag_testcases[] = { 1.2470 + { "int", evtag_int_test, TT_FORK, NULL, NULL }, 1.2471 + { "fuzz", evtag_fuzz, TT_FORK, NULL, NULL }, 1.2472 + { "encoding", evtag_tag_encoding, TT_FORK, NULL, NULL }, 1.2473 + { "peek", evtag_test_peek, 0, NULL, NULL }, 1.2474 + 1.2475 + END_OF_TESTCASES 1.2476 +}; 1.2477 + 1.2478 +struct testcase_t signal_testcases[] = { 1.2479 +#ifndef WIN32 1.2480 + LEGACY(simplesignal, TT_ISOLATED), 1.2481 + LEGACY(multiplesignal, TT_ISOLATED), 1.2482 + LEGACY(immediatesignal, TT_ISOLATED), 1.2483 + LEGACY(signal_dealloc, TT_ISOLATED), 1.2484 + LEGACY(signal_pipeloss, TT_ISOLATED), 1.2485 + LEGACY(signal_switchbase, TT_ISOLATED|TT_NO_LOGS), 1.2486 + LEGACY(signal_restore, TT_ISOLATED), 1.2487 + LEGACY(signal_assert, TT_ISOLATED), 1.2488 + LEGACY(signal_while_processing, TT_ISOLATED), 1.2489 +#endif 1.2490 + END_OF_TESTCASES 1.2491 +}; 1.2492 +