diff options
Diffstat (limited to 'src/util/libsync.h')
-rw-r--r-- | src/util/libsync.h | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/src/util/libsync.h b/src/util/libsync.h index 1c9303c174a..1515484c4b4 100644 --- a/src/util/libsync.h +++ b/src/util/libsync.h @@ -30,18 +30,21 @@ #include <assert.h> #include <errno.h> +#include <poll.h> #include <stdbool.h> #include <stdint.h> #include <string.h> #include <sys/ioctl.h> -#include <sys/poll.h> #include <unistd.h> +#include <time.h> + +#include "util/detect_os.h" #if defined(__cplusplus) extern "C" { #endif -#ifdef ANDROID +#if DETECT_OS_ANDROID /* On Android, rely on the system's libsync instead of rolling our own * sync_wait() and sync_merge(). This gives us compatibility with pre-4.7 * Android kernels. @@ -102,12 +105,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 +124,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; @@ -125,7 +133,7 @@ static inline int sync_wait(int fd, int timeout) static inline int sync_merge(const char *name, int fd1, int fd2) { - struct sync_merge_data data = {0}; + struct sync_merge_data data = {{0}}; int ret; data.fd2 = fd2; @@ -151,7 +159,7 @@ sync_valid_fd(int fd) return ioctl(fd, SYNC_IOC_FILE_INFO, &info) >= 0; } -#endif /* !ANDROID */ +#endif /* DETECT_OS_ANDROID */ /* accumulate fd2 into fd1. If *fd1 is not a valid fd then dup fd2, * otherwise sync_merge() and close the old *fd1. This can be used @@ -193,6 +201,19 @@ static inline int sync_accumulate(const char *name, int *fd1, int fd2) return 0; } +/* Helper macro to complain if fd is non-negative and not a valid fence fd. + * Sprinkle this around to help catch fd lifetime issues. + */ +#if MESA_DEBUG +# include "util/log.h" +# define validate_fence_fd(fd) do { \ + if (((fd) >= 0) && !sync_valid_fd(fd)) \ + mesa_loge("%s:%d: invalid fence fd: %d", __func__, __LINE__, (fd)); \ + } while (0) +#else +# define validate_fence_fd(fd) do {} while (0) +#endif + #if defined(__cplusplus) } #endif |