]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Make bufferevents work with TokenBucketRefillInterval
authorNick Mathewson <nickm@torproject.org>
Thu, 8 Sep 2011 02:00:48 +0000 (22:00 -0400)
committerNick Mathewson <nickm@torproject.org>
Thu, 22 Sep 2011 19:07:34 +0000 (15:07 -0400)
doc/tor.1.txt
src/common/compat_libevent.c
src/common/compat_libevent.h
src/or/config.c
src/or/connection.c
src/or/connection_or.c

index 15f5a211a3fe12f576b82d58dfd2203cfc3fc5f2..4ae721e4a9c14af57773f7000ebf2cd4b79c8316 100644 (file)
@@ -742,8 +742,7 @@ The following options are useful only for clients (that is, if
     NUM must be between 1 and 1000, inclusive.  Note that the configured
     bandwidth limits are still expressed in bytes per second: this
     option only affects the frequency with which Tor checks to see whether
-    previously exhausted connections  may read again. This option is
-    if Tor was built with Libevent's bufferevents enabled. (Default: 10 msec.)
+    previously exhausted connections may read again. (Default: 10 msec.)
 
 **TrackHostExits** __host__,__.domain__,__...__::
     For each value in the comma separated list, Tor will track recent
index beae9502dae6c300c0693549a84c7622f832e099..32017387012fe6c3eeed4b20b6e461a98b1efd4f 100644 (file)
@@ -169,6 +169,7 @@ struct event_base *the_event_base = NULL;
 
 #ifdef USE_BUFFEREVENTS
 static int using_iocp_bufferevents = 0;
+static void tor_libevent_set_tick_timeout(int msec_per_tick);
 
 int
 tor_libevent_using_iocp_bufferevents(void)
@@ -236,6 +237,10 @@ tor_libevent_initialize(tor_libevent_cfg *torcfg)
       "You have a *VERY* old version of libevent.  It is likely to be buggy; "
       "please build Tor with a more recent version.");
 #endif
+
+#ifdef USE_BUFFEREVENTS
+  tor_libevent_set_tick_timeout(torcfg->msec_per_tick);
+#endif
 }
 
 /** Return the current Libevent event base that we're set up to use. */
@@ -598,26 +603,29 @@ static const struct timeval *one_tick = NULL;
 /**
  * Return a special timeout to be passed whenever libevent's O(1) timeout
  * implementation should be used. Only use this when the timer is supposed
- * to fire after 1 / TOR_LIBEVENT_TICKS_PER_SECOND seconds have passed.
+ * to fire after msec_per_tick ticks have elapsed.
 */
 const struct timeval *
 tor_libevent_get_one_tick_timeout(void)
 {
-  if (PREDICT_UNLIKELY(one_tick == NULL)) {
-    struct event_base *base = tor_libevent_get_base();
-    struct timeval tv;
-    if (TOR_LIBEVENT_TICKS_PER_SECOND == 1) {
-      tv.tv_sec = 1;
-      tv.tv_usec = 0;
-    } else {
-      tv.tv_sec = 0;
-      tv.tv_usec = 1000000 / TOR_LIBEVENT_TICKS_PER_SECOND;
-    }
-    one_tick = event_base_init_common_timeout(base, &tv);
-  }
+  tor_assert(one_tick);
   return one_tick;
 }
 
+/** Initialize the common timeout that we'll use to refill the buckets every
+ * time a tick elapses. */
+static void
+tor_libevent_set_tick_timeout(int msec_per_tick)
+{
+  struct event_base *base = tor_libevent_get_base();
+  struct timeval tv;
+
+  tor_assert(! one_tick);
+  tv.tv_sec = msec_per_tick / 1000;
+  tv.tv_usec = (msec_per_tick % 1000) * 1000;
+  one_tick = event_base_init_common_timeout(base, &tv);
+}
+
 static struct bufferevent *
 tor_get_root_bufferevent(struct bufferevent *bev)
 {
index 15b0fc273b08a1966c4896e9f30e44a352cae388..02472971774290804ecded93f9adc890ae4a817f 100644 (file)
@@ -62,6 +62,7 @@ int tor_event_base_loopexit(struct event_base *base, struct timeval *tv);
 typedef struct tor_libevent_cfg {
   int disable_iocp;
   int num_cpus;
+  int msec_per_tick;
 } tor_libevent_cfg;
 
 void tor_libevent_initialize(tor_libevent_cfg *cfg);
@@ -73,7 +74,6 @@ void tor_check_libevent_header_compatibility(void);
 const char *tor_libevent_get_version_str(void);
 
 #ifdef USE_BUFFEREVENTS
-#define TOR_LIBEVENT_TICKS_PER_SECOND 3
 const struct timeval *tor_libevent_get_one_tick_timeout(void);
 int tor_libevent_using_iocp_bufferevents(void);
 int tor_set_bufferevent_rate_limit(struct bufferevent *bev,
index 5a7a5906851a12be7ecaefd4845e4258fc1de9f1..e22f539aded09f202d9eca1b32aa71ab9f0a012a 100644 (file)
@@ -5645,6 +5645,7 @@ init_libevent(const or_options_t *options)
   memset(&cfg, 0, sizeof(cfg));
   cfg.disable_iocp = options->DisableIOCP;
   cfg.num_cpus = get_num_cpus(options);
+  cfg.msec_per_tick = options->TokenBucketRefillInterval;
 
   tor_libevent_initialize(&cfg);
 
index cb93a81e4eae3849a4ca21aa6bb6b674c828ea5d..9dd92972e13eaa30ca07c592a6bb085c78bafd35 100644 (file)
@@ -2561,7 +2561,10 @@ connection_bucket_init(void)
     burst = options->BandwidthBurst;
   }
 
-  rate /= TOR_LIBEVENT_TICKS_PER_SECOND;
+  /* This can't overflow, since TokenBucketRefillInterval <= 1000,
+   * and rate started out less than INT32_MAX. */
+  rate = (rate * options->TokenBucketRefillInterval) / 1000;
+
   bucket_cfg = ev_token_bucket_cfg_new((uint32_t)rate, (uint32_t)burst,
                                        (uint32_t)rate, (uint32_t)burst,
                                        tick);
index a75444e1ed01121bdd5efca89f1fcd8fee1df555..29f0f8de7247941e512e535d0f506c895657fbcc 100644 (file)
@@ -580,7 +580,12 @@ connection_or_update_token_buckets_helper(or_connection_t *conn, int reset,
   {
     const struct timeval *tick = tor_libevent_get_one_tick_timeout();
     struct ev_token_bucket_cfg *cfg, *old_cfg;
-    int rate_per_tick = rate / TOR_LIBEVENT_TICKS_PER_SECOND;
+    int64_t rate64 = (((int64_t)rate) * options->TokenBucketRefillInterval)
+      / 1000;
+    /* This can't overflow, since TokenBucketRefillInterval <= 1000,
+     * and rate started out less than INT_MAX. */
+    int rate_per_tick = (int) rate64;
+
     cfg = ev_token_bucket_cfg_new(rate_per_tick, burst, rate_per_tick,
                                   burst, tick);
     old_cfg = conn->bucket_cfg;