b=576933 use a separate display to make protocol requests within X error handler r=roc

--HG--
extra : transplant_source : %E9%20K%F1d6%08%3D%05%FE%5B%7F%E0%18%EFQ%92%A0%9AM
This commit is contained in:
Karl Tomlinson 2011-03-25 16:38:59 +13:00
parent 620408b145
commit c46b9f0eef

View File

@ -54,24 +54,15 @@ using mozilla::plugins::PluginProcessChild;
#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) {
@ -79,22 +70,33 @@ X11Error(Display *display, XErrorEvent *event) {
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;
}
}
XFreeExtensionList(extNames);
// 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);
}
XCloseDisplay(tmpDisplay);
}
}