diff options
Diffstat (limited to 'src/or/main.c')
-rw-r--r-- | src/or/main.c | 22 |
1 files changed, 22 insertions, 0 deletions
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."); |