From: Stefan Metzmacher Date: Mon, 28 Apr 2025 15:38:15 +0000 (+0200) Subject: async_sock: let writev_do() try sendmsg() first X-Git-Tag: tevent-0.17.0~213 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=75ca6f5aa08251885b1ba414ed72afc272f20f93;p=thirdparty%2Fsamba.git async_sock: let writev_do() try sendmsg() first This is typically more efficient on the kernel call stack. As far as I can see writev_send/recv is only used with sockets so far, but in any case we fallback on ENOTSOCK. Signed-off-by: Stefan Metzmacher Reviewed-by: Volker Lendecke --- diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c index 795a2c63dba..2185961ea3c 100644 --- a/lib/async_req/async_sock.c +++ b/lib/async_req/async_sock.c @@ -235,6 +235,7 @@ struct writev_state { struct tevent_context *ev; struct tevent_queue_entry *queue_entry; int fd; + bool is_sock; struct tevent_fd *fde; struct iovec *iov; int count; @@ -264,6 +265,7 @@ struct tevent_req *writev_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, } state->ev = ev; state->fd = fd; + state->is_sock = true; state->total_size = 0; state->count = count; state->iov = (struct iovec *)talloc_memdup( @@ -341,7 +343,20 @@ 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 (state->is_sock) { + struct msghdr msg = { + .msg_iov = state->iov, + .msg_iovlen = state->count, + }; + + written = sendmsg(state->fd, &msg, 0); + if ((written == -1) && (errno == ENOTSOCK)) { + state->is_sock = false; + } + } + if (!state->is_sock) { + written = writev(state->fd, state->iov, state->count); + } if ((written == -1) && ((errno == EINTR) || (errno == EAGAIN) ||