summaryrefslogtreecommitdiff
path: root/src/cairo-scaled-font.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-01-08 11:20:08 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2013-01-08 15:03:25 +0000
commitb5dcc8ce4450de1e48fd0586fddb5ed658719b28 (patch)
treee91c80c5878211e496cd36bb0bc49cda68b878b9 /src/cairo-scaled-font.c
parentc4ea7b13b406bf0ea1dc9b337010131d3704bc4a (diff)
scaled-font: Hold the scaled font mutex whilst reaping from the global cache
If we need to reap the global cache, this will call back into the scaled font to free the glyph page. We therefore need to be careful not to run concurrently with a user adding to the glyph page, ergo we need locking. To complicate matters we need to be wary of a lock-inversion as we hold the scaled_font lock whilst thawing the global cache. We prevent the deadlock by careful ordering of the thaw-unlock and by inspecting the current frozen state of the scaled-font before releasing the glyph page. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/cairo-scaled-font.c')
-rw-r--r--src/cairo-scaled-font.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index ac8dc0a88..e61c1cac9 100644
--- a/src/cairo-scaled-font.c
+++ b/src/cairo-scaled-font.c
@@ -449,6 +449,7 @@ _cairo_scaled_font_map_destroy (void)
CLEANUP_MUTEX_LOCK:
CAIRO_MUTEX_UNLOCK (_cairo_scaled_font_map_mutex);
}
+
static void
_cairo_scaled_glyph_page_destroy (void *closure)
{
@@ -459,11 +460,16 @@ _cairo_scaled_glyph_page_destroy (void *closure)
assert (! cairo_list_is_empty (&page->link));
scaled_font = (cairo_scaled_font_t *) page->cache_entry.hash;
+ assert (!scaled_font->cache_frozen);
+ assert (!scaled_font->global_cache_frozen);
+
+ CAIRO_MUTEX_LOCK(scaled_font->mutex);
for (n = 0; n < page->num_glyphs; n++) {
_cairo_hash_table_remove (scaled_font->glyphs,
&page->glyphs[n].hash_entry);
_cairo_scaled_glyph_fini (scaled_font, &page->glyphs[n]);
}
+ CAIRO_MUTEX_UNLOCK(scaled_font->mutex);
cairo_list_del (&page->link);
@@ -790,16 +796,15 @@ void
_cairo_scaled_font_thaw_cache (cairo_scaled_font_t *scaled_font)
{
assert (scaled_font->cache_frozen);
- scaled_font->cache_frozen = FALSE;
if (scaled_font->global_cache_frozen) {
CAIRO_MUTEX_LOCK (_cairo_scaled_glyph_page_cache_mutex);
_cairo_cache_thaw (&cairo_scaled_glyph_page_cache);
CAIRO_MUTEX_UNLOCK (_cairo_scaled_glyph_page_cache_mutex);
-
scaled_font->global_cache_frozen = FALSE;
}
+ scaled_font->cache_frozen = FALSE;
CAIRO_MUTEX_UNLOCK (scaled_font->mutex);
}