From 6d1fb217a904374316abdc9050db795129f72a13 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 31 Jul 2012 10:12:20 -0700 Subject: [PATCH] test-vconn: Block in three cases where a race is visible on FreeBSD. On FreeBSD, sometimes plain vconn_connect() or vconn_recv() reports EAGAIN in these cases. Reported-by: Ed Maste Signed-off-by: Ben Pfaff --- 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 caa1bccf..cbe3c771 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 fd8bb253..3bb44507 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 f37bc38a..b3a9b2fe 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); } -- 2.30.2