Index: ChangeLog =================================================================== RCS file: /mirrors/freedesktop/cairo/cairo/ChangeLog,v retrieving revision 1.951 diff -u -p -r1.951 ChangeLog --- ChangeLog 23 Aug 2005 05:23:54 -0000 1.951 +++ ChangeLog 23 Aug 2005 06:52:36 -0000 @@ -1,3 +1,29 @@ +2005-08-22 Carl Worth + + Fix for bug #4192: + + * src/cairo-ft-font.c: (_font_map_release_face_lock_held): New + function to handle both calling FT_Done_Face on unscaled->face and + decrementing font_map->num_open_faces. + + * src/cairo-ft-font.c: + (_cairo_ft_unscaled_font_map_destroy), + (_cairo_ft_unscaled_font_destroy), + (_cairo_ft_unscaled_font_lock_face): Call new + _font_map_release_face_lock_held as approporiate. + + * src/cairo-ft-font.c: (_cairo_ft_unscaled_font_map_destroy): + Assert that (font_map->num_open_faces == 0) when we're done, to + help guarantee the bug is fixed. + + * src/cairo-ft-font.c: (_cairo_ft_unscaled_font_fini): Don't call + FT_Done_Face anymore, instead assert that (unscaled->face == NULL) + by the time this function is called. + + * src/cairo-ft-font.c: (_cairo_ft_unscaled_font_init), + (_cairo_ft_unscaled_font_set_scale): Prefer TRUE/FALSE as values + for cairo_bool_t have_scale. + 2005-08-22 Billy Biggs * doc/public/Makefile.am: Add version.xml to content_files Index: src/cairo-ft-font.c =================================================================== RCS file: /mirrors/freedesktop/cairo/cairo/src/cairo-ft-font.c,v retrieving revision 1.106 diff -u -p -r1.106 cairo-ft-font.c --- src/cairo-ft-font.c 23 Aug 2005 03:43:23 -0000 1.106 +++ src/cairo-ft-font.c 23 Aug 2005 06:39:31 -0000 @@ -152,6 +152,19 @@ static cairo_ft_unscaled_font_map_t *cai CAIRO_MUTEX_DECLARE(cairo_ft_unscaled_font_map_mutex); static void +_font_map_release_face_lock_held (cairo_ft_unscaled_font_map_t *font_map, + cairo_ft_unscaled_font_t *unscaled) +{ + if (unscaled->face) { + FT_Done_Face (unscaled->face); + unscaled->face = NULL; + unscaled->have_scale = FALSE; + + font_map->num_open_faces--; + } +} + +static void _cairo_ft_unscaled_font_map_create (void) { cairo_ft_unscaled_font_map_t *font_map; @@ -210,10 +223,14 @@ _cairo_ft_unscaled_font_map_destroy (voi break; _cairo_hash_table_remove (font_map->hash_table, &unscaled->base.hash_entry); + + _font_map_release_face_lock_held (font_map, unscaled); _cairo_ft_unscaled_font_fini (unscaled); free (unscaled); } + assert (font_map->num_open_faces == 0); + FT_Done_FreeType (font_map->ft_library); _cairo_hash_table_destroy (font_map->hash_table); @@ -315,7 +332,7 @@ _cairo_ft_unscaled_font_init (cairo_ft_u _cairo_ft_unscaled_font_init_key (unscaled, filename_copy, id); } - unscaled->have_scale = 0; + unscaled->have_scale = FALSE; unscaled->lock = 0; unscaled->faces = NULL; @@ -329,18 +346,26 @@ _cairo_unscaled_font_is_ft (cairo_unscal return unscaled_font->backend == &cairo_ft_unscaled_font_backend; } +/** + * _cairo_ft_unscaled_font_fini: + * + * Free all data associated with a cairo_ft_unscaled_font_t. + * + * CAUTION: The unscaled->face field must be NULL before calling this + * function. This is because the cairo_ft_unscaled_font_map keeps a + * count of these faces (font_map->num_open_faces) so it maintains the + * unscaled->face field while it has its lock held. See + * _font_map_release_face_lock_held(). + **/ static void _cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t *unscaled) { + assert (unscaled->face == NULL); + if (unscaled->filename) { free (unscaled->filename); unscaled->filename = NULL; } - - if (unscaled->face) { - FT_Done_Face (unscaled->face); - unscaled->face = NULL; - } } static int @@ -460,9 +485,10 @@ _cairo_ft_unscaled_font_destroy (void *a _cairo_hash_table_remove (font_map->hash_table, &unscaled->base.hash_entry); - _cairo_ft_unscaled_font_map_unlock (); - + _font_map_release_face_lock_held (font_map, unscaled); _cairo_ft_unscaled_font_fini (unscaled); + + _cairo_ft_unscaled_font_map_unlock (); } } @@ -507,11 +533,7 @@ _cairo_ft_unscaled_font_lock_face (cairo if (entry == NULL) break; - FT_Done_Face (entry->face); - entry->face = NULL; - entry->have_scale = 0; - - font_map->num_open_faces--; + _font_map_release_face_lock_held (font_map, entry); } if (FT_New_Face (font_map->ft_library, @@ -593,7 +615,7 @@ _cairo_ft_unscaled_font_set_scale (cairo scale->yy == unscaled->current_scale.yy) return; - unscaled->have_scale = 1; + unscaled->have_scale = TRUE; unscaled->current_scale = *scale; _compute_transform (&sf, scale);