From 9368bbbb61e8a41b6447d147a233862ca633c6a0 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 7 Jan 2009 10:18:08 -0800 Subject: [PATCH] libdrm: add timeout handling to drmWaitVBlank In some cases, vblank interrupts may be disabled or otherwise broken. The kernel has a 3s timeout builtin to handle these cases, but the X server's SIGALM for cursor handling may interrupt vblank wait ioctls, causing libdrm to restart the ioctl, making the kernel's timeout useless. This change tracks time across ioctl restarts and returns EBUSY to the caller if the expected vblank sequence doesn't occur within 1s of the first call. Fixes fdo bz #18041, which is caused by a drmWaitVBlank hanging due to the corresponding pipe getting disabled (thus preventing further events from coming in). --- libdrm/Makefile.am | 1 + libdrm/xf86drm.c | 17 +++++++---------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/libdrm/Makefile.am b/libdrm/Makefile.am index eb63abe1..71a87186 100644 --- a/libdrm/Makefile.am +++ b/libdrm/Makefile.am @@ -23,6 +23,7 @@ SUBDIRS = . intel libdrm_la_LTLIBRARIES = libdrm.la libdrm_ladir = $(libdir) libdrm_la_LDFLAGS = -version-number 2:4:0 -no-undefined +libdrm_la_LIBADD = -lrt AM_CFLAGS = -I$(top_srcdir)/shared-core libdrm_la_SOURCES = xf86drm.c xf86drmHash.c xf86drmRandom.c xf86drmSL.c \ diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 55df19ab..3396e283 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -1910,16 +1910,13 @@ int drmWaitVBlank(int fd, drmVBlankPtr vbl) do { ret = ioctl(fd, DRM_IOCTL_WAIT_VBLANK, vbl); vbl->request.type &= ~DRM_VBLANK_RELATIVE; - if (ret && errno == EINTR) { - clock_gettime(CLOCK_MONOTONIC, &cur); - /* Timeout after 1s */ - if (cur.tv_sec > timeout.tv_sec + 1 || - (cur.tv_sec == timeout.tv_sec && cur.tv_nsec >= - timeout.tv_nsec)) { - errno = EBUSY; - ret = -1; - break; - } + clock_gettime(CLOCK_MONOTONIC, &cur); + /* Timeout after 1s */ + if (cur.tv_sec > timeout.tv_sec + 1 || + cur.tv_sec == timeout.tv_sec && cur.tv_nsec >= timeout.tv_nsec) { + errno = EBUSY; + ret = -1; + break; } } while (ret && errno == EINTR);