[cairo-commit] 2 commits - src/cairo-xlib-display.c src/cairo-xlib-surface.c
Chris Wilson
ickle at kemper.freedesktop.org
Fri Jun 15 13:22:46 PDT 2007
src/cairo-xlib-display.c | 17 ++++++++++++++---
src/cairo-xlib-surface.c | 2 ++
2 files changed, 16 insertions(+), 3 deletions(-)
New commits:
diff-tree 285b702ef6f73e7eb4ca0da235a287ad1e1f412f (from 7016614dd90798247524f0c118f462aa2e7ef673)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Jun 15 20:38:01 2007 +0100
[cairo-xlib-display] Hide XErrors during processing of the work queue.
It is possible for the resources that we defer freeing to be already
destroyed and trigger an XError whilst processing the work queue. For
example, the application renders to a Window and then destroys the
Drawable before proceeding with more rendering. This will trigger an
invalid Picture from RenderFreePicture whilst attempting to free the
resources.
By ignoring the possibility that the application could allocate a fresh
resource with the same ID, we can simply hide the XErrors...
Fixes: https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=243811
diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c
index 5de9011..3ff633e 100644
--- a/src/cairo-xlib-display.c
+++ b/src/cairo-xlib-display.c
@@ -405,10 +405,13 @@ void
_cairo_xlib_display_notify (cairo_xlib_display_t *display)
{
cairo_xlib_job_t *jobs, *job, *freelist;
+ Display *dpy = display->display;
CAIRO_MUTEX_LOCK (display->mutex);
jobs = display->workqueue;
while (jobs != NULL) {
+ cairo_xlib_error_func_t old_handler;
+
display->workqueue = NULL;
CAIRO_MUTEX_UNLOCK (display->mutex);
@@ -422,24 +425,32 @@ _cairo_xlib_display_notify (cairo_xlib_d
} while (jobs != NULL);
freelist = jobs = job;
+ /* protect the notifies from triggering XErrors
+ * XXX There is a remote possibility that the application has
+ * been reallocated an XID that we are about to destroy here... */
+ XSync (dpy, False);
+ old_handler = XSetErrorHandler (_noop_error_handler);
+
do {
job = jobs;
jobs = job->next;
switch (job->type){
case WORK:
- job->func.work.notify (display->display, job->func.work.data);
+ job->func.work.notify (dpy, job->func.work.data);
if (job->func.work.destroy != NULL)
job->func.work.destroy (job->func.work.data);
break;
case RESOURCE:
- job->func.resource.notify (display->display,
- job->func.resource.xid);
+ job->func.resource.notify (dpy, job->func.resource.xid);
break;
}
} while (jobs != NULL);
+ XSync (dpy, False);
+ XSetErrorHandler (old_handler);
+
CAIRO_MUTEX_LOCK (display->mutex);
do {
job = freelist;
diff-tree 7016614dd90798247524f0c118f462aa2e7ef673 (from 0c5d28a4e5ce5e4dd72c0f416ce5e960e92b808b)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Jun 15 20:45:53 2007 +0100
[cairo-xlib-surface] Check for errors before installing a NOOP error handler.
Call XSync before ignoring errors from XGetImage to avoid hiding
unassociated errors. Similarly, call XSync before reinstalling the old
error handler to ensure no errors creep out of the ignored section.
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index cbd75ad..90333a8 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -542,6 +542,7 @@ _get_image_surface (cairo_xlib_surface_t
{
cairo_xlib_error_func_t old_handler;
+ XSync (surface->dpy, False);
old_handler = XSetErrorHandler (_noop_error_handler);
ximage = XGetImage (surface->dpy,
@@ -550,6 +551,7 @@ _get_image_surface (cairo_xlib_surface_t
x2 - x1, y2 - y1,
AllPlanes, ZPixmap);
+ XSync (surface->dpy, False);
XSetErrorHandler (old_handler);
/* If we get an error, the surface must have been a window,
More information about the cairo-commit
mailing list