From 4fd07b23121e45fa4e7e434d23f3257c8a0ef588 Mon Sep 17 00:00:00 2001 From: james rizzo Date: Thu, 16 Dec 2021 13:13:51 -0700 Subject: [PATCH] Avoid client calls to recv() without prior poll() Signed-off-by: james rizzo --- client.c | 5 +++-- server.c | 24 +++++++++++++++++++++++- server.h | 1 + 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/client.c b/client.c index 8b230617..0bcee29b 100644 --- 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; diff --git a/server.c b/server.c index 90c52e01..1f627e8f 100644 --- 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; diff --git a/server.h b/server.h index 25b6bbdc..75600df2 100644 --- 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); -- 2.25.1