From 83e1ba59c48c79f8b0a7e7aa0b9c9cfd84fa403d Mon Sep 17 00:00:00 2001 From: Jamey Sharp Date: Tue, 15 Mar 2011 16:48:07 -0700 Subject: 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 --- src/XlibInt.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/XlibInt.c b/src/XlibInt.c index a78da9b..3db151e 100644 --- a/src/XlibInt.c +++ b/src/XlibInt.c @@ -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); } -- cgit v1.2.3