summaryrefslogtreecommitdiff
path: root/lib/async_req
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2020-03-19 17:00:59 +0100
committerStefan Metzmacher <metze@samba.org>2020-03-25 10:41:29 +0000
commitbe394406ee016c6bab75fcd96417554468cf495d (patch)
tree7b3dd90ede59b467fa4334757d824ac1af461381 /lib/async_req
parent79f55ba3271b54068535e97695f5d6065a7048a5 (diff)
downloadsamba-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.c71
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)