[cairo-commit] src/cairo-scaled-font.c

Chris Wilson ickle at kemper.freedesktop.org
Tue Jan 8 16:28:00 PST 2013


 src/cairo-scaled-font.c |   66 ++++++++++++++++++++++--------------------------
 1 file changed, 31 insertions(+), 35 deletions(-)

New commits:
commit c5b353c3725a1a8c116b790df4206f060d64eb5c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jan 8 22:56:28 2013 +0000

    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 at chris-wilson.co.uk>

diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index 46a9c4d..aab6937 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);


More information about the cairo-commit mailing list