summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPetr Rockai <prockai@redhat.com>2014-07-21 01:53:48 +0200
committerPetr Rockai <prockai@redhat.com>2014-11-20 12:36:45 +0100
commit7c4b3ba456562a5c18033b69297f230b43444ea0 (patch)
treefb6f283ac933452a8a750210473297bde51a66ce
parentc48ee57de1438cabaa050286e3a7ce1a6b588fc3 (diff)
downloadlvm2-7c4b3ba456562a5c18033b69297f230b43444ea0.tar.gz
libdaemon: Use select to yield CPU on a blocked read or write.
-rw-r--r--libdaemon/client/daemon-io.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/libdaemon/client/daemon-io.c b/libdaemon/client/daemon-io.c
index 6d81ed86e..d19acd641 100644
--- a/libdaemon/client/daemon-io.c
+++ b/libdaemon/client/daemon-io.c
@@ -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 */
}
}