[PATCH xlib] Add support for a display-specific error handler
Jasper St. Pierre
jstpierre at mecheye.net
Fri Nov 13 15:24:24 PST 2015
Writing error-safe code that uses Xlib is too obnoxious, and using XCB
is tedious and not performant, as we can't catch events on a giant
stream -- we have to check every operation manually.
In my specific case (writing a GL driver), it would be enough to simply
have a Display-specific error handler, since our driver re-opens the
Display in our own code, but a better approach might be TLS storage for
the global handler.
Signed-off-by: Jasper St. Pierre <jstpierre at mecheye.net>
---
include/X11/Xlib.h | 4 ++++
include/X11/Xlibint.h | 3 +++
src/ErrHndlr.c | 15 +++++++++++++++
src/XlibInt.c | 12 +++++++++++-
4 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/include/X11/Xlib.h b/include/X11/Xlib.h
index 2bffa76..772e88c 100644
--- a/include/X11/Xlib.h
+++ b/include/X11/Xlib.h
@@ -1849,6 +1849,10 @@ extern XErrorHandler XSetErrorHandler (
XErrorHandler /* handler */
);
+extern XErrorHandler XDisplaySetErrorHandler(
+ Display* /* display */,
+ XErrorHandler /* handler */
+);
typedef int (*XIOErrorHandler) ( /* WARNING, this type not in Xlib spec */
Display* /* display */
diff --git a/include/X11/Xlibint.h b/include/X11/Xlibint.h
index 4431559..e05792f 100644
--- a/include/X11/Xlibint.h
+++ b/include/X11/Xlibint.h
@@ -205,6 +205,9 @@ struct _XDisplay
XGenericEventCookie * /* in */,
XGenericEventCookie * /* out*/);
void *cookiejar; /* cookie events returned but not claimed */
+
+ /* display-specific error handler */
+ XErrorHandler err_handler;
};
#define XAllocIDs(dpy,ids,n) (*(dpy)->idlist_alloc)(dpy,ids,n)
diff --git a/src/ErrHndlr.c b/src/ErrHndlr.c
index 167a68b..a8e1eee 100644
--- a/src/ErrHndlr.c
+++ b/src/ErrHndlr.c
@@ -84,3 +84,18 @@ XSetIOErrorHandler(XIOErrorHandler handler)
return (XIOErrorHandler) oldhandler;
}
+
+XErrorHandler
+XDisplaySetErrorHandler(Display *dpy, XErrorHandler handler)
+{
+ XErrorHandler old_handler;
+#ifdef XTHREADS
+ LockDisplay(dpy);
+#endif
+ old_handler = dpy->err_handler;
+ dpy->err_handler = handler;
+#ifdef XTHREADS
+ UnlockDisplay(dpy);
+#endif
+ return old_handler;
+}
diff --git a/src/XlibInt.c b/src/XlibInt.c
index 80c1298..d720e7b 100644
--- a/src/XlibInt.c
+++ b/src/XlibInt.c
@@ -1387,6 +1387,16 @@ Bool _XDefaultWireError(Display *display, XErrorEvent *he, xError *we)
return True;
}
+static int
+DispatchDisplayErrorEvent (Display *dpy,
+ XErrorEvent *event)
+{
+ if (dpy->err_handler)
+ return dpy->err_handler(dpy, event);
+ else
+ return _XErrorFunction(dpy, event);
+}
+
/*
* _XError - upcall internal or user protocol error handler
*/
@@ -1426,7 +1436,7 @@ int _XError (
(*dpy->lock->user_lock_display)(dpy);
UnlockDisplay(dpy);
#endif
- rtn_val = (*_XErrorFunction)(dpy, (XErrorEvent *)&event); /* upcall */
+ rtn_val = DispatchDisplayErrorEvent(dpy, (XErrorEvent *)&event); /* upcall */
#ifdef XTHREADS
LockDisplay(dpy);
if (dpy->lock)
--
2.4.3
More information about the xorg-devel
mailing list