]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - fd.c
fd.c: Prefer poll(2) over select(2) for write_ok().
[paraslash.git] / fd.c
diff --git a/fd.c b/fd.c
index ae5ef41379d94ea009e6647e62989c74e84cf2b8..2f3ec997c11e796fc5ff8ada46c40a662e0aef13 100644 (file)
--- a/fd.c
+++ b/fd.c
@@ -6,6 +6,7 @@
 #include <sys/types.h>
 #include <dirent.h>
 #include <sys/mman.h>
+#include <poll.h>
 
 #include "para.h"
 #include "error.h"
@@ -179,15 +180,15 @@ __printf_2_3 int write_va_buffer(int fd, const char *fmt, ...)
  * \param rfds An optional fd set pointer.
  * \param num_bytes Result pointer. Contains the number of bytes read from \a fd.
  *
- * If \a rfds is not \p NULL and the (non-blocking) file descriptor \a fd is
- * not set in \a rfds, this function returns early without doing anything.
- * Otherwise The function tries to read up to \a sz bytes from \a fd, where \a
- * sz is the sum of the lengths of all vectors in \a iov. As for xwrite(),
- * \p EAGAIN is not considered an error condition. However, \p EOF is.
+ * If rfds is not NULL and the (non-blocking) file descriptor fd is not set in
+ * rfds, this function returns early without doing anything. Otherwise it tries
+ * to read up to sz bytes from fd, where sz is the sum of the lengths of all
+ * vectors in iov. Like \ref xwrite(), EAGAIN and EINTR are not considered
+ * error conditions. However, EOF is.
  *
  * \return Zero or a negative error code. If the underlying call to readv(2)
  * returned zero (indicating an end of file condition) or failed for some
- * reason other than \p EAGAIN, a negative error code is returned.
+ * reason other than EAGAIN or EINTR, a negative error code is returned.
  *
  * In any case, \a num_bytes contains the number of bytes that have been
  * successfully read from \a fd (zero if the first readv() call failed with
@@ -226,7 +227,7 @@ int readv_nonblock(int fd, struct iovec *iov, int iovcnt, fd_set *rfds,
                if (ret == 0)
                        return -E_EOF;
                if (ret < 0) {
-                       if (errno == EAGAIN)
+                       if (errno == EAGAIN || errno == EINTR)
                                return 0;
                        return -ERRNO_TO_PARA_ERROR(errno);
                }
@@ -334,8 +335,7 @@ bool file_exists(const char *fn)
  * \param n The highest-numbered descriptor in any of the two sets, plus 1.
  * \param readfds fds that should be checked for readability.
  * \param writefds fds that should be checked for writablility.
- * \param timeout_tv upper bound on the amount of time elapsed before select()
- * returns.
+ * \param timeout Upper bound in milliseconds.
  *
  * \return The return value of the underlying select() call on success, the
  * negative system error code on errors.
@@ -343,12 +343,14 @@ bool file_exists(const char *fn)
  * All arguments are passed verbatim to select(2).
  * \sa select(2) select_tut(2).
  */
-int para_select(int n, fd_set *readfds, fd_set *writefds,
-               struct timeval *timeout_tv)
+int para_select(int n, fd_set *readfds, fd_set *writefds, int timeout)
 {
        int ret;
+       struct timeval tv;
+
+       ms2tv(timeout, &tv);
        do
-               ret = select(n, readfds, writefds, NULL, timeout_tv);
+               ret = select(n, readfds, writefds, NULL, &tv);
        while (ret < 0 && errno == EINTR);
        if (ret < 0)
                return -ERRNO_TO_PARA_ERROR(errno);
@@ -650,17 +652,17 @@ int para_munmap(void *start, size_t length)
  * \return positive if fd is ready for writing, zero if it isn't, negative if
  * an error occurred.
  */
-
 int write_ok(int fd)
 {
-       struct timeval tv;
-       fd_set wfds;
+       int ret;
+       struct pollfd pfd = {.fd = fd, .events = POLLOUT};
 
-       FD_ZERO(&wfds);
-       FD_SET(fd, &wfds);
-       tv.tv_sec = 0;
-       tv.tv_usec = 0;
-       return para_select(fd + 1, NULL, &wfds, &tv);
+       do
+               ret = poll(&pfd, 1, 0);
+       while (ret < 0 && errno == EINTR);
+       if (ret < 0)
+               return -ERRNO_TO_PARA_ERROR(errno);
+       return pfd.revents & POLLOUT;
 }
 
 /**