From 24b4eaa97c0ba3c45406ac293a35d78c5342aac8 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Mon, 4 Aug 2025 20:13:59 -0400 Subject: kernel: socket: Implement recv() timeout This commit implements proper timeout handling for recv(). Previously, the recv() syscall would yield the current process forver until data is available to be read. Obviously, that is not the most ideal as it is not uncommon for programs to try seeing if any data exists on the socket before deferring to perform some other task until data arrives. The basics of how this work is that we try reading data off of some specified socket. However, if no data is present, we must wait for the given timeout value before attempting to read again. While this is pretty effective and works perfectly fine as of now, it might be worth optimizing this later to allow that timeout period to be somehow "interrupted" by data arriving at a socket so that the program does not have to defer execution for the full wait-period. Signed-off-by: Ian Moffett --- sys/kern/kern_socket.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'sys/kern') diff --git a/sys/kern/kern_socket.c b/sys/kern/kern_socket.c index 55b7668..0b10d0c 100644 --- a/sys/kern/kern_socket.c +++ b/sys/kern/kern_socket.c @@ -741,10 +741,29 @@ sys_recv(struct syscall_args *scargs) return -ENOBUFS; } - do { + for (;;) { error = recv(sockfd, buf, len, flags); - sched_yield(); - } while (error == -EAGAIN); + if (error <= 0 && error != -EAGAIN) { + break; + } + + /* + * Wait for data to be ready on the socket. + * If a less than zero value is returned, don't + * handle timeouts. + */ + error = socket_rx_wait(sockfd); + if (error < 0) { + continue; + } + + /* Try one more time, obey timeout */ + error = recv(sockfd, buf, len, flags); + if (error == -EAGAIN) { + return error; + } + break; + } if (error < 0) { pr_error("sys_recv: recv() fail (fd=%d)\n", sockfd); -- cgit v1.2.3