From ede93677272e62d6477333dee02a4cca4d322964 Mon Sep 17 00:00:00 2001 From: Matheus Date: Mon, 24 Oct 2022 15:34:15 -0300 Subject: [PATCH] poll: properly do timeouts --- src/sys/syscalls/poll.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/sys/syscalls/poll.c b/src/sys/syscalls/poll.c index 8702bb08..c9f97187 100644 --- a/src/sys/syscalls/poll.c +++ b/src/sys/syscalls/poll.c @@ -5,6 +5,8 @@ #include #include #include +#include +#include #define MAXNFDS 4096 @@ -12,6 +14,7 @@ syscallret syscall_poll(pollfd *fds, size_t nfds, int timeoutms){ syscallret retv; retv.ret = -1; + if(fds > USER_SPACE_END){ retv.errno = EFAULT; return retv; @@ -42,6 +45,14 @@ syscallret syscall_poll(pollfd *fds, size_t nfds, int timeoutms){ bool eventhappened = false; fdtable_t* fdtable = &arch_getcls()->thread->proc->fdtable; + + struct timespec target = arch_timekeeper_gettime(); + target.tv_sec += timeoutms / 1000; + target.tv_nsec += timeoutms * 1000000; + if(target.tv_nsec >= 1000000000){ + target.tv_sec++; + target.tv_nsec %= 1000000000; + } while(!eventhappened){ for(uintmax_t i = 0; i < nfds; ++i){ @@ -69,6 +80,7 @@ syscallret syscall_poll(pollfd *fds, size_t nfds, int timeoutms){ if(ilist[i].revents) eventhappened = true; + // cleanup @@ -79,6 +91,15 @@ syscallret syscall_poll(pollfd *fds, size_t nfds, int timeoutms){ // TODO check for signal or timeout if(timeoutms == 0) break; + if(timeoutms > 0){ + struct timespec now = arch_timekeeper_gettime(); + if(now.tv_sec > target.tv_sec) + break; + + if(now.tv_sec == target.tv_sec && now.tv_nsec >= target.tv_sec) + break; + + } arch_interrupt_disable(); sched_yield(); arch_interrupt_enable(); @@ -91,12 +112,14 @@ syscallret syscall_poll(pollfd *fds, size_t nfds, int timeoutms){ for(uintmax_t i = 0; i < nfds; ++i){ - if(ilist[i].fd < 0 || ilist[i].revents == 0) + if(ilist[i].fd < 0) continue; + fds[i].revents = ilist[i].revents; - ++eventcount; + if(ilist[i].revents) + ++eventcount; }