[cairo] [PATCH] scaled-font: Hold the scaled font mutex whilst reaping from the global cache
Chris Wilson
chris at chris-wilson.co.uk
Tue Jan 8 03:26:56 PST 2013
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 at chris-wilson.co.uk>
---
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
More information about the cairo
mailing list