]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
lib: Try nonblocking writes in writev_send()
authorVolker Lendecke <vl@samba.org>
Thu, 19 Mar 2020 16:00:59 +0000 (17:00 +0100)
committerStefan Metzmacher <metze@samba.org>
Wed, 25 Mar 2020 10:41:29 +0000 (10:41 +0000)
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

lib/async_req/async_sock.c

index 2f36da889bda9891eee98bf9ceedd8875e0e03e6..8f04a7bcbae804dcc5d9e6ccec9c6e7c8eb7814d 100644 (file)
@@ -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)