]> sourceware.org Git - lvm2.git/commitdiff
libdaemon: Use select to yield CPU on a blocked read or write.
authorPetr Rockai <prockai@redhat.com>
Sun, 20 Jul 2014 23:53:48 +0000 (01:53 +0200)
committerPetr Rockai <prockai@redhat.com>
Thu, 5 Feb 2015 12:47:20 +0000 (13:47 +0100)
libdaemon/client/daemon-io.c

index 6d81ed86e7b727b9ac02216f6a165dcccbf03171..d19acd64192a379fc9389d3c5df1255de93d50e1 100644 (file)
@@ -49,9 +49,18 @@ int buffer_read(int fd, struct buffer *buffer) {
                } else if (result == 0) {
                        errno = ECONNRESET;
                        return 0; /* we should never encounter EOF here */
-               } else if (result < 0 && errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR)
+               } else if (result < 0 && ( errno == EAGAIN || errno == EWOULDBLOCK ||
+                                          errno == EINTR || errno == EIO)) {
+                       struct timeval tval;
+                       fd_set in;
+                       tval.tv_sec = 1;
+                       tval.tv_usec = 0;
+                       FD_ZERO(&in);
+                       FD_SET(fd, &in);
+                       /* ignore the result, this is just a glorified sleep */
+                       select(FD_SETSIZE, &in, NULL, NULL, NULL);
+               } else if (result < 0)
                        return 0;
-               /* TODO call select here if we encountered EAGAIN/EWOULDBLOCK/EINTR */
        }
 
        return 1;
@@ -60,8 +69,6 @@ int buffer_read(int fd, struct buffer *buffer) {
 /*
  * Write a buffer to a filedescriptor. Keep trying. Blocks (even on
  * SOCK_NONBLOCK) until all of the write went through.
- *
- * TODO use select on EWOULDBLOCK/EAGAIN/EINTR to avoid useless spinning
  */
 int buffer_write(int fd, const struct buffer *buffer) {
        static const struct buffer _terminate = { .mem = (char *) "\n##\n", .used = 4 };
@@ -74,7 +81,17 @@ int buffer_write(int fd, const struct buffer *buffer) {
                        result = write(fd, use->mem + written, use->used - written);
                        if (result > 0)
                                written += result;
-                       else if (result < 0 && errno != EWOULDBLOCK && errno != EAGAIN && errno != EINTR)
+                       else if (result < 0 && ( errno == EAGAIN || errno == EWOULDBLOCK ||
+                                                errno == EINTR || errno == EIO)) {
+                               struct timeval tval;
+                               fd_set out;
+                               tval.tv_sec = 1;
+                               tval.tv_usec = 0;
+                               FD_ZERO(&out);
+                               FD_SET(fd, &out);
+                               /* ignore the result, this is just a glorified sleep */
+                               select(FD_SETSIZE, NULL, &out, NULL, NULL);
+                       } else if (result < 0)
                                return 0; /* too bad */
                }
        }
This page took 0.036339 seconds and 5 git commands to generate.