diff options
author | Volker Lendecke <vl@samba.org> | 2020-03-19 17:00:59 +0100 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2020-03-25 10:41:29 +0000 |
commit | be394406ee016c6bab75fcd96417554468cf495d (patch) | |
tree | 7b3dd90ede59b467fa4334757d824ac1af461381 /lib/async_req | |
parent | 79f55ba3271b54068535e97695f5d6065a7048a5 (diff) | |
download | samba-be394406ee016c6bab75fcd96417554468cf495d.tar.gz |
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 <vl@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Autobuild-User(master): Stefan Metzmacher <metze@samba.org>
Autobuild-Date(master): Wed Mar 25 10:41:29 UTC 2020 on sn-devel-184
Diffstat (limited to 'lib/async_req')
-rw-r--r-- | lib/async_req/async_sock.c | 71 |
1 files changed, 44 insertions, 27 deletions
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) |