From: Volker Lendecke Date: Thu, 19 Mar 2020 16:00:59 +0000 (+0100) Subject: lib: Try nonblocking writes in writev_send() X-Git-Tag: ldb-2.2.0~1221 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=be394406ee016c6bab75fcd96417554468cf495d;p=thirdparty%2Fsamba.git lib: Try nonblocking writes in writev_send() All callers now use nonblocking sockets, so that we can optimize by doing early writes Signed-off-by: Volker Lendecke Reviewed-by: Stefan Metzmacher Autobuild-User(master): Stefan Metzmacher Autobuild-Date(master): Wed Mar 25 10:41:29 UTC 2020 on sn-devel-184 --- diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 2f36da889bd..8f04a7bcbae 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -296,6 +296,9 @@ struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, if (tevent_req_nomem(state->queue_entry, req)) { return tevent_req_post(req, ev); } + if (!tevent_req_is_in_progress(req)) { + return tevent_req_post(req, ev); + } return req; } @@ -327,12 +330,52 @@ static bool writev_cancel(struct tevent_req *req) return true; } +static void writev_do(struct tevent_req *req, struct writev_state *state) +{ + ssize_t written; + bool ok; + + written = writev(state->fd, state->iov, state->count); + if ((written == -1) && + ((errno == EINTR) || + (errno == EAGAIN) || + (errno == EWOULDBLOCK))) { + /* retry after going through the tevent loop */ + return; + } + if (written == -1) { + tevent_req_error(req, errno); + return; + } + if (written == 0) { + tevent_req_error(req, EPIPE); + return; + } + state->total_size += written; + + ok = iov_advance(&state->iov, &state->count, written); + if (!ok) { + tevent_req_error(req, EIO); + return; + } + + if (state->count == 0) { + tevent_req_done(req); + return; + } +} + static void writev_trigger(struct tevent_req *req, void *private_data) { struct writev_state *state = tevent_req_data(req, struct writev_state); state->queue_entry = NULL; + writev_do(req, state); + if (!tevent_req_is_in_progress(req)) { + return; + } + state->fde = tevent_add_fd(state->ev, state, state->fd, state->flags, writev_handler, req); if (tevent_req_nomem(state->fde, req)) { @@ -347,8 +390,6 @@ static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde, private_data, struct tevent_req); struct writev_state *state = tevent_req_data(req, struct writev_state); - ssize_t written; - bool ok; if ((state->flags & TEVENT_FD_READ) && (flags & TEVENT_FD_READ)) { int ret, value; @@ -382,31 +423,7 @@ static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde, } } - written = writev(state->fd, state->iov, state->count); - if ((written == -1) && (errno == EINTR)) { - /* retry */ - return; - } - if (written == -1) { - tevent_req_error(req, errno); - return; - } - if (written == 0) { - tevent_req_error(req, EPIPE); - return; - } - state->total_size += written; - - ok = iov_advance(&state->iov, &state->count, written); - if (!ok) { - tevent_req_error(req, EIO); - return; - } - - if (state->count == 0) { - tevent_req_done(req); - return; - } + writev_do(req, state); } ssize_t writev_recv(struct tevent_req *req, int *perrno)