[Mesa-dev] [PATCH 3/3] xlib: use X error handler to catch XShmQueryVersion() failure

Brian Paul brian.e.paul at gmail.com
Tue Jan 10 18:46:40 PST 2012


From: Brian Paul <brianp at vmware.com>

This is a follow-on to the previous commits.  It seems that
XShmQueryVersion() can trigger an X error after the first X
connection is closed and we start using a new connection.

Fixes a bug found by Wayne E. Robertz.

NOTE: This is a candidate for the 7.11 branch.
---
 src/mesa/drivers/x11/xm_api.c |   28 +++++++++++++++++++++++++++-
 1 files changed, 27 insertions(+), 1 deletions(-)

diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c
index 81b2459..8c0e783 100644
--- a/src/mesa/drivers/x11/xm_api.c
+++ b/src/mesa/drivers/x11/xm_api.c
@@ -105,6 +105,19 @@ static int host_byte_order( void )
 }
 
 
+static GLboolean XShmErrorFlag;
+
+static int
+xshm_query_version_err_handler( XMesaDisplay* dpy, XErrorEvent* xerr )
+{
+   /* If this function gets called, it's because XShmQuerryVersion()
+    * has failed.
+    */
+   XShmErrorFlag = True;
+   return 0;
+}
+
+
 /**
  * Check if the X Shared Memory extension is available.
  * Return:  0 = not available
@@ -118,7 +131,20 @@ static int check_for_xshm( XMesaDisplay *display )
    Bool pixmaps;
 
    if (XQueryExtension( display, "MIT-SHM", &ignore, &ignore, &ignore )) {
-      if (XShmQueryVersion( display, &major, &minor, &pixmaps )==True) {
+      int (*old_handler)(XMesaDisplay *, XErrorEvent *);
+      int ok;
+
+      /* Install X error handler before calling XShmQueryVersion() to catch
+       * a spurious X error.
+       */
+      XShmErrorFlag = False;
+      old_handler = XSetErrorHandler(xshm_query_version_err_handler);
+      ok = XShmQueryVersion( display, &major, &minor, &pixmaps );
+      XSetErrorHandler(old_handler);
+      if (XShmErrorFlag)
+         ok = False;
+
+      if (ok) {
 	 return (pixmaps==True) ? 2 : 1;
       }
       else {
-- 
1.7.1



More information about the mesa-dev mailing list