Module: Mesa
Branch: main
Commit: df92a13a270bea95f5c5260ee5de0c5b776f5131
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=df92a13a270bea95f5c5260ee5de0c5b776f5131

Author: Jesse Natalie <[email protected]>
Date:   Tue Nov  2 10:10:01 2021 -0700

util/libsync: Fix timeout handling if poll() wakes up early

Check how long poll waited, and use a smaller timeout on the next
iteration through the loop.

Reviewed-by: Jason Ekstrand <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12268>

---

 src/util/libsync.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/util/libsync.h b/src/util/libsync.h
index 1c9303c174a..0cb895a75d3 100644
--- a/src/util/libsync.h
+++ b/src/util/libsync.h
@@ -36,6 +36,7 @@
 #include <sys/ioctl.h>
 #include <sys/poll.h>
 #include <unistd.h>
+#include <time.h>
 
 #if defined(__cplusplus)
 extern "C" {
@@ -102,12 +103,15 @@ static inline int sync_wait(int fd, int timeout)
 {
        struct pollfd fds = {0};
        int ret;
+       struct timespec poll_start, poll_end;
 
        fds.fd = fd;
        fds.events = POLLIN;
 
        do {
+               clock_gettime(CLOCK_MONOTONIC, &poll_start);
                ret = poll(&fds, 1, timeout);
+               clock_gettime(CLOCK_MONOTONIC, &poll_end);
                if (ret > 0) {
                        if (fds.revents & (POLLERR | POLLNVAL)) {
                                errno = EINVAL;
@@ -118,6 +122,8 @@ static inline int sync_wait(int fd, int timeout)
                        errno = ETIME;
                        return -1;
                }
+               timeout -= (poll_end.tv_sec - poll_start.tv_sec) * 1000 +
+                       (poll_end.tv_nsec - poll_end.tv_nsec) / 1000000;
        } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
 
        return ret;

Reply via email to