summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2025-08-04 20:13:59 -0400
committerIan Moffett <ian@osmora.org>2025-08-04 20:13:59 -0400
commit24b4eaa97c0ba3c45406ac293a35d78c5342aac8 (patch)
treefef7e0c00a58a5536ecde5e6fc74910a0c78223f
parentff68e8679d7d2487126ff355ed2b34a6f84058bb (diff)
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 <ian@osmora.org>
-rw-r--r--sys/kern/kern_socket.c25
1 files changed, 22 insertions, 3 deletions
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);