summaryrefslogtreecommitdiff
path: root/src/util/libsync.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/libsync.h')
-rw-r--r--src/util/libsync.h29
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