summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-01-08 22:56:28 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2013-01-09 00:26:19 +0000
commitc5b353c3725a1a8c116b790df4206f060d64eb5c (patch)
tree3423bc5a51080f7e85e1933b5af81f99fd807aea
parentd1184b69e8871180b7b357a02d1a0bed3e68d897 (diff)
downloadcairo-c5b353c3725a1a8c116b790df4206f060d64eb5c.tar.gz
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>
-rw-r--r--src/cairo-scaled-font.c66
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);