aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@redhat.com>2015-11-27 15:41:18 +0100
committerMichael S. Tsirkin <mst@redhat.com>2015-12-02 16:42:26 +0200
commit9732baf67850dac57dfc7dc8980bf408889a8973 (patch)
tree1e76601c535c6809a6d00ebff8201d663f1fe8ce
parent9d7b969ea6d9663a94760c6c131481b366f4d38a (diff)
vhost-user-test: fix chardriver race
vhost-user-tests uses a helper thread to dispatch the vhost-user servers sources. However the CharDriverState is not thread-safe. Therefore, when it's given to the thread, it shouldn't be manipulated concurrently. We dispatch cleaning the server in an idle source. By the end of the test, we ensure not to leave anything behind by joining the thread and finishing the sources dispatch. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
-rw-r--r--tests/vhost-user-test.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c
index e4c36afbda..261f4b711a 100644
--- a/tests/vhost-user-test.c
+++ b/tests/vhost-user-test.c
@@ -216,8 +216,7 @@ static void read_guest_mem(TestServer *s)
static void *thread_function(void *data)
{
- GMainLoop *loop;
- loop = g_main_loop_new(NULL, FALSE);
+ GMainLoop *loop = data;
g_main_loop_run(loop);
return NULL;
}
@@ -389,7 +388,7 @@ static TestServer *test_server_new(const gchar *name)
g_strdup_printf(QEMU_CMD extra, (mem), (mem), (root), (s)->chr_name, \
(s)->socket_path, (s)->chr_name, ##__VA_ARGS__)
-static void test_server_free(TestServer *server)
+static gboolean _test_server_free(TestServer *server)
{
int i;
@@ -406,9 +405,15 @@ static void test_server_free(TestServer *server)
unlink(server->socket_path);
g_free(server->socket_path);
-
g_free(server->chr_name);
g_free(server);
+
+ return FALSE;
+}
+
+static void test_server_free(TestServer *server)
+{
+ g_idle_add((GSourceFunc)_test_server_free, server);
}
static void wait_for_log_fd(TestServer *s)
@@ -590,6 +595,8 @@ int main(int argc, char **argv)
char *qemu_cmd = NULL;
int ret;
char template[] = "/tmp/vhost-test-XXXXXX";
+ GMainLoop *loop;
+ GThread *thread;
g_test_init(&argc, &argv, NULL);
@@ -612,8 +619,9 @@ int main(int argc, char **argv)
server = test_server_new("test");
+ loop = g_main_loop_new(NULL, FALSE);
/* run the main loop thread so the chardev may operate */
- g_thread_new(NULL, thread_function, NULL);
+ thread = g_thread_new(NULL, thread_function, loop);
qemu_cmd = GET_QEMU_CMD(server);
@@ -632,6 +640,14 @@ int main(int argc, char **argv)
/* cleanup */
test_server_free(server);
+ /* finish the helper thread and dispatch pending sources */
+ g_main_loop_quit(loop);
+ g_thread_join(thread);
+ while (g_main_context_pending(NULL)) {
+ g_main_context_iteration (NULL, TRUE);
+ }
+ g_main_loop_unref(loop);
+
ret = rmdir(tmpfs);
if (ret != 0) {
g_test_message("unable to rmdir: path (%s): %s\n",