[ovs-dev] [PATCH 1/2] test-vconn: Block in three cases where a race is visible on FreeBSD.

Ben Pfaff blp at nicira.com
Tue Jul 31 17:12:20 UTC 2012


On FreeBSD, sometimes plain vconn_connect() or vconn_recv() reports EAGAIN
in these cases.

Reported-by: Ed Maste <emaste at freebsd.org>
Signed-off-by: Ben Pfaff <blp at nicira.com>
---
 lib/vconn.c        |   26 +++++++++++++++++++-------
 lib/vconn.h        |    3 ++-
 tests/test-vconn.c |    6 +++---
 3 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/lib/vconn.c b/lib/vconn.c
index caa1bcc..cbe3c77 100644
--- a/lib/vconn.c
+++ b/lib/vconn.c
@@ -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)
diff --git a/lib/vconn.h b/lib/vconn.h
index fd8bb25..3bb4450 100644
--- a/lib/vconn.h
+++ b/lib/vconn.h
@@ -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 **);
 
diff --git a/tests/test-vconn.c b/tests/test-vconn.c
index f37bc38..b3a9b2f 100644
--- a/tests/test-vconn.c
+++ b/tests/test-vconn.c
@@ -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);
 }
 
-- 
1.7.2.5




More information about the dev mailing list