rconn: Reconnect reliably when underlying vconn reports error.
authorBen Pfaff <blp@nicira.com>
Tue, 29 Jul 2008 00:29:26 +0000 (17:29 -0700)
committerBen Pfaff <blp@nicira.com>
Tue, 29 Jul 2008 00:31:18 +0000 (17:31 -0700)
commit5147d004899fb7979878ff59b879b88f1c66d0bf
tree56eb7cab0b84a141671c8ad8675a38a713a3d2c1
parent15c94784deeb7fd25cb3c45ed4c746eef1fe94ca
rconn: Reconnect reliably when underlying vconn reports error.

When a vconn reports an error, the rconn would not reliably reconnect.
In particular, if the error was reported after the call to rconn_run()
but before rconn_run_wait() was called, then the state's "run" routine
would not set min_timeout properly, leading to a potentially arbitrarily
long wait (depending on what other events were going on in) until the
state's "run" routine was called again.

The fix is to have a separate per-state "timeout" routine to compute
when the state needs to be re-entered.

This commit was tested using the following change to randomly inject
errors:

@@ -554,11 +554,16 @@
 static int
 try_send(struct rconn *rc)
 {
     int retval = 0;
     struct buffer *next = rc->txq.head->next;
-    retval = vconn_send(rc->vconn, rc->txq.head);
+    if (!random_range(1000)) {
+        fprintf(stderr, "injecting ECONNRESET\n");
+        retval = ECONNRESET;
+    } else {
+        retval = vconn_send(rc->vconn, rc->txq.head);
+    }
     if (retval) {
         if (retval != EAGAIN) {
             disconnect(rc, retval);
         }
         return retval;
lib/rconn.c