summaryrefslogtreecommitdiff
path: root/src/cairo-xlib-screen.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2008-04-10 14:49:47 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2008-04-11 15:39:09 +0100
commitdc714106e156cb7901e376c0935922446ae9bcdf (patch)
tree52674dd2b73bc492af4ea85838d3577bcf2c0970 /src/cairo-xlib-screen.c
parent9166686abd92f8b2c7067002b051220e2f8fe780 (diff)
[xlib] Add locking around GC cache.
The per-screen cached of most-recently freed GCs lacks suitable locking for it to be threadsafe.
Diffstat (limited to 'src/cairo-xlib-screen.c')
-rw-r--r--src/cairo-xlib-screen.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/src/cairo-xlib-screen.c b/src/cairo-xlib-screen.c
index 8a3da6675..fc07fda22 100644
--- a/src/cairo-xlib-screen.c
+++ b/src/cairo-xlib-screen.c
@@ -256,12 +256,14 @@ _cairo_xlib_screen_info_close_display (cairo_xlib_screen_info_t *info)
{
int i;
+ CAIRO_MUTEX_LOCK (info->mutex);
for (i = 0; i < ARRAY_LENGTH (info->gc); i++) {
if (info->gc[i] != NULL) {
XFreeGC (info->display->display, info->gc[i]);
info->gc[i] = NULL;
}
}
+ CAIRO_MUTEX_UNLOCK (info->mutex);
}
void
@@ -295,6 +297,8 @@ _cairo_xlib_screen_info_destroy (cairo_xlib_screen_info_t *info)
_cairo_array_fini (&info->visuals);
+ CAIRO_MUTEX_FINI (info->mutex);
+
free (info);
}
@@ -335,6 +339,7 @@ _cairo_xlib_screen_info_get (Display *dpy, Screen *screen)
info = malloc (sizeof (cairo_xlib_screen_info_t));
if (info != NULL) {
CAIRO_REFERENCE_COUNT_INIT (&info->ref_count, 2); /* Add one for display cache */
+ CAIRO_MUTEX_INIT (info->mutex);
info->display = _cairo_xlib_display_reference (display);
info->screen = screen;
info->has_render = FALSE;
@@ -385,16 +390,18 @@ GC
_cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info, int depth)
{
GC gc;
+ cairo_bool_t needs_reset;
depth = depth_to_index (depth);
+ CAIRO_MUTEX_LOCK (info->mutex);
gc = info->gc[depth];
info->gc[depth] = NULL;
+ needs_reset = info->gc_needs_clip_reset & (1 << depth);
+ CAIRO_MUTEX_UNLOCK (info->mutex);
- if (info->gc_needs_clip_reset & (1 << depth)) {
+ if (needs_reset)
XSetClipMask(info->display->display, gc, None);
- info->gc_needs_clip_reset &= ~(1 << depth);
- }
return gc;
}
@@ -403,21 +410,25 @@ cairo_status_t
_cairo_xlib_screen_put_gc (cairo_xlib_screen_info_t *info, int depth, GC gc, cairo_bool_t reset_clip)
{
cairo_status_t status = CAIRO_STATUS_SUCCESS;
+ GC oldgc;
depth = depth_to_index (depth);
- if (info->gc[depth] != NULL) {
- status = _cairo_xlib_display_queue_work (info->display,
- (cairo_xlib_notify_func) XFreeGC,
- info->gc[depth],
- NULL);
- }
-
+ CAIRO_MUTEX_LOCK (info->mutex);
+ oldgc = info->gc[depth];
info->gc[depth] = gc;
if (reset_clip)
info->gc_needs_clip_reset |= 1 << depth;
else
info->gc_needs_clip_reset &= ~(1 << depth);
+ CAIRO_MUTEX_UNLOCK (info->mutex);
+
+ if (oldgc != NULL) {
+ status = _cairo_xlib_display_queue_work (info->display,
+ (cairo_xlib_notify_func) XFreeGC,
+ oldgc,
+ NULL);
+ }
return status;
}