]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
interactive: Avoid select(2) in input_available().
authorAndre Noll <maan@tuebingen.mpg.de>
Wed, 29 Sep 2021 20:29:51 +0000 (22:29 +0200)
committerAndre Noll <maan@tuebingen.mpg.de>
Thu, 25 Aug 2022 13:37:26 +0000 (15:37 +0200)
In analogy to write_ok(), introduce read_ok() which uses poll(2)
rather than select(2). To avoid duplications, abstract out the common
code to the new xpoll() helper.

We could avoid the timeout parameter of xpoll() at this point because
both callers call it with a zero timeout (causing poll() to return
immediately), but later patches introduce other callers which specify
non-zero timeouts.

fd.c
fd.h
interactive.c

diff --git a/fd.c b/fd.c
index 2f3ec997c11e796fc5ff8ada46c40a662e0aef13..63c0337b348e10705a92f53492d5ff4491ab4ac1 100644 (file)
--- a/fd.c
+++ b/fd.c
@@ -644,6 +644,33 @@ int para_munmap(void *start, size_t length)
        return -ERRNO_TO_PARA_ERROR(err);
 }
 
+static int xpoll(struct pollfd *fds, nfds_t nfds, int timeout)
+{
+       int ret;
+
+       do
+               ret = poll(fds, nfds, timeout);
+       while (ret < 0 && errno == EINTR);
+       return ret < 0? -ERRNO_TO_PARA_ERROR(errno) : ret;
+}
+
+/**
+ * Check a file descriptor for readability.
+ *
+ * \param fd The file descriptor.
+ *
+ * \return positive if fd is ready for reading, zero if it isn't, negative if
+ * an error occurred.
+ *
+ * \sa \ref write_ok().
+ */
+int read_ok(int fd)
+{
+       struct pollfd pfd = {.fd = fd, .events = POLLIN};
+       int ret = xpoll(&pfd, 1, 0);
+       return ret < 0? ret : pfd.revents & POLLIN;
+}
+
 /**
  * Check a file descriptor for writability.
  *
@@ -651,18 +678,14 @@ 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.
+ *
+ * \sa \ref read_ok().
  */
 int write_ok(int fd)
 {
-       int ret;
        struct pollfd pfd = {.fd = fd, .events = POLLOUT};
-
-       do
-               ret = poll(&pfd, 1, 0);
-       while (ret < 0 && errno == EINTR);
-       if (ret < 0)
-               return -ERRNO_TO_PARA_ERROR(errno);
-       return pfd.revents & POLLOUT;
+       int ret = xpoll(&pfd, 1, 0);
+       return ret < 0? ret : pfd.revents & POLLOUT;
 }
 
 /**
diff --git a/fd.h b/fd.h
index 820e1cc97452d5f4c577f86f789d504391e96b59..31b0c88c471b03cb02c2106c84a33fd0016a5b41 100644 (file)
--- a/fd.h
+++ b/fd.h
@@ -17,6 +17,7 @@ int para_chdir(const char *path);
 int mmap_full_file(const char *filename, int open_mode, void **map,
        size_t *size, int *fd_ptr);
 int para_munmap(void *start, size_t length);
+int read_ok(int fd);
 int write_ok(int fd);
 void valid_fd_012(void);
 int readv_nonblock(int fd, struct iovec *iov, int iovcnt, fd_set *rfds,
index 8e61484009cb73b5842485d9168c48aaea9e0002..3af90a6814d79e248178a3e47ae04cd066a8efad 100644 (file)
@@ -258,17 +258,6 @@ static void clear_bottom_line(void)
        rl_point = point;
 }
 
-static bool input_available(void)
-{
-       fd_set rfds;
-       int ret;
-
-       FD_ZERO(&rfds);
-       FD_SET(i9ep->ici->fds[0], &rfds);
-       ret = para_select(1, &rfds, NULL, 0);
-       return ret > 0;
-}
-
 static void i9e_line_handler(char *line)
 {
        int ret;
@@ -309,7 +298,7 @@ static int i9e_post_select(__a_unused struct sched *s, __a_unused void *context)
        ret = 0;
        if (i9ep->caught_sigint)
                goto rm_btrn;
-       while (input_available()) {
+       while (read_ok(i9ep->ici->fds[0]) > 0) {
                if (i9ep->stdout_btrn) {
                        while (i9ep->key_sequence_length < sizeof(i9ep->key_sequence) - 1) {
                                buf = i9ep->key_sequence + i9ep->key_sequence_length;
@@ -326,7 +315,7 @@ static int i9e_post_select(__a_unused struct sched *s, __a_unused void *context)
                                i9ep->key_sequence_length++;
                                rl_stuff_char((int)(unsigned char)*buf);
                                rl_callback_read_char();
-                               if (!input_available())
+                               if (read_ok(i9ep->ici->fds[0]) <= 0)
                                        break;
                        }
                        i9ep->key_sequence_length = 0;