return g;
}
+int
+bufferevent_rate_limit_group_set_cfg(
+ struct bufferevent_rate_limit_group *g,
+ const struct ev_token_bucket_cfg *cfg)
+{
+ int same_tick;
+ if (!g || !cfg)
+ return -1;
+
+ LOCK_GROUP(g);
+ same_tick = evutil_timercmp(
+ &g->rate_limit_cfg.tick_timeout, &cfg->tick_timeout, ==);
+ memcpy(&g->rate_limit_cfg, cfg, sizeof(g->rate_limit_cfg));
+
+ if (g->rate_limit.read_limit > cfg->read_maximum)
+ g->rate_limit.read_limit = cfg->read_maximum;
+ if (g->rate_limit.write_limit > cfg->write_maximum)
+ g->rate_limit.write_limit = cfg->write_maximum;
+
+ if (!same_tick) {
+ /* This can cause a hiccup in the schedule */
+ event_add(&g->master_refill_event, &cfg->tick_timeout);
+ }
+
+ UNLOCK_GROUP(g);
+ return 0;
+}
+
+
+void
+bufferevent_rate_limit_group_free(struct bufferevent_rate_limit_group *g)
+{
+ LOCK_GROUP(g);
+ EVUTIL_ASSERT(0 == g->n_members);
+ event_del(&g->master_refill_event);
+ UNLOCK_GROUP(g);
+ EVTHREAD_FREE_LOCK(g->lock, EVTHREAD_LOCKTYPE_RECURSIVE);
+ mm_free(g);
+}
+
int
bufferevent_add_to_rate_limit_group(struct bufferevent *bev,
struct bufferevent_rate_limit_group *g)
struct bufferevent_rate_limit_group *bufferevent_rate_limit_group_new(
struct event_base *base,
const struct ev_token_bucket_cfg *cfg);
-/*XXX we need a bufferevent_rate_limit_group_set_cfg */
-/*XXX we need a bufferevent_rate_limit_group_free */
+/**
+ Change the rate-limiting settings for a given rate-limiting group.
+
+ Return 0 on success, -1 on failure.
+*/
+int bufferevent_rate_limit_group_set_cfg(
+ struct bufferevent_rate_limit_group *,
+ const struct ev_token_bucket_cfg *);
+/**
+ Free a rate-limiting group. The group must have no members when
+ this function is called.
+*/
+void bufferevent_rate_limit_group_free(struct bufferevent_rate_limit_group *);
/**
Add 'bev' to the list of bufferevents whose aggregate reading and writing