aboutsummaryrefslogtreecommitdiff
path: root/src/or/main.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2017-12-20 11:16:17 -0500
committerNick Mathewson <nickm@torproject.org>2017-12-20 11:16:17 -0500
commit7ca0a9c4aec374f5fbddc7847c543c5ba9e44869 (patch)
tree4e02cbfec3202d0057ba9953bc0dfa25c5a8367e /src/or/main.c
parentc99ec36defadf763034b82107f6168987668862f (diff)
parentd4f4108601fe7e2614f30055ff5abe00460f6a12 (diff)
downloadtor-7ca0a9c4aec374f5fbddc7847c543c5ba9e44869.tar.gz
tor-7ca0a9c4aec374f5fbddc7847c543c5ba9e44869.zip
Merge remote-tracking branch 'ahf-oniongit/bugs/24605'
Diffstat (limited to 'src/or/main.c')
-rw-r--r--src/or/main.c83
1 files changed, 82 insertions, 1 deletions
diff --git a/src/or/main.c b/src/or/main.c
index 2c8dfae2f3..7f55f1210d 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -179,6 +179,12 @@ static uint64_t stats_n_bytes_written = 0;
time_t time_of_process_start = 0;
/** How many seconds have we been running? */
long stats_n_seconds_working = 0;
+/** How many times have we returned from the main loop successfully? */
+static uint64_t stats_n_main_loop_successes = 0;
+/** How many times have we received an error from the main loop? */
+static uint64_t stats_n_main_loop_errors = 0;
+/** How many times have we returned from the main loop with no events. */
+static uint64_t stats_n_main_loop_idle = 0;
/** How often will we honor SIGNEWNYM requests? */
#define MAX_SIGNEWNYM_RATE 10
@@ -493,6 +499,57 @@ connection_is_reading(connection_t *conn)
(conn->read_event && event_pending(conn->read_event, EV_READ, NULL));
}
+/** Reset our main loop counters. */
+void
+reset_main_loop_counters(void)
+{
+ stats_n_main_loop_successes = 0;
+ stats_n_main_loop_errors = 0;
+ stats_n_main_loop_idle = 0;
+}
+
+/** Increment the main loop success counter. */
+static void
+increment_main_loop_success_count(void)
+{
+ ++stats_n_main_loop_successes;
+}
+
+/** Get the main loop success counter. */
+uint64_t
+get_main_loop_success_count(void)
+{
+ return stats_n_main_loop_successes;
+}
+
+/** Increment the main loop error counter. */
+static void
+increment_main_loop_error_count(void)
+{
+ ++stats_n_main_loop_errors;
+}
+
+/** Get the main loop error counter. */
+uint64_t
+get_main_loop_error_count(void)
+{
+ return stats_n_main_loop_errors;
+}
+
+/** Increment the main loop idle counter. */
+static void
+increment_main_loop_idle_count(void)
+{
+ ++stats_n_main_loop_idle;
+}
+
+/** Get the main loop idle counter. */
+uint64_t
+get_main_loop_idle_count(void)
+{
+ return stats_n_main_loop_idle;
+}
+
/** Check whether <b>conn</b> is correct in having (or not having) a
* read/write event (passed in <b>ev</b>). On success, return 0. On failure,
* log a warning and return -1. */
@@ -2693,6 +2750,8 @@ run_main_loop_once(void)
if (main_loop_should_exit)
return 0;
+ const or_options_t *options = get_options();
+
#ifndef _WIN32
/* Make it easier to tell whether libevent failure is our fault or not. */
errno = 0;
@@ -2702,7 +2761,14 @@ run_main_loop_once(void)
* so that libevent knows to run their callbacks. */
SMARTLIST_FOREACH(active_linked_connection_lst, connection_t *, conn,
event_active(conn->read_event, EV_READ, 1));
- called_loop_once = smartlist_len(active_linked_connection_lst) ? 1 : 0;
+
+ if (options->MainloopStats) {
+ /* We always enforce that EVLOOP_ONCE is passed to event_base_loop() if we
+ * are collecting main loop statistics. */
+ called_loop_once = 1;
+ } else {
+ called_loop_once = smartlist_len(active_linked_connection_lst) ? 1 : 0;
+ }
/* Make sure we know (about) what time it is. */
update_approx_time(time(NULL));
@@ -2714,6 +2780,21 @@ run_main_loop_once(void)
loop_result = event_base_loop(tor_libevent_get_base(),
called_loop_once ? EVLOOP_ONCE : 0);
+ if (options->MainloopStats) {
+ /* Update our main loop counters. */
+ if (loop_result == 0) {
+ // The call was succesful.
+ increment_main_loop_success_count();
+ } else if (loop_result == -1) {
+ // The call was erroneous.
+ increment_main_loop_error_count();
+ } else if (loop_result == 1) {
+ // The call didn't have any active or pending events
+ // to handle.
+ increment_main_loop_idle_count();
+ }
+ }
+
/* Oh, the loop failed. That might be an error that we need to
* catch, but more likely, it's just an interrupted poll() call or something,
* and we should try again. */