[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
This commit is contained in:
Chris Wilson 2007-06-15 20:38:01 +01:00
parent 7016614dd9
commit 285b702ef6

View file

@ -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_display_t *display)
} 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;