mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-01-13 10:50:28 +01:00
[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:
parent
7016614dd9
commit
285b702ef6
1 changed files with 14 additions and 3 deletions
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue