Patchwork [2/5] char: unix write: Add some sleep to ease off spinning in a tight loop

login
register
mail settings
Submitter Amit Shah
Date April 5, 2010, 12:45 p.m.
Message ID <1270471538-31275-3-git-send-email-amit.shah@redhat.com>
Download mbox | patch
Permalink /patch/49384/
State New
Headers show

Comments

Amit Shah - April 5, 2010, 12:45 p.m.
When the other end of a chardev connection isn't picking up data as
fast as we're sending, we just used to keep spinning in a tight loop
till all the data was sent out.

Polling for POLLOUT indefinitely gives the other end a chance to catch
up and also saves us CPU cycles.

Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
 qemu-char.c |   17 +++++++++++++++--
 1 files changed, 15 insertions(+), 2 deletions(-)

Patch

diff --git a/qemu-char.c b/qemu-char.c
index d5b1662..48e1e57 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -36,6 +36,7 @@ 
 
 #include <unistd.h>
 #include <fcntl.h>
+#include <poll.h>
 #include <signal.h>
 #include <time.h>
 #include <errno.h>
@@ -513,15 +514,27 @@  int send_all(int fd, const void *buf, size_t *len)
 
 static int unix_write(int fd, const uint8_t *buf, size_t *len)
 {
+    struct pollfd pollfds[1];
     ssize_t tmplen, ret;
 
+    pollfds[0].fd = fd;
+    pollfds[0].events = POLLOUT;
+
     tmplen = *len;
     *len = 0;
     while (tmplen > 0) {
+        ret = poll(pollfds, 1, -1);
+        if (ret == -1) {
+            if (errno == EINTR) {
+                continue;
+            }
+            return -1;
+        }
         ret = write(fd, buf, tmplen);
         if (ret < 0) {
-            if (errno != EINTR && errno != EAGAIN)
-                return -1;
+            if (errno != EINTR && errno != EAGAIN) {
+                 return -1;
+            }
         } else if (ret == 0) {
             break;
         } else {