[cairo-commit] 2 commits - src/cairo-damage.c src/cairo-damage-private.h src/cairo-scaled-font.c src/cairo-xlib-surface-shm.c

Chris Wilson ickle at kemper.freedesktop.org
Tue Jan 8 08:08:45 PST 2013


 src/cairo-damage-private.h   |    3 +++
 src/cairo-damage.c           |    7 +++++++
 src/cairo-scaled-font.c      |    9 +++++++--
 src/cairo-xlib-surface-shm.c |    3 +++
 4 files changed, 20 insertions(+), 2 deletions(-)

New commits:
commit 2ed484817ef3a5084dc65a2ae1acdef551acd107
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jan 8 16:06:02 2013 +0000

    xlib/shm: Discard damage upon shm finish
    
    Both to make sure we do not leak the memory, but to also prevent
    _cairo_xlib_surface_put_shm() from operating upon the finished shm
    surface after the display is closed.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=58253
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-damage-private.h b/src/cairo-damage-private.h
index 28768fd..97b177e 100644
--- a/src/cairo-damage-private.h
+++ b/src/cairo-damage-private.h
@@ -60,6 +60,9 @@ cairo_private cairo_damage_t *
 _cairo_damage_create (void);
 
 cairo_private cairo_damage_t *
+_cairo_damage_create_in_error (cairo_status_t status);
+
+cairo_private cairo_damage_t *
 _cairo_damage_add_box (cairo_damage_t *damage,
 		       const cairo_box_t *box);
 
diff --git a/src/cairo-damage.c b/src/cairo-damage.c
index 1e06b26..63191fe 100644
--- a/src/cairo-damage.c
+++ b/src/cairo-damage.c
@@ -40,6 +40,13 @@
 static const cairo_damage_t __cairo_damage__nil = { CAIRO_STATUS_NO_MEMORY };
 
 cairo_damage_t *
+_cairo_damage_create_in_error (cairo_status_t status)
+{
+    _cairo_error_throw (status);
+    return (cairo_damage_t *) &__cairo_damage__nil;
+}
+
+cairo_damage_t *
 _cairo_damage_create (void)
 {
     cairo_damage_t *damage;
diff --git a/src/cairo-xlib-surface-shm.c b/src/cairo-xlib-surface-shm.c
index 2c2858c..ff0aaf8 100644
--- a/src/cairo-xlib-surface-shm.c
+++ b/src/cairo-xlib-surface-shm.c
@@ -710,6 +710,9 @@ _cairo_xlib_shm_surface_finish (void *abstract_surface)
     cairo_xlib_display_t *display;
     cairo_status_t status;
 
+    _cairo_damage_destroy (shm->image.base.damage);
+    shm->image.base.damage = _cairo_damage_create_in_error (CAIRO_STATUS_SURFACE_FINISHED);
+
     status = _cairo_xlib_display_acquire (shm->image.base.device, &display);
     if (unlikely (status))
 	return status;
commit b5dcc8ce4450de1e48fd0586fddb5ed658719b28
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jan 8 11:20:08 2013 +0000

    scaled-font: Hold the scaled font mutex whilst reaping from the global cache
    
    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>

diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c
index ac8dc0a..e61c1ca 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);
 
@@ -790,16 +796,15 @@ void
 _cairo_scaled_font_thaw_cache (cairo_scaled_font_t *scaled_font)
 {
     assert (scaled_font->cache_frozen);
-    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);
 }
 


More information about the cairo-commit mailing list