diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-01-08 11:20:08 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-01-08 15:03:25 +0000 |
commit | b5dcc8ce4450de1e48fd0586fddb5ed658719b28 (patch) | |
tree | e91c80c5878211e496cd36bb0bc49cda68b878b9 /src/cairo-scaled-font.c | |
parent | c4ea7b13b406bf0ea1dc9b337010131d3704bc4a (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.c | 9 |
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); } |