diff --git a/hw/kdrive/ephyr/XF86dri.c b/hw/kdrive/ephyr/XF86dri.c index 506d7bed8..e656ff5a0 100644 --- a/hw/kdrive/ephyr/XF86dri.c +++ b/hw/kdrive/ephyr/XF86dri.c @@ -385,9 +385,8 @@ Bool XF86DRICreateContext(dpy, screen, visual, context, hHWContext) context, hHWContext ); } -GLboolean XF86DRIDestroyContext( __DRInativeDisplay * ndpy, int screen, __DRIid context) +GLboolean XF86DRIDestroyContext( Display *dpy, int screen, XID context) { - Display * const dpy = (Display *) ndpy; XExtDisplayInfo *info = find_display (dpy); xXF86DRIDestroyContextReq *req; @@ -407,10 +406,9 @@ GLboolean XF86DRIDestroyContext( __DRInativeDisplay * ndpy, int screen, __DRIid } GLboolean -XF86DRICreateDrawable (__DRInativeDisplay * ndpy, int screen, - __DRIid drawable, drm_drawable_t * hHWDrawable) +XF86DRICreateDrawable (Display *dpy, int screen, + XID drawable, drm_drawable_t * hHWDrawable) { - Display * const dpy = (Display *) ndpy; XExtDisplayInfo *info = find_display (dpy); xXF86DRICreateDrawableReply rep; xXF86DRICreateDrawableReq *req; @@ -437,16 +435,36 @@ XF86DRICreateDrawable (__DRInativeDisplay * ndpy, int screen, return True; } -GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay * ndpy, int screen, - __DRIid drawable ) +static int noopErrorHandler(Display *dpy, XErrorEvent *xerr) +{ + return 0; +} + +GLboolean XF86DRIDestroyDrawable( Display *dpy, int screen, + XID drawable ) { - Display * const dpy = (Display *) ndpy; XExtDisplayInfo *info = find_display (dpy); xXF86DRIDestroyDrawableReq *req; + int (*oldXErrorHandler)(Display *, XErrorEvent *); TRACE("DestroyDrawable..."); XF86DRICheckExtension (dpy, info, False); + /* This is called from the DRI driver, which used call it like this + * + * if (windowExists(drawable)) + * destroyDrawable(drawable); + * + * which is a textbook race condition - the window may disappear + * from the server between checking for its existance and + * destroying it. Instead we change the semantics of + * __DRIinterfaceMethodsRec::destroyDrawable() to succeed even if + * the windows is gone, by wrapping the destroy call in an error + * handler. */ + + XSync(dpy, GL_FALSE); + oldXErrorHandler = XSetErrorHandler(noopErrorHandler); + LockDisplay(dpy); GetReq(XF86DRIDestroyDrawable, req); req->reqType = info->codes->major_opcode; @@ -455,6 +473,9 @@ GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay * ndpy, int screen, req->drawable = drawable; UnlockDisplay(dpy); SyncHandle(); + + XSetErrorHandler(oldXErrorHandler); + TRACE("DestroyDrawable... return True"); return True; }