From 82aafa4ac8b9751a044eaaa1796b15b0a88d1e6a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 12 Jan 2023 12:54:33 +0100 Subject: [PATCH] lib/async_req: let writev_send/recv use TEVENT_FD_ERROR Unless err_on_readability is true, we use TEVENT_FD_READ only to detect errors. Now that we have TEVENT_FD_ERROR we should use it. As a side effect it makes the code much simpler and clearer, as we can directly map TEVENT_FD_ERROR to EPIPE. In addition the err_on_readability=true case is now also clearer, where we just map TEVENT_FD_READ to EPIPE. Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme Reviewed-by: Andrew Bartlett --- lib/async_req/async_sock.c | 49 ++++++++++++++------------------------ 1 file changed, 18 insertions(+), 31 deletions(-) diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 533b247c13d..bdbefd162ac 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -278,8 +278,10 @@ struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, if (tevent_req_nomem(state->iov, req)) { return tevent_req_post(req, ev); } - state->flags = TEVENT_FD_WRITE|TEVENT_FD_READ; - state->err_on_readability = err_on_readability; + state->flags = TEVENT_FD_WRITE | TEVENT_FD_ERROR; + if (err_on_readability) { + state->flags |= TEVENT_FD_READ; + } tevent_req_set_cleanup_fn(req, writev_cleanup); tevent_req_set_cancel_fn(req, writev_cancel); @@ -402,36 +404,21 @@ static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde, struct writev_state *state = tevent_req_data(req, struct writev_state); - if ((state->flags & TEVENT_FD_READ) && (flags & TEVENT_FD_READ)) { - int ret, value; + if (flags & TEVENT_FD_ERROR) { + /* + * There's an error, for legacy reasons + * we just use EPIPE instead of a more + * detailed error using + * samba_socket_poll_or_sock_error(). + */ + tevent_req_error(req, EPIPE); + return; + } - if (state->err_on_readability) { - /* Readable and the caller wants an error on read. */ - tevent_req_error(req, EPIPE); - return; - } - - /* Might be an error. Check if there are bytes to read */ - ret = ioctl(state->fd, FIONREAD, &value); - /* FIXME - should we also check - for ret == 0 and value == 0 here ? */ - if (ret == -1) { - /* There's an error. */ - tevent_req_error(req, EPIPE); - return; - } - /* A request for TEVENT_FD_READ will succeed from now and - forevermore until the bytes are read so if there was - an error we'll wait until we do read, then get it in - the read callback function. Until then, remove TEVENT_FD_READ - from the flags we're waiting for. */ - state->flags &= ~TEVENT_FD_READ; - TEVENT_FD_NOT_READABLE(fde); - - /* If not writable, we're done. */ - if (!(flags & TEVENT_FD_WRITE)) { - return; - } + if (flags & TEVENT_FD_READ) { + /* Readable and the caller wants an error on read. */ + tevent_req_error(req, EPIPE); + return; } writev_do(req, state);