From d3ea16dd8a98d939dc32da5dd92f3d35eaa111d8 Mon Sep 17 00:00:00 2001 From: Andrey Dodonov Date: Thu, 4 Jul 2024 16:51:18 +0200 Subject: [PATCH] net: lib: websocket: call socket poll for websocket If we couldn't send all (or any data) via the socket, invoke poll instead of blindly retrying and flooding the socket. Signed-off-by: Andrey Dodonov --- subsys/net/lib/websocket/websocket.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/subsys/net/lib/websocket/websocket.c b/subsys/net/lib/websocket/websocket.c index ceeec5823e61efa..0244af7da61a3cd 100644 --- a/subsys/net/lib/websocket/websocket.c +++ b/subsys/net/lib/websocket/websocket.c @@ -544,11 +544,12 @@ static int websocket_ioctl_vmeth(void *obj, unsigned int request, va_list args) } #if !defined(CONFIG_NET_TEST) -static int sendmsg_all(int sock, const struct msghdr *message, int flags) +static int sendmsg_all(int sock, const struct msghdr *message, int flags, int32_t timeout) { int ret, i; size_t offset = 0; size_t total_len = 0; + int64_t timestamp = k_uptime_get(); for (i = 0; i < message->msg_iovlen; i++) { total_len += message->msg_iov[i].iov_len; @@ -556,7 +557,26 @@ static int sendmsg_all(int sock, const struct msghdr *message, int flags) while (offset < total_len) { ret = zsock_sendmsg(sock, message, flags); - if (ret < 0) { + + if ((ret == 0) || (ret < 0 && errno == EAGAIN)) { + struct zsock_pollfd pfd; + int pollres; + + timeout -= (int32_t)k_uptime_delta(×tamp); + if (timeout < 0) { + /* timeout, make poll return immediately */ + timeout = 0; + } + + pfd.fd = sock; + pfd.events = ZSOCK_POLLOUT; + pollres = zsock_poll(&pfd, 1, timeout); + if (pollres >= 0) { + continue; + } else { + return -errno; + } + } else if (ret < 0) { return -errno; } @@ -623,7 +643,7 @@ static int websocket_prepare_and_send(struct websocket_context *ctx, } return sendmsg_all(ctx->real_sock, &msg, - K_TIMEOUT_EQ(tout, K_NO_WAIT) ? MSG_DONTWAIT : 0); + K_TIMEOUT_EQ(tout, K_NO_WAIT) ? MSG_DONTWAIT : 0, timeout); #endif /* CONFIG_NET_TEST */ }