Skip to content

Commit db2efdf

Browse files
committed
Merge branch 'EV_CLOSED-and-EV_ET-fixes'
* EV_CLOSED-and-EV_ET-fixes: Avoid triggering wrong events with EV_ET set epoll: handle EV_ET for EV_CLOSED too test: cover EV_CLOSED with lots of possible scenarious test: rename simpleclose to simpleclose_rw (since it works via write/read) (cherry picked from commit c10cde4)
1 parent 4dd3acd commit db2efdf

File tree

3 files changed

+87
-5
lines changed

3 files changed

+87
-5
lines changed

epoll.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ epoll_apply_one_change(struct event_base *base,
281281
return 0;
282282
}
283283

284-
if ((ch->read_change|ch->write_change) & EV_CHANGE_ET)
284+
if ((ch->read_change|ch->write_change|ch->close_change) & EV_CHANGE_ET)
285285
events |= EPOLLET;
286286

287287
memset(&epev, 0, sizeof(epev));

evmap.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ evmap_io_active_(struct event_base *base, evutil_socket_t fd, short events)
432432
if (NULL == ctx)
433433
return;
434434
LIST_FOREACH(ev, &ctx->events, ev_io_next) {
435-
if (ev->ev_events & events)
435+
if (ev->ev_events & (events & ~EV_ET))
436436
event_active_nolock_(ev, ev->ev_events & events, 1);
437437
}
438438
}

test/regress.c

+85-3
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ record_event_cb(evutil_socket_t s, short what, void *ptr)
387387
}
388388

389389
static void
390-
test_simpleclose(void *ptr)
390+
test_simpleclose_rw(void *ptr)
391391
{
392392
/* Test that a close of FD is detected as a read and as a write. */
393393
struct event_base *base = event_base_new();
@@ -469,6 +469,61 @@ test_simpleclose(void *ptr)
469469
event_base_free(base);
470470
}
471471

472+
static void
473+
test_simpleclose(void *ptr)
474+
{
475+
struct basic_test_data *data = ptr;
476+
struct event_base *base = data->base;
477+
evutil_socket_t *pair = data->pair;
478+
const char *flags = (const char *)data->setup_data;
479+
int et = !!strstr(flags, "ET");
480+
int persist = !!strstr(flags, "persist");
481+
short events = EV_CLOSED | (et ? EV_ET : 0) | (persist ? EV_PERSIST : 0);
482+
struct event *ev = NULL;
483+
short got_event;
484+
485+
if (!(event_base_get_features(data->base) & EV_FEATURE_EARLY_CLOSE))
486+
tt_skip();
487+
488+
/* XXX: should this code moved to regress_et.c ? */
489+
if (et && !(event_base_get_features(data->base) & EV_FEATURE_ET))
490+
tt_skip();
491+
492+
ev = event_new(base, pair[0], events, record_event_cb, &got_event);
493+
tt_assert(ev);
494+
tt_assert(!event_add(ev, NULL));
495+
496+
got_event = 0;
497+
if (strstr(flags, "close")) {
498+
tt_assert(!close(pair[1]));
499+
/* avoid closing in setup routines */
500+
pair[1] = -1;
501+
} else if (strstr(flags, "shutdown")) {
502+
tt_assert(!shutdown(pair[1], EVUTIL_SHUT_WR));
503+
} else {
504+
tt_abort_msg("unknown flags");
505+
}
506+
507+
/* w/o edge-triggerd but w/ persist it will not stop */
508+
if (!et && persist) {
509+
struct timeval tv;
510+
tv.tv_sec = 0;
511+
tv.tv_usec = 10000;
512+
tt_assert(!event_base_loopexit(base, &tv));
513+
}
514+
515+
/* via close() */
516+
if (pair[1] == -1) {
517+
tt_int_op(event_base_loop(base, EVLOOP_NONBLOCK), ==, 0);
518+
} else {
519+
tt_int_op(event_base_loop(base, EVLOOP_NONBLOCK), ==, !persist);
520+
tt_int_op(got_event, ==, (events & ~EV_PERSIST));
521+
}
522+
523+
end:
524+
if (ev)
525+
event_free(ev);
526+
}
472527

473528
static void
474529
test_multiple(void)
@@ -3461,8 +3516,35 @@ struct testcase_t main_testcases[] = {
34613516
LEGACY(simpleread, TT_ISOLATED),
34623517
LEGACY(simpleread_multiple, TT_ISOLATED),
34633518
LEGACY(simplewrite, TT_ISOLATED),
3464-
{ "simpleclose", test_simpleclose, TT_FORK, &basic_setup,
3465-
NULL },
3519+
{ "simpleclose_rw", test_simpleclose_rw, TT_FORK, &basic_setup, NULL },
3520+
/* simpleclose */
3521+
{ "simpleclose_close", test_simpleclose,
3522+
TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_BASE,
3523+
&basic_setup, (void *)"close" },
3524+
{ "simpleclose_shutdown", test_simpleclose,
3525+
TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_BASE,
3526+
&basic_setup, (void *)"shutdown" },
3527+
/* simpleclose_*_persist */
3528+
{ "simpleclose_close_persist", test_simpleclose,
3529+
TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_BASE,
3530+
&basic_setup, (void *)"close_persist" },
3531+
{ "simpleclose_shutdown_persist", test_simpleclose,
3532+
TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_BASE,
3533+
&basic_setup, (void *)"shutdown_persist" },
3534+
/* simpleclose_*_et */
3535+
{ "simpleclose_close_et", test_simpleclose,
3536+
TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_BASE,
3537+
&basic_setup, (void *)"close_ET" },
3538+
{ "simpleclose_shutdown_et", test_simpleclose,
3539+
TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_BASE,
3540+
&basic_setup, (void *)"shutdown_ET" },
3541+
/* simpleclose_*_persist_et */
3542+
{ "simpleclose_close_persist_et", test_simpleclose,
3543+
TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_BASE,
3544+
&basic_setup, (void *)"close_persist_ET" },
3545+
{ "simpleclose_shutdown_persist_et", test_simpleclose,
3546+
TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_BASE,
3547+
&basic_setup, (void *)"shutdown_persist_ET" },
34663548
LEGACY(multiple, TT_ISOLATED),
34673549
LEGACY(persistent, TT_ISOLATED),
34683550
LEGACY(combined, TT_ISOLATED),

0 commit comments

Comments
 (0)