Make rate-limits go up to SIZE_MAX/EV_SSIZE_MAX, not just INT32_MAX

Someday, when networks are far faster and people frequently want a
burst value greater than 2GB per tick, this will seem very forsightful
indeed.

For now, it breaks ABI, but not source.  Fixes bug 3092096.
This commit is contained in:
Nick Mathewson 2010-10-26 10:27:29 -04:00
parent 8e342e5630
commit 2cbb1a161e
4 changed files with 26 additions and 18 deletions

View File

@ -96,7 +96,7 @@ struct bufferevent_rate_limit_group {
/** The smallest number of bytes that any member of the group should /** The smallest number of bytes that any member of the group should
* be limited to read or write at a time. */ * be limited to read or write at a time. */
ev_int32_t min_share; ev_ssize_t min_share;
/** Timeout event that goes off once a tick, when the bucket is ready /** Timeout event that goes off once a tick, when the bucket is ready
* to refill. */ * to refill. */
struct event master_refill_event; struct event master_refill_event;

View File

@ -138,8 +138,8 @@ ev_token_bucket_get_tick(const struct timeval *tv,
} }
struct ev_token_bucket_cfg * struct ev_token_bucket_cfg *
ev_token_bucket_cfg_new(ev_uint32_t read_rate, ev_uint32_t read_burst, ev_token_bucket_cfg_new(size_t read_rate, size_t read_burst,
ev_uint32_t write_rate, ev_uint32_t write_burst, size_t write_rate, size_t write_burst,
const struct timeval *tick_len) const struct timeval *tick_len)
{ {
struct ev_token_bucket_cfg *r; struct ev_token_bucket_cfg *r;
@ -152,6 +152,11 @@ ev_token_bucket_cfg_new(ev_uint32_t read_rate, ev_uint32_t read_burst,
if (read_rate > read_burst || write_rate > write_burst || if (read_rate > read_burst || write_rate > write_burst ||
read_rate < 1 || write_rate < 1) read_rate < 1 || write_rate < 1)
return NULL; return NULL;
if (read_rate > EV_RATE_LIMIT_MAX ||
write_rate > EV_RATE_LIMIT_MAX ||
read_burst > EV_RATE_LIMIT_MAX ||
write_burst > EV_RATE_LIMIT_MAX)
return NULL;
r = mm_calloc(1, sizeof(struct ev_token_bucket_cfg)); r = mm_calloc(1, sizeof(struct ev_token_bucket_cfg));
if (!r) if (!r)
return NULL; return NULL;
@ -221,7 +226,7 @@ _bufferevent_get_rlim_max(struct bufferevent_private *bev, int is_write)
if (bev->rate_limiting->group) { if (bev->rate_limiting->group) {
struct bufferevent_rate_limit_group *g = struct bufferevent_rate_limit_group *g =
bev->rate_limiting->group; bev->rate_limiting->group;
ev_int32_t share; ev_ssize_t share;
LOCK_GROUP(g); LOCK_GROUP(g);
if (GROUP_SUSPENDED(g)) { if (GROUP_SUSPENDED(g)) {
/* We can get here if we failed to lock this /* We can get here if we failed to lock this
@ -655,9 +660,9 @@ bufferevent_rate_limit_group_set_cfg(
&g->rate_limit_cfg.tick_timeout, &cfg->tick_timeout, ==); &g->rate_limit_cfg.tick_timeout, &cfg->tick_timeout, ==);
memcpy(&g->rate_limit_cfg, cfg, sizeof(g->rate_limit_cfg)); memcpy(&g->rate_limit_cfg, cfg, sizeof(g->rate_limit_cfg));
if (g->rate_limit.read_limit > (ev_int32_t)cfg->read_maximum) if (g->rate_limit.read_limit > (ev_ssize_t)cfg->read_maximum)
g->rate_limit.read_limit = cfg->read_maximum; g->rate_limit.read_limit = cfg->read_maximum;
if (g->rate_limit.write_limit > (ev_int32_t)cfg->write_maximum) if (g->rate_limit.write_limit > (ev_ssize_t)cfg->write_maximum)
g->rate_limit.write_limit = cfg->write_maximum; g->rate_limit.write_limit = cfg->write_maximum;
if (!same_tick) { if (!same_tick) {
@ -674,7 +679,7 @@ bufferevent_rate_limit_group_set_min_share(
struct bufferevent_rate_limit_group *g, struct bufferevent_rate_limit_group *g,
size_t share) size_t share)
{ {
if (share > EV_INT32_MAX) if (share > EV_SSIZE_MAX)
return -1; return -1;
g->min_share = share; g->min_share = share;
@ -865,7 +870,7 @@ int
bufferevent_decrement_read_limit(struct bufferevent *bev, ev_ssize_t decr) bufferevent_decrement_read_limit(struct bufferevent *bev, ev_ssize_t decr)
{ {
int r = 0; int r = 0;
ev_int32_t old_limit, new_limit; ev_ssize_t old_limit, new_limit;
struct bufferevent_private *bevp; struct bufferevent_private *bevp;
BEV_LOCK(bev); BEV_LOCK(bev);
bevp = BEV_UPCAST(bev); bevp = BEV_UPCAST(bev);
@ -894,7 +899,7 @@ bufferevent_decrement_write_limit(struct bufferevent *bev, ev_ssize_t decr)
/* XXXX this is mostly copy-and-paste from /* XXXX this is mostly copy-and-paste from
* bufferevent_decrement_read_limit */ * bufferevent_decrement_read_limit */
int r = 0; int r = 0;
ev_int32_t old_limit, new_limit; ev_ssize_t old_limit, new_limit;
struct bufferevent_private *bevp; struct bufferevent_private *bevp;
BEV_LOCK(bev); BEV_LOCK(bev);
bevp = BEV_UPCAST(bev); bevp = BEV_UPCAST(bev);
@ -922,7 +927,7 @@ bufferevent_rate_limit_group_decrement_read(
struct bufferevent_rate_limit_group *grp, ev_ssize_t decr) struct bufferevent_rate_limit_group *grp, ev_ssize_t decr)
{ {
int r = 0; int r = 0;
ev_int32_t old_limit, new_limit; ev_ssize_t old_limit, new_limit;
LOCK_GROUP(grp); LOCK_GROUP(grp);
old_limit = grp->rate_limit.read_limit; old_limit = grp->rate_limit.read_limit;
new_limit = (grp->rate_limit.read_limit -= decr); new_limit = (grp->rate_limit.read_limit -= decr);
@ -942,7 +947,7 @@ bufferevent_rate_limit_group_decrement_write(
struct bufferevent_rate_limit_group *grp, ev_ssize_t decr) struct bufferevent_rate_limit_group *grp, ev_ssize_t decr)
{ {
int r = 0; int r = 0;
ev_int32_t old_limit, new_limit; ev_ssize_t old_limit, new_limit;
LOCK_GROUP(grp); LOCK_GROUP(grp);
old_limit = grp->rate_limit.write_limit; old_limit = grp->rate_limit.write_limit;
new_limit = (grp->rate_limit.write_limit -= decr); new_limit = (grp->rate_limit.write_limit -= decr);

View File

@ -565,6 +565,9 @@ struct ev_token_bucket_cfg;
*/ */
struct bufferevent_rate_limit_group; struct bufferevent_rate_limit_group;
/** Maximum configurable rate- or burst-limit. */
#define EV_RATE_LIMIT_MAX EV_SSIZE_MAX
/** /**
Initialize and return a new object to configure the rate-limiting behavior Initialize and return a new object to configure the rate-limiting behavior
of bufferevents. of bufferevents.
@ -582,8 +585,8 @@ struct bufferevent_rate_limit_group;
of Libevent may implement them more tightly. of Libevent may implement them more tightly.
*/ */
struct ev_token_bucket_cfg *ev_token_bucket_cfg_new( struct ev_token_bucket_cfg *ev_token_bucket_cfg_new(
ev_uint32_t read_rate, ev_uint32_t read_burst, size_t read_rate, size_t read_burst,
ev_uint32_t write_rate, ev_uint32_t write_burst, size_t write_rate, size_t write_burst,
const struct timeval *tick_len); const struct timeval *tick_len);
/** Free all storage held in 'cfg'. /** Free all storage held in 'cfg'.

View File

@ -38,7 +38,7 @@ extern "C" {
struct ev_token_bucket { struct ev_token_bucket {
/** How many bytes are we willing to read or write right now? These /** How many bytes are we willing to read or write right now? These
* values are signed so that we can do "defecit spending" */ * values are signed so that we can do "defecit spending" */
ev_int32_t read_limit, write_limit; ev_ssize_t read_limit, write_limit;
/** When was this bucket last updated? Measured in abstract 'ticks' /** When was this bucket last updated? Measured in abstract 'ticks'
* relative to the token bucket configuration. */ * relative to the token bucket configuration. */
ev_uint32_t last_updated; ev_uint32_t last_updated;
@ -47,13 +47,13 @@ struct ev_token_bucket {
/** Configuration info for a token bucket or set of token buckets. */ /** Configuration info for a token bucket or set of token buckets. */
struct ev_token_bucket_cfg { struct ev_token_bucket_cfg {
/** How many bytes are we willing to read on average per tick? */ /** How many bytes are we willing to read on average per tick? */
ev_uint32_t read_rate; size_t read_rate;
/** How many bytes are we willing to read at most in any one tick? */ /** How many bytes are we willing to read at most in any one tick? */
ev_uint32_t read_maximum; size_t read_maximum;
/** How many bytes are we willing to write on average per tick? */ /** How many bytes are we willing to write on average per tick? */
ev_uint32_t write_rate; size_t write_rate;
/** How many bytes are we willing to write at most in any one tick? */ /** How many bytes are we willing to write at most in any one tick? */
ev_uint32_t write_maximum; size_t write_maximum;
/* How long is a tick? Note that fractions of a millisecond are /* How long is a tick? Note that fractions of a millisecond are
* ignored. */ * ignored. */