1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

libdaemon: Use select to yield CPU on a blocked read or write.

This commit is contained in:
Petr Rockai 2014-07-21 01:53:48 +02:00
parent 19bb62e2ec
commit c2aa918c53

View File

@ -49,9 +49,18 @@ int buffer_read(int fd, struct buffer *buffer) {
} else if (result == 0) { } else if (result == 0) {
errno = ECONNRESET; errno = ECONNRESET;
return 0; /* we should never encounter EOF here */ 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; return 0;
/* TODO call select here if we encountered EAGAIN/EWOULDBLOCK/EINTR */
} }
return 1; 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 * Write a buffer to a filedescriptor. Keep trying. Blocks (even on
* SOCK_NONBLOCK) until all of the write went through. * 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) { int buffer_write(int fd, const struct buffer *buffer) {
static const struct buffer _terminate = { .mem = (char *) "\n##\n", .used = 4 }; 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); result = write(fd, use->mem + written, use->used - written);
if (result > 0) if (result > 0)
written += result; 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 */ return 0; /* too bad */
} }
} }