mrc0mmand / rpms / libguestfs

Forked from rpms/libguestfs 3 years ago
Clone
Blob Blame History Raw
From a5806c1b4be3f74b25ec733328259e7966af6af6 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Mon, 20 Jun 2016 10:18:22 +0100
Subject: [PATCH] p2v: Poll to make Cancel Conversion button more responsive.

Previously cancelling the conversion only set a flag, which was
checked when the run dialog displayed new output from virt-v2v.  When
virt-v2v was showing hundreds of debugging messages, this wasn't a
problem, but now that we are hiding those messages, cancelling the
conversion might mean a wait of seconds or minutes.

By polling (albeit infrequently) we can make the cancel button more
responsive.

(cherry picked from commit 6da4941db7f8a85997d6281b9b4c5165768e6489)
---
 p2v/conversion.c | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/p2v/conversion.c b/p2v/conversion.c
index b54f971..de2a4b2 100644
--- a/p2v/conversion.c
+++ b/p2v/conversion.c
@@ -25,6 +25,7 @@
 #include <fcntl.h>
 #include <inttypes.h>
 #include <unistd.h>
+#include <poll.h>
 #include <time.h>
 #include <errno.h>
 #include <error.h>
@@ -346,13 +347,35 @@ start_conversion (struct config *config,
   }
 
   /* Read output from the virt-v2v process and echo it through the
-   * notify function, until virt-v2v closes the connection.
+   * notify function, until virt-v2v closes the connection.  We
+   * actually poll in this loop (albeit it only every 2 seconds) so
+   * that the user won't have to wait too long between pressing the
+   * cancel button and having the conversion cancelled.
    */
   while (!is_cancel_requested ()) {
+    int fd = mexp_get_fd (control_h);
+    struct pollfd fds[1];
+    int rp;
     char buf[257];
     ssize_t r;
 
-    r = read (mexp_get_fd (control_h), buf, sizeof buf - 1);
+    fds[0].fd = fd;
+    fds[0].events = POLLIN;
+    fds[0].revents = 0;
+    rp = poll (fds, 1, 2000 /* ms */);
+    if (rp == -1) {
+      /* See comment about this in miniexpect.c. */
+      if (errno == EIO)
+        break;
+      set_conversion_error ("poll: %m");
+      goto out;
+    }
+    else if (rp == 0)
+      /* Timeout. */
+      continue;
+    /* ... else rp == 1, ignore revents and just do the read. */
+
+    r = read (fd, buf, sizeof buf - 1);
     if (r == -1) {
       /* See comment about this in miniexpect.c. */
       if (errno == EIO)
-- 
1.8.3.1