/* On Linux 3.2.1 (at least, as patched by Fedora and tested by Nick), *doinga"recv"onanAF_UNIXsocketresetsthereadabilityofthe *socket,eventhoughthereisnostatechange,sowedon'tactually *getedge-triggeredbehavior.Yuck!Linux3.1.9didn'thavethis *problem.
*/
supports_et = base_supports_et(base);
TT_BLATHER(("Checking for edge-triggered events with %s, which should %s" "support edge-triggering", event_base_get_method(base),
supports_et?"":"not "));
/* Initialize one event */
ev = event_new(base, pair[1], EV_READ|EV_ET|EV_PERSIST, read_cb, &ev);
tt_assert(ev != NULL);
tt_int_op(event_add(ev, NULL), ==, 0);
/* We're going to call the dispatch function twice. The first invocation *willreadasinglebytefrompair[1]ineithercase.Ifwe'reedge *triggered,we'llonlyseetheeventonce(sinceweonlyseetransitions *fromnodatatodata),sothesecondinvocationofevent_base_loopwill *donothing.Ifwe'releveltriggered,thesecondinvocationof *event_base_loopwillalsoactivatetheevent(becausethere'sstill
* data to read). */
tt_int_op(event_base_loop(base,EVLOOP_NONBLOCK|EVLOOP_ONCE), ==, 0);
tt_int_op(event_base_loop(base,EVLOOP_NONBLOCK|EVLOOP_ONCE), ==, 0);
#ifdef EVENT__DISABLE_DEBUG_MODE
if (1)
tt_skip(); #endif
if (!libevent_tests_running_in_debug_mode)
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);
tt_assert(ev_et);
ev_lt = event_new(base, data->pair[0], EV_READ, read_cb, ev_lt);
tt_assert(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);
if (base)
event_base_free(base);
}
static int read_notification_count; static int last_read_notification_was_et; staticvoid
read_notification_cb(evutil_socket_t fd, short event, void *arg)
{
read_notification_count++;
last_read_notification_was_et = (event & EV_ET);
}
static int write_notification_count; static int last_write_notification_was_et; staticvoid
write_notification_cb(evutil_socket_t fd, short event, void *arg)
{
write_notification_count++;
last_write_notification_was_et = (event & EV_ET);
}
/* After two or more events have been registered for the same *filedescriptorusingEV_ET,ifoneoftheeventsis *deleted,thentheepoll_ctl()callissuedbylibeventdrops *theEPOLLETflagresultinginleveltriggered *notifications.
*/ staticvoid
test_edge_triggered_multiple_events(void *data_)
{ struct basic_test_data *data = data_; struct event *read_ev = NULL; struct event *write_ev = NULL; const char c = 'A'; struct event_base *base = data->base;
evutil_socket_t *pair = data->pair;
if (!base_supports_et(base)) {
tt_skip(); return;
}
/* trigger acitivity second time for the backend that can have multiple
* events for one fd (like kqueue) */
close(pair[0]);
pair[0] = -1;
/* Verify that we are still edge-triggered for write notifications */
event_base_loop(base, EVLOOP_NONBLOCK|EVLOOP_ONCE);
event_base_loop(base, EVLOOP_NONBLOCK|EVLOOP_ONCE);
tt_assert(last_write_notification_was_et);
tt_int_op(write_notification_count, ==, 2);
end:
if (read_ev)
event_free(read_ev);
if (write_ev)
event_free(write_ev);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.