[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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.