summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-10-25 10:15:39 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2012-10-25 10:15:39 +0100
commitef431b2d35c1bf4d77bbcc73688951d22f6aa135 (patch)
tree9190097f7cc33bd5687f70b97d2503450f4d2a20
parentefb8ff16491ecfb4d9c0c6a718684310d949d8d3 (diff)
uxa: Drain the DRM event queue before server regeneration
Adam Jackson notes that what appeared to be my paranoid ramblings in SNA actually served a purpose - it prevents a server crash following server regen if an indirect client happened to be running at the time (e.g. LIBGL_INDIRECT_ALWAYS=1 glxgears). Reported-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/intel.h1
-rw-r--r--src/intel_display.c21
-rw-r--r--src/intel_driver.c2
3 files changed, 24 insertions, 0 deletions
diff --git a/src/intel.h b/src/intel.h
index a5603fee..d3947501 100644
--- a/src/intel.h
+++ b/src/intel.h
@@ -366,6 +366,7 @@ extern Bool intel_mode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp);
extern void intel_mode_init(struct intel_screen_private *intel);
extern void intel_mode_disable_unused_functions(ScrnInfoPtr scrn);
extern void intel_mode_remove_fb(intel_screen_private *intel);
+extern void intel_mode_close(intel_screen_private *intel);
extern void intel_mode_fini(intel_screen_private *intel);
extern int intel_get_pipe_from_crtc_id(drm_intel_bufmgr *bufmgr, xf86CrtcPtr crtc);
diff --git a/src/intel_display.c b/src/intel_display.c
index f442da93..2c93c2de 100644
--- a/src/intel_display.c
+++ b/src/intel_display.c
@@ -31,6 +31,7 @@
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/poll.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
@@ -1830,6 +1831,26 @@ intel_mode_remove_fb(intel_screen_private *intel)
}
}
+static Bool has_pending_events(int fd)
+{
+ struct pollfd pfd;
+ pfd.fd = fd;
+ pfd.events = POLLIN;
+ return poll(&pfd, 1, 0) == 1;
+}
+
+void
+intel_mode_close(intel_screen_private *intel)
+{
+ struct intel_mode *mode = intel->modes;
+
+ if (mode == NULL)
+ return;
+
+ while (has_pending_events(mode->fd))
+ drmHandleEvent(mode->fd, &mode->event_context);
+}
+
void
intel_mode_fini(intel_screen_private *intel)
{
diff --git a/src/intel_driver.c b/src/intel_driver.c
index 65a50088..3029b228 100644
--- a/src/intel_driver.c
+++ b/src/intel_driver.c
@@ -1139,6 +1139,8 @@ static Bool I830CloseScreen(CLOSE_SCREEN_ARGS_DECL)
I830UeventFini(scrn);
#endif
+ intel_mode_close(intel);
+
DeleteCallback(&FlushCallback, intel_flush_callback, scrn);
intel_glamor_close_screen(screen);