Call _XErrorFunction without holding the Display lock.

Historically, Xlib dropped the Display lock around the upcall to any
user-supplied _XErrorFunction, but somewhere along the way I quit doing
that if you built with XCB. The reasons are lost somewhere in the
pre-git history of Xlib/XCB, and I can't now see any reason to hold the
lock.

The documentation for XSetErrorHandler still applies though:

    Because this condition is not assumed to be fatal, it is acceptable
    for your error handler to return; the returned value is ignored.
    However, 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 while you are now once again permitted to re-enter Xlib from the
error handler, you're only allowed to call non-protocol functions.

Signed-off-by: Jamey Sharp <jamey@minilop.net>
This commit is contained in:
Jamey Sharp 2011-03-15 16:48:07 -07:00
parent fd85aca7a6
commit 83e1ba59c4

View file

@ -1574,7 +1574,19 @@ int _XError (
!(*dpy->error_vec[rep->errorCode])(dpy, &event.xerror, rep))
return 0;
if (_XErrorFunction != NULL) {
return (*_XErrorFunction)(dpy, (XErrorEvent *)&event); /* upcall */
int rtn_val;
#ifdef XTHREADS
if (dpy->lock)
(*dpy->lock->user_lock_display)(dpy);
UnlockDisplay(dpy);
#endif
rtn_val = (*_XErrorFunction)(dpy, (XErrorEvent *)&event); /* upcall */
#ifdef XTHREADS
LockDisplay(dpy);
if (dpy->lock)
(*dpy->lock->user_unlock_display)(dpy);
#endif
return rtn_val;
} else {
return _XDefaultError(dpy, (XErrorEvent *)&event);
}