test-vconn: Block in three cases where a race is visible on FreeBSD.
authorBen Pfaff <blp@nicira.com>
Tue, 31 Jul 2012 17:12:20 +0000 (10:12 -0700)
committerBen Pfaff <blp@nicira.com>
Wed, 1 Aug 2012 00:04:34 +0000 (17:04 -0700)
On FreeBSD, sometimes plain vconn_connect() or vconn_recv() reports EAGAIN
in these cases.

Reported-by: Ed Maste <emaste@freebsd.org>
Signed-off-by: Ben Pfaff <blp@nicira.com>
lib/vconn.c
lib/vconn.h
tests/test-vconn.c

index caa1bccfcae38c9b5d1d2372b36aafadefa4a76c..cbe3c77131d63f2d32a9a4a420bbf1982d74d0a4 100644 (file)
@@ -288,13 +288,7 @@ vconn_open_block(const char *name, enum ofp_version min_version,
 
     error = vconn_open(name, min_version, &vconn, DSCP_DEFAULT);
     if (!error) {
-        while ((error = vconn_connect(vconn)) == EAGAIN) {
-            vconn_run(vconn);
-            vconn_run_wait(vconn);
-            vconn_connect_wait(vconn);
-            poll_block();
-        }
-        assert(error != EINPROGRESS);
+        error = vconn_connect_block(vconn);
     }
 
     if (error) {
@@ -622,6 +616,24 @@ do_send(struct vconn *vconn, struct ofpbuf *msg)
     return retval;
 }
 
+/* Same as vconn_connect(), except that it waits until the connection on
+ * 'vconn' completes or fails.  Thus, it will never return EAGAIN. */
+int
+vconn_connect_block(struct vconn *vconn)
+{
+    int error;
+
+    while ((error = vconn_connect(vconn)) == EAGAIN) {
+        vconn_run(vconn);
+        vconn_run_wait(vconn);
+        vconn_connect_wait(vconn);
+        poll_block();
+    }
+    assert(error != EINPROGRESS);
+
+    return error;
+}
+
 /* Same as vconn_send, except that it waits until 'msg' can be transmitted. */
 int
 vconn_send_block(struct vconn *vconn, struct ofpbuf *msg)
index fd8bb2534b9a2d9759985e1249fe3deb8e44d6b6..3bb44507fdd86f7b049f71cbfa98f81ca86c32db 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010, 2011 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -56,6 +56,7 @@ void vconn_run_wait(struct vconn *);
 
 int vconn_open_block(const char *name, enum ofp_version min_version,
                      struct vconn **);
+int vconn_connect_block(struct vconn *);
 int vconn_send_block(struct vconn *, struct ofpbuf *);
 int vconn_recv_block(struct vconn *, struct ofpbuf **);
 
index f37bc38a863c14570a3b73340832ab9e7d5a7895..b3a9b2fe0d0653dee08c77113fb53818376370b2 100644 (file)
@@ -156,7 +156,7 @@ test_refuse_connection(int argc OVS_UNUSED, char *argv[])
                            DSCP_DEFAULT), 0);
     fpv_close(&fpv);
     vconn_run(vconn);
-    CHECK_ERRNO(vconn_connect(vconn), expected_error);
+    CHECK_ERRNO(vconn_connect_block(vconn), expected_error);
     vconn_close(vconn);
     fpv_destroy(&fpv);
 }
@@ -229,7 +229,7 @@ test_read_hello(int argc OVS_UNUSED, char *argv[])
        poll_block();
     }
     stream_close(stream);
-    CHECK_ERRNO(vconn_connect(vconn), ECONNRESET);
+    CHECK_ERRNO(vconn_connect_block(vconn), ECONNRESET);
     vconn_close(vconn);
 }
 
@@ -322,7 +322,7 @@ test_send_hello(const char *type, const void *out, size_t out_size,
        poll_block();
     }
     stream_close(stream);
-    CHECK_ERRNO(vconn_recv(vconn, &msg), EOF);
+    CHECK_ERRNO(vconn_recv_block(vconn, &msg), EOF);
     vconn_close(vconn);
 }