[PATCH] scaled-font: Hold the scaled font mutex whilst reaping from the global cache
Chris Wilson <[email protected]>
| Newsgroups | gmane.comp.lib.cairo |
|---|---|
| Message-ID | <[email protected]> |
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 <[email protected]> --- src/cairo-scaled-font.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c index dc6a6fd..e1cb095 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); @@ -788,16 +794,14 @@ _cairo_scaled_font_freeze_cache (cairo_scaled_font_t *scaled_font) void _cairo_scaled_font_thaw_cache (cairo_scaled_font_t *scaled_font) { - 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); } -- 1.7.10.4 -- cairo mailing list [email protected] http://lists.cairographics.org/mailman/listinfo/cairo