summaryrefslogtreecommitdiff
path: root/src/cairo-xlib-surface-shm.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-08-18 08:02:42 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2012-08-18 08:06:26 +0100
commitec01c71ecab46e0252d295f8d1f24f261b3f52af (patch)
treeedf5de63b52b7edf58d96acbef1d2b4a95c7c18b /src/cairo-xlib-surface-shm.c
parent1bc9f673b61aa48369329606acc13aa5bce94a0a (diff)
downloadcairo-ec01c71ecab46e0252d295f8d1f24f261b3f52af.tar.gz
xlib/shm: Wrap the detection of shm with locking
As we access a global error variable, we need to hold a mutex against simultaneous checking of multiple Displays. This should already be true as we hold our display mutex to serialize initialisation, so just add an assertion. As the client may mix use of cairo in one thread with X from another, we need to hold the Display lock and serialise whilst manipulating the low-level state of the Display. Suggested-by: Uli Schlachter <psychon@znc.in> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/cairo-xlib-surface-shm.c')
-rw-r--r--src/cairo-xlib-surface-shm.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/src/cairo-xlib-surface-shm.c b/src/cairo-xlib-surface-shm.c
index ad36ce1d0..2d201272a 100644
--- a/src/cairo-xlib-surface-shm.c
+++ b/src/cairo-xlib-surface-shm.c
@@ -231,6 +231,7 @@ _pqueue_pop (struct pqueue *pq)
}
static cairo_bool_t _x_error_occurred;
+
static int
_check_error_handler (Display *display,
XErrorEvent *event)
@@ -263,7 +264,11 @@ can_use_shm (Display *dpy, int *has_pixmap)
return FALSE;
}
+ assert (CAIRO_MUTEX_IS_LOCKED (_cairo_xlib_display_mutex));
_x_error_occurred = FALSE;
+
+ XLockDisplay (dpy);
+ XSync (dpy, False);
old_handler = XSetErrorHandler (_check_error_handler);
success = XShmAttach (dpy, &shm);
@@ -272,6 +277,7 @@ can_use_shm (Display *dpy, int *has_pixmap)
XSync (dpy, False);
XSetErrorHandler (old_handler);
+ XUnlockDisplay (dpy);
shmctl (shm.shmid, IPC_RMID, NULL);
shmdt (shm.shmaddr);