summaryrefslogtreecommitdiff
path: root/bufferevent_ratelim.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2011-08-11 15:15:17 -0400
committerNick Mathewson <nickm@torproject.org>2011-08-11 15:15:17 -0400
commit6d5440e80e7ecd95c52b3f3d5217e1693294404e (patch)
tree2320d8188e8bb116d337f65955cc1e1a0a114fc9 /bufferevent_ratelim.c
parent5d1b255b1475602707d61337107e2ab6e5a94da9 (diff)
downloadlibevent-6d5440e80e7ecd95c52b3f3d5217e1693294404e.tar.gz
Fix handling of group rate limits under 64 bytes of burst
The "min_share" logic, which was designed to prevent piles of extremely small writes when running up against a group rate limit, could lead to confusing behavior if you ever set a min_share less than your burst rate. If that happened, then as soon as your group rate limit was exhausted, you'd stop reading/writing, and never start again, since the amount readable/writeable would never actually hit min_share. We now cap min_share at the rate per tick. Found by George Kadianakis
Diffstat (limited to 'bufferevent_ratelim.c')
-rw-r--r--bufferevent_ratelim.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/bufferevent_ratelim.c b/bufferevent_ratelim.c
index 85904e82..827b346c 100644
--- a/bufferevent_ratelim.c
+++ b/bufferevent_ratelim.c
@@ -636,13 +636,15 @@ bufferevent_rate_limit_group_new(struct event_base *base,
ev_token_bucket_init(&g->rate_limit, cfg, tick, 0);
- g->min_share = 64;
event_assign(&g->master_refill_event, base, -1, EV_PERSIST,
_bev_group_refill_callback, g);
/*XXXX handle event_add failure */
event_add(&g->master_refill_event, &cfg->tick_timeout);
EVTHREAD_ALLOC_LOCK(g->lock, EVTHREAD_LOCKTYPE_RECURSIVE);
+
+ bufferevent_rate_limit_group_set_min_share(g, 64);
+
return g;
}
@@ -670,6 +672,9 @@ bufferevent_rate_limit_group_set_cfg(
event_add(&g->master_refill_event, &cfg->tick_timeout);
}
+ /* The new limits might force us to adjust min_share differently. */
+ bufferevent_rate_limit_group_set_min_share(g, g->configured_min_share);
+
UNLOCK_GROUP(g);
return 0;
}
@@ -682,6 +687,15 @@ bufferevent_rate_limit_group_set_min_share(
if (share > EV_SSIZE_MAX)
return -1;
+ g->configured_min_share = share;
+
+ /* Can't set share to less than the one-tick maximum. IOW, at steady
+ * state, at least one connection can go per tick. */
+ if (share > g->rate_limit_cfg.read_rate)
+ share = g->rate_limit_cfg.read_rate;
+ if (share > g->rate_limit_cfg.write_rate)
+ share = g->rate_limit_cfg.write_rate;
+
g->min_share = share;
return 0;
}