mirror of
https://github.com/libevent/libevent.git
synced 2025-01-31 09:12:55 +08:00
Make debug mode catch mixed ET and non-ET events on an fd
Of the backends that support edge-triggered IO, most (all?) do not support attempts to mix edge-triggered and level-triggered IO on the same FD. With debugging mode enabled, we now detect and refuse attempts to add a level-triggered IO event to an fd that already has an edge-triggered IO event, and vice versa.
This commit is contained in:
parent
a5208fe422
commit
cb6707405c
@ -158,6 +158,9 @@ struct event_changelist {
|
||||
#ifndef _EVENT_DISABLE_DEBUG_MODE
|
||||
/* Global internal flag: set to one if debug mode is on. */
|
||||
extern int _event_debug_mode_on;
|
||||
#define EVENT_DEBUG_MODE_IS_ON() (_event_debug_mode_on)
|
||||
#else
|
||||
#define EVENT_DEBUG_MODE_IS_ON() (0)
|
||||
#endif
|
||||
|
||||
struct event_base {
|
||||
|
8
evmap.c
8
evmap.c
@ -264,6 +264,7 @@ evmap_io_add(struct event_base *base, evutil_socket_t fd, struct event *ev)
|
||||
struct evmap_io *ctx = NULL;
|
||||
int nread, nwrite, retval = 0;
|
||||
short res = 0, old = 0;
|
||||
struct event *old_ev;
|
||||
|
||||
EVUTIL_ASSERT(fd == ev->ev_fd);
|
||||
|
||||
@ -300,6 +301,13 @@ evmap_io_add(struct event_base *base, evutil_socket_t fd, struct event *ev)
|
||||
(int)fd);
|
||||
return -1;
|
||||
}
|
||||
if (EVENT_DEBUG_MODE_IS_ON() &&
|
||||
(old_ev = TAILQ_FIRST(&ctx->events)) &&
|
||||
(old_ev->ev_events&EV_ET) != (ev->ev_events&EV_ET)) {
|
||||
event_warnx("Tried to mix edge-triggered and non-edge-triggered"
|
||||
" events on fd %d", (int)fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (res) {
|
||||
void *extra = ((char*)ctx) + sizeof(struct evmap_io);
|
||||
|
@ -149,7 +149,49 @@ test_edgetriggered(void *et)
|
||||
evutil_closesocket(pair[1]);
|
||||
}
|
||||
|
||||
static void
|
||||
test_edgetriggered_mix_error(void *data_)
|
||||
{
|
||||
struct basic_test_data *data = data_;
|
||||
struct event_base *base;
|
||||
struct event *ev_et=NULL, *ev_lt=NULL;
|
||||
|
||||
#ifdef _EVENT_DISABLE_DEBUG_MODE
|
||||
if (1)
|
||||
tt_skip();
|
||||
#endif
|
||||
|
||||
event_enable_debug_mode();
|
||||
|
||||
base = event_base_new();
|
||||
|
||||
/* try mixing edge-triggered and level-triggered to make sure it fails*/
|
||||
ev_et = event_new(base, data->pair[0], EV_READ|EV_ET, read_cb, ev_et);
|
||||
ev_lt = event_new(base, data->pair[0], EV_READ, read_cb, ev_lt);
|
||||
|
||||
/* Add edge-triggered, then level-triggered. Get an error. */
|
||||
tt_int_op(0, ==, event_add(ev_et, NULL));
|
||||
tt_int_op(-1, ==, event_add(ev_lt, NULL));
|
||||
tt_int_op(EV_READ, ==, event_pending(ev_et, EV_READ, NULL));
|
||||
tt_int_op(0, ==, event_pending(ev_lt, EV_READ, NULL));
|
||||
|
||||
tt_int_op(0, ==, event_del(ev_et));
|
||||
/* Add level-triggered, then edge-triggered. Get an error. */
|
||||
tt_int_op(0, ==, event_add(ev_lt, NULL));
|
||||
tt_int_op(-1, ==, event_add(ev_et, NULL));
|
||||
tt_int_op(EV_READ, ==, event_pending(ev_lt, EV_READ, NULL));
|
||||
tt_int_op(0, ==, event_pending(ev_et, EV_READ, NULL));
|
||||
|
||||
end:
|
||||
if (ev_et)
|
||||
event_free(ev_et);
|
||||
if (ev_lt)
|
||||
event_free(ev_lt);
|
||||
}
|
||||
|
||||
struct testcase_t edgetriggered_testcases[] = {
|
||||
{ "et", test_edgetriggered, TT_FORK, NULL, NULL },
|
||||
{ "et_mix_error", test_edgetriggered_mix_error,
|
||||
TT_FORK|TT_NEED_SOCKETPAIR|TT_NO_LOGS, &basic_setup, NULL },
|
||||
END_OF_TESTCASES
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user