net engine: use poll() always for sending/receiving
Avoids getting stuck waiting for data and not accepting signals.
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
diff --git a/engines/net.c b/engines/net.c
index 8dbc2a8..fd01089 100644
--- a/engines/net.c
+++ b/engines/net.c
@@ -28,6 +28,39 @@
struct sockaddr_in addr;
};
+/*
+ * Return -1 for error and 'nr events' for a positive number
+ * of events
+ */
+static int poll_wait(struct thread_data *td, int fd, short events)
+{
+ struct pollfd pfd;
+ int ret;
+
+ while (!td->terminate) {
+ pfd.fd = fd;
+ pfd.events = events;
+ ret = poll(&pfd, 1, -1);
+ if (ret < 0) {
+ if (errno == EINTR)
+ continue;
+
+ td_verror(td, errno, "poll");
+ return -1;
+ } else if (!ret)
+ continue;
+
+ break;
+ }
+
+ if (pfd.revents & events)
+ return 1;
+ else if (td->terminate)
+ return 1;
+
+ return -1;
+}
+
static int fio_netio_prep(struct thread_data *td, struct io_u *io_u)
{
struct netio_data *nd = td->io_ops->data;
@@ -182,7 +215,11 @@
static int fio_netio_send(struct thread_data *td, struct io_u *io_u)
{
struct netio_data *nd = td->io_ops->data;
- int flags = 0;
+ int ret, flags = 0;
+
+ ret = poll_wait(td, io_u->file->fd, POLLOUT);
+ if (ret <= 0)
+ return ret;
/*
* if we are going to write more, set MSG_MORE
@@ -194,7 +231,7 @@
if (nd->net_protocol == IPPROTO_UDP) {
return sendto(io_u->file->fd, io_u->xfer_buf, io_u->xfer_buflen,
- 0, &nd->addr, sizeof(nd->addr));
+ flags, &nd->addr, sizeof(nd->addr));
} else {
return send(io_u->file->fd, io_u->xfer_buf, io_u->xfer_buflen,
flags);
@@ -204,7 +241,11 @@
static int fio_netio_recv(struct thread_data *td, struct io_u *io_u)
{
struct netio_data *nd = td->io_ops->data;
- int flags = MSG_WAITALL;
+ int ret, flags = MSG_WAITALL;
+
+ ret = poll_wait(td, io_u->file->fd, POLLIN);
+ if (ret <= 0)
+ return ret;
if (nd->net_protocol == IPPROTO_UDP) {
socklen_t len = sizeof(nd->addr);
@@ -289,8 +330,6 @@
{
struct netio_data *nd = td->io_ops->data;
socklen_t socklen = sizeof(nd->addr);
- struct pollfd pfd;
- int ret;
if (nd->net_protocol == IPPROTO_UDP) {
f->fd = nd->listenfd;
@@ -299,36 +338,13 @@
log_info("fio: waiting for connection\n");
- /*
- * Accept loop. poll for incoming events, accept them. Repeat until we
- * have all connections.
- */
- while (!td->terminate) {
- pfd.fd = nd->listenfd;
- pfd.events = POLLIN;
+ if (poll_wait(td, nd->listenfd, POLLIN) < 0)
+ return 1;
- ret = poll(&pfd, 1, -1);
- if (ret < 0) {
- if (errno == EINTR)
- continue;
-
- td_verror(td, errno, "poll");
- break;
- } else if (!ret)
- continue;
-
- /*
- * should be impossible
- */
- if (!(pfd.revents & POLLIN))
- continue;
-
- f->fd = accept(nd->listenfd, (struct sockaddr *) &nd->addr, &socklen);
- if (f->fd < 0) {
- td_verror(td, errno, "accept");
- return 1;
- }
- break;
+ f->fd = accept(nd->listenfd, (struct sockaddr *) &nd->addr, &socklen);
+ if (f->fd < 0) {
+ td_verror(td, errno, "accept");
+ return 1;
}
return 0;