[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