aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/TODO6
-rw-r--r--src/or/config.c3
-rw-r--r--src/or/main.c22
3 files changed, 27 insertions, 4 deletions
diff --git a/doc/TODO b/doc/TODO
index 5a170af3c..d7afebd0f 100644
--- a/doc/TODO
+++ b/doc/TODO
@@ -46,9 +46,9 @@ For 0.1.0.x:
- Is it the buf_shrink bug? (Quite possibly)
- Instrument the 0.1.1 code to figure out where our memory is going;
apply the results. (all platforms?)
- - Why does kevent barf with EINVAL on some freebsd boxes?
- - Submit libevent patch to Niels
- - Warn on non-repeated EINVAL in Tor (don't die.)
+ . Why does kevent barf with EINVAL on some freebsd boxes?
+ o Submit libevent patch to Niels
+ o Warn on non-repeated EINVAL in Tor (don't die.)
- Investigate why freebsd kernel actually does this: it doesn't seem
simple to trigger.
diff --git a/src/or/config.c b/src/or/config.c
index dfb12ad09..4784c412d 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -2684,7 +2684,8 @@ check_libevent_version(const char *m, const char *v, int server)
tor_assert(m && v);
if (!strcmp(m, "kqueue")) {
- if (!strcmp(v, "1.0c")) {
+ if (!strcmp(v, "1.0c") || !strcmp(v, "1.0d") || !strcmp(v, "1.0e") ||
+ !strcmp(v, "1.1")) {
buggy = 1;
}
} else if (!strcmp(m, "epoll")) {
diff --git a/src/or/main.c b/src/or/main.c
index 78d9047d6..e855c06ee 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -810,6 +810,7 @@ run_scheduled_events(time_t now)
}
static struct event *timeout_event = NULL;
+static int n_libevent_errors = 0;
/** Libevent callback: invoked once every second. */
static void
@@ -829,6 +830,8 @@ second_elapsed_callback(int fd, short event, void *args)
one_second.tv_usec = 0;
}
+ n_libevent_errors = 0;
+
/* log_fn(LOG_NOTICE, "Tick."); */
tor_gettimeofday(&now);
@@ -885,6 +888,19 @@ second_elapsed_callback(int fd, short event, void *args)
"Error from libevent when setting one-second timeout event");
}
+/** Called when a possibly ignorable libevent error occurs; ensures that we
+ * don't get into an infinite loop by ignoring too many errors from
+ * libevent. */
+int
+got_libevent_error(void)
+{
+ if (++n_libevent_errors > 8) {
+ log_fn(LOG_ERR, "Too many libevent errors in one second; dying");
+ return -1;
+ }
+ return 0;
+}
+
/** Called when we get a SIGHUP: reload configuration files and keys,
* retry all connections, re-upload all descriptors, and so on. */
static int
@@ -1001,6 +1017,12 @@ do_main_loop(void)
tor_socket_strerror(e), e);
#endif
return -1;
+#ifndef MS_WINDOWS
+ } else if (e == EINVAL) {
+ log_fn(LOG_WARN, "EINVAL from libevent: should you upgrade libevent?");
+ if (got_libevent_error())
+ return -1;
+#endif
} else {
if (ERRNO_IS_EINPROGRESS(e))
log_fn(LOG_WARN,"libevent poll returned EINPROGRESS? Please report.");