b=576933 use a separate display to make protocol requests within X error handler r=roc
authorKarl Tomlinson <karlt+@karlt.net>
Fri, 25 Mar 2011 16:38:59 +1300
changeset 63993 06ca0535285e66ba87940ff245b78e9c1d14d956
parent 63992 bf6532a3d889bae1d9f21d55c28729f41e69e87c
child 63994 286410eeba47b4b9a8ec8e18779ee10a7b312f1e
push id19298
push userktomlinson@mozilla.com
push dateMon, 28 Mar 2011 01:54:05 +0000
treeherdermozilla-central@dacd66ab4dc4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs576933
milestone2.2a1pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
b=576933 use a separate display to make protocol requests within X error handler r=roc
toolkit/xre/nsX11ErrorHandler.cpp
--- a/toolkit/xre/nsX11ErrorHandler.cpp
+++ b/toolkit/xre/nsX11ErrorHandler.cpp
@@ -50,56 +50,58 @@ using mozilla::plugins::PluginProcessChi
 
 #include "mozilla/X11Util.h"
 #include <X11/Xlib.h>
 
 #define BUFSIZE 2048 // What Xlib uses with XGetErrorDatabaseText
 
 extern "C" {
 static int
-IgnoreError(Display *display, XErrorEvent *event) {
-  return 0; // This return value is ignored.
-}
-
-static int
 X11Error(Display *display, XErrorEvent *event) {
   nsCAutoString notes;
   char buffer[BUFSIZE];
 
   // Get an indication of how long ago the request that caused the error was
-  // made.  Do this before querying extensions etc below.
+  // made.
   unsigned long age = NextRequest(display) - event->serial;
 
-  // Ignore subsequent errors, which may get processed during the extension
-  // queries below for example.
-  XSetErrorHandler(IgnoreError);
-
   // Get a string to represent the request that caused the error.
   nsCAutoString message;
   if (event->request_code < 128) {
     // Core protocol request
     message.AppendInt(event->request_code);
   } else {
     // Extension request
-    int nExts;
-    char** extNames = XListExtensions(display, &nExts);
-    if (extNames) {
-      for (int i = 0; i < nExts; ++i) {
-        int major_opcode, first_event, first_error;
-        if (XQueryExtension(display, extNames[i],
-                            &major_opcode, &first_event, &first_error)
-            && major_opcode == event->request_code) {
-          message.Append(extNames[i]);
-          message.Append('.');
-          message.AppendInt(event->minor_code);
-          break;
+
+    // man XSetErrorHandler says "the error handler should not call any
+    // functions (directly or indirectly) on the display that will generate
+    // protocol requests or that will look for input events" so we use another
+    // temporary Display to request extension information.  This assumes on
+    // the DISPLAY environment variable has been set and matches what was used
+    // to open |display|.
+    Display *tmpDisplay = XOpenDisplay(NULL);
+    if (tmpDisplay) {
+      int nExts;
+      char** extNames = XListExtensions(tmpDisplay, &nExts);
+      if (extNames) {
+        for (int i = 0; i < nExts; ++i) {
+          int major_opcode, first_event, first_error;
+          if (XQueryExtension(tmpDisplay, extNames[i],
+                              &major_opcode, &first_event, &first_error)
+              && major_opcode == event->request_code) {
+            message.Append(extNames[i]);
+            message.Append('.');
+            message.AppendInt(event->minor_code);
+            break;
+          }
         }
+
+        XFreeExtensionList(extNames);
       }
-
-      XFreeExtensionList(extNames);
+      XCloseDisplay(tmpDisplay);
     }
   }
 
   if (message.IsEmpty()) {
     buffer[0] = '\0';
   } else {
     XGetErrorDatabaseText(display, "XRequest", message.get(), "",
                           buffer, sizeof(buffer));