Merge branch 'check-O_NONBLOCK-in-debug'

* check-O_NONBLOCK-in-debug:
  regress: use non blocking descriptors whenever it is possible
  assert that fds are nonblocking in debug mode

Closes: nmathewson/Libevent#90
(cherry picked from commit 6f988ee161680925fc3308f17d293c680e3ac916)
This commit is contained in:
Azat Khuzhin 2018-11-04 01:21:48 +03:00 committed by Azat Khuzhin
parent bf3a67cfc5
commit a39898f363
No known key found for this signature in database
GPG Key ID: B86086848EF8686D
3 changed files with 40 additions and 48 deletions

39
event.c
View File

@ -52,6 +52,9 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <limits.h> #include <limits.h>
#ifdef EVENT__HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include "event2/event.h" #include "event2/event.h"
#include "event2/event_struct.h" #include "event2/event_struct.h"
@ -234,9 +237,8 @@ static void event_debug_note_setup_(const struct event *ev)
{ {
struct event_debug_entry *dent, find; struct event_debug_entry *dent, find;
if (!event_debug_mode_on_) { if (!event_debug_mode_on_)
goto out; goto out;
}
find.ptr = ev; find.ptr = ev;
EVLOCK_LOCK(event_debug_map_lock_, 0); EVLOCK_LOCK(event_debug_map_lock_, 0);
@ -262,9 +264,8 @@ static void event_debug_note_teardown_(const struct event *ev)
{ {
struct event_debug_entry *dent, find; struct event_debug_entry *dent, find;
if (!event_debug_mode_on_) { if (!event_debug_mode_on_)
goto out; goto out;
}
find.ptr = ev; find.ptr = ev;
EVLOCK_LOCK(event_debug_map_lock_, 0); EVLOCK_LOCK(event_debug_map_lock_, 0);
@ -281,9 +282,8 @@ static void event_debug_note_add_(const struct event *ev)
{ {
struct event_debug_entry *dent,find; struct event_debug_entry *dent,find;
if (!event_debug_mode_on_) { if (!event_debug_mode_on_)
goto out; goto out;
}
find.ptr = ev; find.ptr = ev;
EVLOCK_LOCK(event_debug_map_lock_, 0); EVLOCK_LOCK(event_debug_map_lock_, 0);
@ -308,9 +308,8 @@ static void event_debug_note_del_(const struct event *ev)
{ {
struct event_debug_entry *dent, find; struct event_debug_entry *dent, find;
if (!event_debug_mode_on_) { if (!event_debug_mode_on_)
goto out; goto out;
}
find.ptr = ev; find.ptr = ev;
EVLOCK_LOCK(event_debug_map_lock_, 0); EVLOCK_LOCK(event_debug_map_lock_, 0);
@ -335,9 +334,8 @@ static void event_debug_assert_is_setup_(const struct event *ev)
{ {
struct event_debug_entry *dent, find; struct event_debug_entry *dent, find;
if (!event_debug_mode_on_) { if (!event_debug_mode_on_)
return; return;
}
find.ptr = ev; find.ptr = ev;
EVLOCK_LOCK(event_debug_map_lock_, 0); EVLOCK_LOCK(event_debug_map_lock_, 0);
@ -357,9 +355,8 @@ static void event_debug_assert_not_added_(const struct event *ev)
{ {
struct event_debug_entry *dent, find; struct event_debug_entry *dent, find;
if (!event_debug_mode_on_) { if (!event_debug_mode_on_)
return; return;
}
find.ptr = ev; find.ptr = ev;
EVLOCK_LOCK(event_debug_map_lock_, 0); EVLOCK_LOCK(event_debug_map_lock_, 0);
@ -374,6 +371,21 @@ static void event_debug_assert_not_added_(const struct event *ev)
} }
EVLOCK_UNLOCK(event_debug_map_lock_, 0); EVLOCK_UNLOCK(event_debug_map_lock_, 0);
} }
static void event_debug_assert_socket_nonblocking_(evutil_socket_t fd)
{
int flags;
if (!event_debug_mode_on_)
return;
#ifndef _WIN32
if ((flags = fcntl(fd, F_GETFL, NULL)) >= 0) {
EVUTIL_ASSERT(flags & O_NONBLOCK);
}
#else
(void)flags;
#endif
}
#else #else
static void event_debug_note_setup_(const struct event *ev) { (void)ev; } static void event_debug_note_setup_(const struct event *ev) { (void)ev; }
static void event_debug_note_teardown_(const struct event *ev) { (void)ev; } static void event_debug_note_teardown_(const struct event *ev) { (void)ev; }
@ -381,6 +393,7 @@ static void event_debug_note_add_(const struct event *ev) { (void)ev; }
static void event_debug_note_del_(const struct event *ev) { (void)ev; } static void event_debug_note_del_(const struct event *ev) { (void)ev; }
static void event_debug_assert_is_setup_(const struct event *ev) { (void)ev; } static void event_debug_assert_is_setup_(const struct event *ev) { (void)ev; }
static void event_debug_assert_not_added_(const struct event *ev) { (void)ev; } static void event_debug_assert_not_added_(const struct event *ev) { (void)ev; }
static void event_debug_assert_socket_nonblocking_(evutil_socket_t fd) { (void)fd; }
#endif #endif
#define EVENT_BASE_ASSERT_LOCKED(base) \ #define EVENT_BASE_ASSERT_LOCKED(base) \
@ -2099,6 +2112,8 @@ event_assign(struct event *ev, struct event_base *base, evutil_socket_t fd, shor
if (arg == &event_self_cbarg_ptr_) if (arg == &event_self_cbarg_ptr_)
arg = ev; arg = ev;
if (!(events & EV_SIGNAL))
event_debug_assert_socket_nonblocking_(fd);
event_debug_assert_not_added_(ev); event_debug_assert_not_added_(ev);
ev->ev_base = base; ev->ev_base = base;

View File

@ -1389,18 +1389,14 @@ test_free_active_base(void *ptr)
struct event ev1; struct event ev1;
base1 = event_init(); base1 = event_init();
if (base1) { tt_assert(base1);
event_assign(&ev1, base1, data->pair[1], EV_READ, event_assign(&ev1, base1, data->pair[1], EV_READ, dummy_read_cb, NULL);
dummy_read_cb, NULL);
event_add(&ev1, NULL); event_add(&ev1, NULL);
event_base_free(base1); /* should not crash */ event_base_free(base1); /* should not crash */
} else {
tt_fail_msg("failed to create event_base for test");
}
base1 = event_init(); base1 = event_init();
tt_assert(base1); tt_assert(base1);
event_assign(&ev1, base1, 0, 0, dummy_read_cb, NULL); event_assign(&ev1, base1, data->pair[0], 0, dummy_read_cb, NULL);
event_active(&ev1, EV_READ, 1); event_active(&ev1, EV_READ, 1);
event_base_free(base1); event_base_free(base1);
end: end:
@ -3080,6 +3076,7 @@ test_many_events(void *arg)
* instance of that. */ * instance of that. */
sock[i] = socket(AF_INET, SOCK_DGRAM, 0); sock[i] = socket(AF_INET, SOCK_DGRAM, 0);
tt_assert(sock[i] >= 0); tt_assert(sock[i] >= 0);
tt_assert(!evutil_make_socket_nonblocking(sock[i]));
called[i] = 0; called[i] = 0;
ev[i] = event_new(base, sock[i], EV_WRITE|evflags, ev[i] = event_new(base, sock[i], EV_WRITE|evflags,
many_event_cb, &called[i]); many_event_cb, &called[i]);

View File

@ -75,19 +75,14 @@ read_cb(evutil_socket_t fd, short event, void *arg)
event_del(arg); event_del(arg);
} }
#ifdef _WIN32
#define LOCAL_SOCKETPAIR_AF AF_INET
#else
#define LOCAL_SOCKETPAIR_AF AF_UNIX
#endif
static void static void
test_edgetriggered(void *et) test_edgetriggered(void *data_)
{ {
struct basic_test_data *data = data_;
struct event_base *base = data->base;
int *pair = data->pair;
struct event *ev = NULL; struct event *ev = NULL;
struct event_base *base = NULL;
const char *test = "test string"; const char *test = "test string";
evutil_socket_t pair[2] = {-1,-1};
int supports_et; int supports_et;
/* On Linux 3.2.1 (at least, as patched by Fedora and tested by Nick), /* On Linux 3.2.1 (at least, as patched by Fedora and tested by Nick),
@ -96,24 +91,12 @@ test_edgetriggered(void *et)
* get edge-triggered behavior. Yuck! Linux 3.1.9 didn't have this * get edge-triggered behavior. Yuck! Linux 3.1.9 didn't have this
* problem. * problem.
*/ */
#ifdef __linux__
if (evutil_ersatz_socketpair_(AF_INET, SOCK_STREAM, 0, pair) == -1) {
tt_abort_perror("socketpair");
}
#else
if (evutil_socketpair(LOCAL_SOCKETPAIR_AF, SOCK_STREAM, 0, pair) == -1) {
tt_abort_perror("socketpair");
}
#endif
called = was_et = 0; called = was_et = 0;
tt_int_op(send(pair[0], test, (int)strlen(test)+1, 0), >, 0); tt_int_op(send(pair[0], test, (int)strlen(test)+1, 0), >, 0);
shutdown(pair[0], EVUTIL_SHUT_WR); shutdown(pair[0], EVUTIL_SHUT_WR);
/* Initalize the event library */
base = event_base_new();
supports_et = base_supports_et(base); supports_et = base_supports_et(base);
TT_BLATHER(("Checking for edge-triggered events with %s, which should %s" TT_BLATHER(("Checking for edge-triggered events with %s, which should %s"
"support edge-triggering", event_base_get_method(base), "support edge-triggering", event_base_get_method(base),
@ -142,15 +125,11 @@ test_edgetriggered(void *et)
tt_assert(!was_et); tt_assert(!was_et);
} }
end: end:
if (ev) { if (ev) {
event_del(ev); event_del(ev);
event_free(ev); event_free(ev);
} }
if (base)
event_base_free(base);
evutil_closesocket(pair[0]);
evutil_closesocket(pair[1]);
} }
static void static void
@ -281,7 +260,8 @@ end:
} }
struct testcase_t edgetriggered_testcases[] = { struct testcase_t edgetriggered_testcases[] = {
{ "et", test_edgetriggered, TT_FORK, NULL, NULL }, { "et", test_edgetriggered,
TT_FORK|TT_NEED_BASE|TT_NEED_SOCKETPAIR, &basic_setup, NULL },
{ "et_mix_error", test_edgetriggered_mix_error, { "et_mix_error", test_edgetriggered_mix_error,
TT_FORK|TT_NEED_SOCKETPAIR|TT_NO_LOGS, &basic_setup, NULL }, TT_FORK|TT_NEED_SOCKETPAIR|TT_NO_LOGS, &basic_setup, NULL },
{ "et_multiple_events", test_edge_triggered_multiple_events, { "et_multiple_events", test_edge_triggered_multiple_events,