read_packet_handler_do_recv recvmsg
authorStefan Metzmacher <metze@samba.org>
Tue, 20 Apr 2021 14:46:20 +0000 (14:46 +0000)
committerStefan Metzmacher <metze@samba.org>
Wed, 8 Feb 2023 09:28:42 +0000 (10:28 +0100)
lib/async_req/async_sock.c

index cdd48dbdceb884cbfb80851e731f3651e6b94f20..11a216491494e9367a545f6b4d53f447a66d1ec4 100644 (file)
@@ -456,6 +456,7 @@ struct read_packet_state {
 
 static void read_packet_cleanup(struct tevent_req *req,
                                 enum tevent_req_state req_state);
+static void read_packet_handler_do_recv(struct tevent_req *req);
 static void read_packet_handler(struct tevent_context *ev,
                                struct tevent_fd *fde,
                                uint16_t flags, void *private_data);
@@ -487,6 +488,11 @@ struct tevent_req *read_packet_send(TALLOC_CTX *mem_ctx,
                return tevent_req_post(req, ev);
        }
 
+       read_packet_handler_do_recv(req);
+       if (!tevent_req_is_in_progress(req)) {
+               return tevent_req_post(req, ev);
+       }
+
        state->fde = tevent_add_fd(ev, state, fd,
                                   TEVENT_FD_READ, read_packet_handler,
                                   req);
@@ -511,14 +517,39 @@ static void read_packet_handler(struct tevent_context *ev,
 {
        struct tevent_req *req = talloc_get_type_abort(
                private_data, struct tevent_req);
+
+       read_packet_handler_do_recv(req);
+}
+
+static void read_packet_handler_do_recv(struct tevent_req *req)
+{
        struct read_packet_state *state =
                tevent_req_data(req, struct read_packet_state);
-       size_t total = talloc_get_size(state->buf);
+       size_t total;
        ssize_t nread, more;
        uint8_t *tmp;
+       struct iovec iov = {
+               .iov_len = 0,
+       };
+       struct msghdr msg = {
+               .msg_iovlen = 0,
+       };
+       unsigned recvmsg_flags = MSG_DONTWAIT | MSG_NOSIGNAL;
+
+again:
+       total = talloc_get_size(state->buf);
+       iov = (struct iovec) {
+               .iov_base = (void *)(state->buf+state->nread),
+               .iov_len = total-state->nread,
+       };
+       msg = (struct msghdr) {
+               .msg_iov = &iov,
+               .msg_iovlen = 1,
+       };
 
-       nread = recv(state->fd, state->buf+state->nread, total-state->nread,
-                    0);
+       nread = recvmsg(state->fd, &msg, recvmsg_flags);
+       //nread = recv(state->fd, state->buf+state->nread, total-state->nread,
+       //           0);
        if ((nread == -1) && (errno == ENOTSOCK)) {
                nread = read(state->fd, state->buf+state->nread,
                             total-state->nread);
@@ -527,6 +558,20 @@ static void read_packet_handler(struct tevent_context *ev,
                /* retry */
                return;
        }
+       if ((nread == -1) && (errno == EAGAIN)) {
+               /* retry */
+               return;
+       }
+       if ((nread == -1) && (errno == ENOMEM)) {
+               /* retry */
+               return;
+       }
+#ifdef EWOULDBLOCK
+       if ((nread == -1) && (errno == EWOULDBLOCK)) {
+               /* retry */
+               return;
+       }
+#endif /* EWOULDBLOCK */
        if (nread == -1) {
                tevent_req_error(req, errno);
                return;
@@ -573,6 +618,8 @@ static void read_packet_handler(struct tevent_context *ev,
                return;
        }
        state->buf = tmp;
+
+       goto again;
 }
 
 ssize_t read_packet_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,