Avoid client calls to recv() without prior poll()
authorjames rizzo <james.rizzo@broadcom.com>
Thu, 16 Dec 2021 20:13:51 +0000 (13:13 -0700)
committerjames rizzo <james.rizzo@broadcom.com>
Thu, 16 Dec 2021 20:13:51 +0000 (13:13 -0700)
Signed-off-by: james rizzo <james.rizzo@broadcom.com>
client.c
server.c
server.h

index 8b230617f79bd0dbab6853e9388a1e7fa8f700ce..0bcee29b571e1e72b24d92438f79a272a158464b 100644 (file)
--- a/client.c
+++ b/client.c
@@ -284,9 +284,10 @@ static int fio_client_dec_jobs_eta(struct client_eta *eta, client_eta_op eta_fn)
 static void fio_drain_client_text(struct fio_client *client)
 {
        do {
-               struct fio_net_cmd *cmd;
+               struct fio_net_cmd *cmd = NULL;
 
-               cmd = fio_net_recv_cmd(client->fd, false);
+               if (fio_server_poll_fd(client->fd, POLLIN, 0))
+                       cmd = fio_net_recv_cmd(client->fd, false);
                if (!cmd)
                        break;
 
index 90c52e01ac231f4972bbd94e91361d3fe61ad132..1f627e8f116acbbd3456552ed87986960eed011b 100644 (file)
--- a/server.c
+++ b/server.c
@@ -250,6 +250,27 @@ static int fio_send_data(int sk, const void *p, unsigned int len)
        return fio_sendv_data(sk, &iov, 1);
 }
 
+bool fio_server_poll_fd(int fd, short events, int timeout) {
+       struct pollfd pfd = {
+               .fd     = fd,
+               .events = events,
+       };
+       int ret;
+
+       ret = poll(&pfd, 1, timeout);
+       if (ret < 0) {
+               if (errno == EINTR)
+                       return false;
+               log_err("fio: poll: %s\n", strerror(errno));
+               return false;
+       } else if (!ret) {
+               return false;
+       }
+       if (pfd.revents & events)
+               return true;
+       return false;
+}
+
 static int fio_recv_data(int sk, void *buf, unsigned int len, bool wait)
 {
        int flags;
@@ -1238,7 +1259,8 @@ static int handle_connection(struct sk_out *sk_out)
                if (ret < 0)
                        break;
 
-               cmd = fio_net_recv_cmd(sk_out->sk, true);
+               if (pfd.revents & POLLIN)
+                       cmd = fio_net_recv_cmd(sk_out->sk, true);
                if (!cmd) {
                        ret = -1;
                        break;
index 25b6bbdc25dfb6f6f45e7ddb318d6a5cb9030156..75600df209f874738d94e532dc427e313ba0311f 100644 (file)
--- a/server.h
+++ b/server.h
@@ -222,6 +222,7 @@ extern void fio_server_send_gs(struct group_run_stats *);
 extern void fio_server_send_du(void);
 extern void fio_server_send_job_options(struct flist_head *, unsigned int);
 extern int fio_server_get_verify_state(const char *, int, void **);
+extern bool fio_server_poll_fd(int fd, short events, int timeout);
 
 extern struct fio_net_cmd *fio_net_recv_cmd(int sk, bool wait);