summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2012-06-13 16:23:16 -0400
committerNick Mathewson <nickm@torproject.org>2012-06-13 16:23:16 -0400
commit54ef039ba527acba4cbcde158b17674e91ede904 (patch)
treef1966946aef41a3f592a0c182e1f61d5a47a6160
parent37ef4f1689b51f2c78a1f02ec466b2fd34d11636 (diff)
parent9c588730598c8da6c8ad8f0829e443235699a37d (diff)
downloadtor-54ef039ba527acba4cbcde158b17674e91ede904.tar.gz
tor-54ef039ba527acba4cbcde158b17674e91ede904.zip
Merge branch 'bug5263_023'
-rw-r--r--changes/bug52635
-rw-r--r--src/or/main.c24
2 files changed, 29 insertions, 0 deletions
diff --git a/changes/bug5263 b/changes/bug5263
new file mode 100644
index 0000000000..25793f141b
--- /dev/null
+++ b/changes/bug5263
@@ -0,0 +1,5 @@
+ o Minor bugfixes:
+ - Disable writing on marked-for-close connections when they are
+ blocked on bandwidth, to prevent busy-looping in Libevent. Fixes
+ bug 5263; bugfix on 0.0.2pre13, where we first added a special
+ case for flushing marked connections.
diff --git a/src/or/main.c b/src/or/main.c
index 163dd5d0fb..3e913d968d 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -848,6 +848,30 @@ conn_close_if_marked(int i)
"Holding conn (fd %d) open for more flushing.",
(int)conn->s));
conn->timestamp_lastwritten = now; /* reset so we can flush more */
+ } else if (sz == 0) { /* retval is also 0 */
+ /* Connection must flush before closing, but it's being rate-limited.
+ Let's remove from Libevent, and mark it as blocked on bandwidth so it
+ will be re-added on next token bucket refill. Prevents busy Libevent
+ loops where we keep ending up here and returning 0 until we are no
+ longer blocked on bandwidth. */
+ if (connection_is_writing(conn)) {
+ conn->write_blocked_on_bw = 1;
+ connection_stop_writing(conn);
+ }
+ if (connection_is_reading(conn)) {
+#define MARKED_READING_RATE 180
+ static ratelim_t marked_read_lim = RATELIM_INIT(MARKED_READING_RATE);
+ char *m;
+ if ((m = rate_limit_log(&marked_read_lim, now))) {
+ log_warn(LD_BUG, "Marked connection (fd %d, type %s, state %s) "
+ "is still reading; that shouldn't happen.%s",
+ (int)conn->s, conn_type_to_string(conn->type),
+ conn_state_to_string(conn->type, conn->state), m);
+ tor_free(m);
+ }
+ conn->read_blocked_on_bw = 1;
+ connection_stop_reading(conn);
+ }
}
return 0;
}