summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJamey Sharp <jamey@minilop.net>2011-03-15 16:48:07 -0700
committerJamey Sharp <jamey@minilop.net>2011-03-15 16:48:07 -0700
commit83e1ba59c48c79f8b0a7e7aa0b9c9cfd84fa403d (patch)
tree19896164d179df5f9584a06293982a8ba61fc6df
parentfd85aca7a616c595fc17b2520f84316a11e8906f (diff)
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>
-rw-r--r--src/XlibInt.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/src/XlibInt.c b/src/XlibInt.c
index a78da9bf..3db151e2 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);
}