From 5a9052e0576a4dea4ad2385acde63cf53e62d5ef Mon Sep 17 00:00:00 2001 From: Richard Yu Date: Sat, 27 Jun 2026 15:19:44 +0800 Subject: [PATCH] ubusd: avoid client_cb stalls after short reads client_cb() uses edge-triggered uloop events for client sockets. If a recvmsg() or read() returns fewer bytes than requested, there may still be data buffered on the socket, but no further read event is guaranteed. After making progress on an incomplete header or message body, retry the receive path immediately instead of returning to the event loop. Also treat a zero-length recvmsg() as no progress/EOF, avoiding a retry loop on a closed connection. Signed-off-by: Richard Yu --- ubusd_main.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/ubusd_main.c b/ubusd_main.c index 14d3be2..ce20009 100644 --- a/ubusd_main.c +++ b/ubusd_main.c @@ -139,15 +139,17 @@ static void client_cb(struct uloop_fd *sock, unsigned int events) } bytes = recvmsg(sock->fd, &msghdr, 0); - if (bytes < 0) + if (bytes <= 0) goto out; if (*pfd >= 0) cl->pending_msg_fd = *pfd; cl->pending_msg_offset += bytes; - if (cl->pending_msg_offset < (int) sizeof(cl->hdrbuf)) - goto out; + if (cl->pending_msg_offset < (int) sizeof(cl->hdrbuf)) { + /* Keep draining; edge-triggered uloop may not fire again. */ + goto retry; + } if (blob_raw_len(&cl->hdrbuf.data) < sizeof(struct blob_attr)) goto disconnect; @@ -179,7 +181,8 @@ static void client_cb(struct uloop_fd *sock, unsigned int events) if (bytes < len) { cl->pending_msg_offset += bytes; - goto out; + /* Keep draining; edge-triggered uloop may not fire again. */ + goto retry; } /* accept message */