diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-10-25 10:15:39 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-10-25 10:15:39 +0100 |
commit | ef431b2d35c1bf4d77bbcc73688951d22f6aa135 (patch) | |
tree | 9190097f7cc33bd5687f70b97d2503450f4d2a20 | |
parent | efb8ff16491ecfb4d9c0c6a718684310d949d8d3 (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.h | 1 | ||||
-rw-r--r-- | src/intel_display.c | 21 | ||||
-rw-r--r-- | src/intel_driver.c | 2 |
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); |