diff options
author | Jamey Sharp <jamey@minilop.net> | 2011-03-15 16:48:07 -0700 |
---|---|---|
committer | Jamey Sharp <jamey@minilop.net> | 2011-03-15 16:48:07 -0700 |
commit | 83e1ba59c48c79f8b0a7e7aa0b9c9cfd84fa403d (patch) | |
tree | 19896164d179df5f9584a06293982a8ba61fc6df | |
parent | fd85aca7a616c595fc17b2520f84316a11e8906f (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.c | 14 |
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); } |