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;
