rconn: Fix bug #100, "Inactivity time-out slow under heavy load."
authorBen Pfaff <blp@nicira.com>
Fri, 22 Aug 2008 17:34:15 +0000 (10:34 -0700)
committerBen Pfaff <blp@nicira.com>
Fri, 22 Aug 2008 17:34:15 +0000 (10:34 -0700)
The timeout() function returns a duration relative to the time at which the
current state was entered, but rconn_run_wait() was treating it as the
waiting time remaining.

lib/rconn.c

index 671a584d3b387e90a7f80f9bdbc68cfae7c9112f..931338478c566549b55c09be9929e73fdf4afd77 100644 (file)
@@ -110,6 +110,7 @@ struct rconn {
 };
 
 static unsigned int sat_add(unsigned int x, unsigned int y);
+static unsigned int sat_sub(unsigned int x, unsigned int y);
 static unsigned int sat_mul(unsigned int x, unsigned int y);
 static unsigned int elapsed_in_this_state(const struct rconn *);
 static unsigned int timeout(const struct rconn *);
@@ -396,7 +397,9 @@ rconn_run_wait(struct rconn *rc)
 {
     unsigned int timeo = timeout(rc);
     if (timeo != UINT_MAX) {
-        poll_timer_wait(sat_mul(timeo, 1000));
+        unsigned int expires = sat_add(rc->state_entered, timeo);
+        unsigned int remaining = sat_sub(expires, time_now());
+        poll_timer_wait(sat_mul(remaining, 1000));
     }
 
     if ((rc->state & (S_ACTIVE | S_IDLE)) && rc->txq.n) {
@@ -676,6 +679,12 @@ sat_add(unsigned int x, unsigned int y)
     return x + y >= x ? x + y : UINT_MAX;
 }
 
+static unsigned int
+sat_sub(unsigned int x, unsigned int y)
+{
+    return x >= y ? x - y : 0;
+}
+
 static unsigned int
 sat_mul(unsigned int x, unsigned int y)
 {