diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-01-08 22:56:28 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-01-09 00:26:19 +0000 |
commit | c5b353c3725a1a8c116b790df4206f060d64eb5c (patch) | |
tree | 3423bc5a51080f7e85e1933b5af81f99fd807aea /src/cairo-scaled-font.c | |
parent | d1184b69e8871180b7b357a02d1a0bed3e68d897 (diff) |
scaled-font: Make reset-font-cache threadsafe
Stop trying to workaround the destroy-callback requiring the font mutex
as we already hold the mutex whilst cleaning up the font caches.
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 | 66 |
1 files changed, 31 insertions, 35 deletions
diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c index 46a9c4d77..aab69371f 100644 --- a/src/cairo-scaled-font.c +++ b/src/cairo-scaled-font.c @@ -451,31 +451,39 @@ _cairo_scaled_font_map_destroy (void) } static void -_cairo_scaled_glyph_page_destroy (void *closure) +_cairo_scaled_glyph_page_destroy (cairo_scaled_font_t *scaled_font, + cairo_scaled_glyph_page_t *page) { - cairo_scaled_glyph_page_t *page = closure; - cairo_scaled_font_t *scaled_font; unsigned int n; - 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); free (page); } +static void +_cairo_scaled_glyph_page_pluck (void *closure) +{ + cairo_scaled_glyph_page_t *page = closure; + cairo_scaled_font_t *scaled_font; + + assert (! cairo_list_is_empty (&page->link)); + + scaled_font = (cairo_scaled_font_t *) page->cache_entry.hash; + + CAIRO_MUTEX_LOCK (scaled_font->mutex); + _cairo_scaled_glyph_page_destroy (scaled_font, page); + CAIRO_MUTEX_UNLOCK (scaled_font->mutex); +} + /* If a scaled font wants to unlock the font map while still being * created (needed for user-fonts), we need to take extra care not * ending up with multiple identical scaled fonts being created. @@ -810,16 +818,23 @@ _cairo_scaled_font_thaw_cache (cairo_scaled_font_t *scaled_font) void _cairo_scaled_font_reset_cache (cairo_scaled_font_t *scaled_font) { + CAIRO_MUTEX_LOCK (scaled_font->mutex); assert (! scaled_font->cache_frozen); - + assert (! scaled_font->global_cache_frozen); CAIRO_MUTEX_LOCK (_cairo_scaled_glyph_page_cache_mutex); while (! cairo_list_is_empty (&scaled_font->glyph_pages)) { - _cairo_cache_remove (&cairo_scaled_glyph_page_cache, - &cairo_list_first_entry (&scaled_font->glyph_pages, - cairo_scaled_glyph_page_t, - link)->cache_entry); + cairo_scaled_glyph_page_t *page = + cairo_list_first_entry (&scaled_font->glyph_pages, + cairo_scaled_glyph_page_t, + link); + _cairo_scaled_glyph_page_destroy (scaled_font, page); + + cairo_scaled_glyph_page_cache.size -= page->cache_entry.size; + _cairo_hash_table_remove (cairo_scaled_glyph_page_cache.hash_table, + (cairo_hash_entry_t *) &page->cache_entry); } CAIRO_MUTEX_UNLOCK (_cairo_scaled_glyph_page_cache_mutex); + CAIRO_MUTEX_UNLOCK (scaled_font->mutex); } cairo_status_t @@ -852,32 +867,13 @@ _cairo_scaled_font_set_metrics (cairo_scaled_font_t *scaled_font, } static void -_cairo_scaled_font_fini_pages (cairo_scaled_font_t *scaled_font) -{ - cairo_scaled_glyph_page_t *page; - unsigned int i; - - cairo_list_foreach_entry (page, cairo_scaled_glyph_page_t, - &scaled_font->glyph_pages, link) { - for (i = 0; i < page->num_glyphs; i++) { - _cairo_hash_table_remove (scaled_font->glyphs, - &page->glyphs[i].hash_entry); - _cairo_scaled_glyph_fini (scaled_font, &page->glyphs[i]); - } - page->num_glyphs = 0; - } - - _cairo_scaled_font_reset_cache (scaled_font); -} - -static void _cairo_scaled_font_fini_internal (cairo_scaled_font_t *scaled_font) { assert (! scaled_font->cache_frozen); assert (! scaled_font->global_cache_frozen); scaled_font->finished = TRUE; - _cairo_scaled_font_fini_pages (scaled_font); + _cairo_scaled_font_reset_cache (scaled_font); _cairo_hash_table_destroy (scaled_font->glyphs); cairo_font_face_destroy (scaled_font->font_face); @@ -2865,7 +2861,7 @@ _cairo_scaled_font_allocate_glyph (cairo_scaled_font_t *scaled_font, status = _cairo_cache_init (&cairo_scaled_glyph_page_cache, NULL, _cairo_scaled_glyph_page_can_remove, - _cairo_scaled_glyph_page_destroy, + _cairo_scaled_glyph_page_pluck, MAX_GLYPH_PAGES_CACHED); if (unlikely (status)) { CAIRO_MUTEX_UNLOCK (_cairo_scaled_glyph_page_cache_mutex); |