diff options
-rw-r--r-- | ChangeLog | 38 | ||||
-rw-r--r-- | pango/fonts.c | 10 | ||||
-rw-r--r-- | pango/pangoatsui.c | 8 | ||||
-rw-r--r-- | pango/pangocairo-font.c | 17 | ||||
-rw-r--r-- | pango/pangocairo-win32font.c | 5 | ||||
-rw-r--r-- | pango/pangofc-font.c | 9 | ||||
-rw-r--r-- | pango/pangofc-fontmap.c | 9 | ||||
-rw-r--r-- | pango/pangowin32-fontmap.c | 4 | ||||
-rw-r--r-- | pango/pangowin32.c | 4 | ||||
-rw-r--r-- | pango/pangox-fontmap.c | 1 | ||||
-rw-r--r-- | pango/pangox.c | 8 |
11 files changed, 93 insertions, 20 deletions
@@ -1,3 +1,41 @@ +2008-08-22 Behdad Esfahbod <behdad@gnome.org> + + Bug 143542 – PangoFT2Fontmap leak + + * pango/fonts.c: + * pango/pangoatsui.c (pango_atsui_font_finalize), + (_pango_atsui_font_set_font_map): + * pango/pangocairo-font.c (_pango_cairo_font_get_metrics), + (_pango_cairo_font_private_get_hex_box_info): + * pango/pangocairo-win32font.c (_pango_cairo_win32_font_new): + * pango/pangofc-font.c (pango_fc_font_get_metrics): + * pango/pangofc-fontmap.c (pango_fc_font_map_add), + (_pango_fc_font_map_remove), (cleanup_font): + * pango/pangowin32-fontmap.c (pango_win32_font_neww), + (pango_win32_font_map_real_find_font): + * pango/pangowin32.c (pango_win32_font_finalize): + * pango/pangox-fontmap.c (pango_x_font_map_load_font): + * pango/pangox.c (pango_x_font_new), (pango_x_font_finalize): + Make the reference the font->fontmap reference weak. + + The code for setting the reference must look like this: + + g_assert (font->fontmap == NULL); + font->fontmap = (PangoFontMap *) fontmap; + g_object_add_weak_pointer (G_OBJECT (font->fontmap), (gpointer *) (gpointer) &font->fontmap); + + And releasing it like: + + g_assert (font->fontmap != NULL); + g_object_remove_weak_pointer (G_OBJECT (font->fontmap), (gpointer *) (gpointer) &font->fontmap); + font->fontmap = NULL; + + I have converted all fontmaps. The win32 and atsui ones can + use some simple testing. + + The PangoFc fonts actually don't need the weakref as the fontmap + already provides a similar link by itself. + 2008-08-20 Murray Cumming <murrayc@murrayc.com> * pango/pango-language.c: pango_language_get_scripts(): Fix a diff --git a/pango/fonts.c b/pango/fonts.c index efb989bb..2f997035 100644 --- a/pango/fonts.c +++ b/pango/fonts.c @@ -1414,10 +1414,18 @@ pango_font_get_metrics (PangoFont *font, /** * pango_font_get_font_map: - * @font: a #PangoFont + * @font: a #PangoFont, or %NULL * * Gets the font map for which the font was created. * + * Note that the font maintains a <firstterm>weak</firstterm> reference + * to the font map, so if all references to font map are dropped, the font + * map will be finalized even if there are fonts created with the font + * map that are still alive. In that case this function will return %NULL. + * It is the responsibility of the user to ensure that the font map is kept + * alive. In most uses this is not an issue as a #PangoContext holds + * a reference to the font map. + * * Return value: the #PangoFontMap for the font, or %NULL if @font is %NULL. * * Since: 1.10 diff --git a/pango/pangoatsui.c b/pango/pangoatsui.c index 58a4569a..a8c026e6 100644 --- a/pango/pangoatsui.c +++ b/pango/pangoatsui.c @@ -45,7 +45,9 @@ pango_atsui_font_finalize (GObject *object) pango_font_description_free (priv->desc); - g_object_unref (priv->fontmap); + g_assert (priv->fontmap != NULL); + g_object_remove_weak_pointer (G_OBJECT (priv->fontmap), (gpointer *) (gpointer) &priv->fontmap); + priv->fontmap = NULL; G_OBJECT_CLASS (pango_atsui_font_parent_class)->finalize (object); } @@ -135,8 +137,8 @@ _pango_atsui_font_set_font_map (PangoATSUIFont *font, PangoATSUIFontPrivate *priv = font->priv; g_assert (priv->fontmap == NULL); - - priv->fontmap = g_object_ref (fontmap); + priv->fontmap = (PangoFontMap *) fontmap; + g_object_add_weak_pointer (G_OBJECT (prev->fontmap), (gpointer *) (gpointer) &priv->fontmap); } void diff --git a/pango/pangocairo-font.c b/pango/pangocairo-font.c index 0ce3cafc..15757eee 100644 --- a/pango/pangocairo-font.c +++ b/pango/pangocairo-font.c @@ -223,17 +223,24 @@ _pango_cairo_font_get_metrics (PangoFont *font, if (!tmp_list) { + PangoFontMap *fontmap; PangoContext *context; cairo_font_options_t *font_options; int height, shift; + /* XXX this is racy. need a ref'ing getter... */ + fontmap = pango_font_get_font_map (font); + if (!fontmap) + return pango_font_metrics_new (); + fontmap = g_object_ref (fontmap); + info = g_slice_new0 (PangoCairoFontMetricsInfo); cf_priv->metrics_by_lang = g_slist_prepend (cf_priv->metrics_by_lang, info); info->sample_str = sample_str; - context = pango_font_map_create_context (pango_font_get_font_map (font)); + context = pango_font_map_create_context (fontmap); pango_context_set_language (context, language); font_options = cairo_font_options_create (); cairo_scaled_font_get_font_options (_pango_cairo_font_private_get_scaled_font (cf_priv), font_options); @@ -271,6 +278,7 @@ _pango_cairo_font_get_metrics (PangoFont *font, info->metrics->ascent = height - info->metrics->descent; g_object_unref (context); + g_object_unref (fontmap); } return pango_font_metrics_ref (info->metrics); @@ -356,10 +364,14 @@ _pango_cairo_font_private_get_hex_box_info (PangoCairoFontPrivate *cf_priv) /* create mini_font description */ { - PangoContext *context; PangoFontMap *fontmap; + PangoContext *context; + /* XXX this is racy. need a ref'ing getter... */ fontmap = pango_font_get_font_map ((PangoFont *)cf_priv->cfont); + if (!fontmap) + return NULL; + fontmap = g_object_ref (fontmap); /* we inherit most font properties for the mini font. just * change family and size. means, you get bold hex digits @@ -396,6 +408,7 @@ _pango_cairo_font_private_get_hex_box_info (PangoCairoFontPrivate *cf_priv) mini_font = pango_font_map_load_font (fontmap, context, desc); g_object_unref (context); + g_object_unref (fontmap); } pango_font_description_free (desc); diff --git a/pango/pangocairo-win32font.c b/pango/pangocairo-win32font.c index 6cfe29ed..4f0ec3d7 100644 --- a/pango/pangocairo-win32font.c +++ b/pango/pangocairo-win32font.c @@ -288,8 +288,9 @@ _pango_cairo_win32_font_new (PangoCairoWin32FontMap *cwfontmap, cwfont = g_object_new (PANGO_TYPE_CAIRO_WIN32_FONT, NULL); win32font = PANGO_WIN32_FONT (cwfont); - win32font->fontmap = PANGO_FONT_MAP (cwfontmap); - g_object_ref (cwfontmap); + g_assert (win32font->fontmap == NULL); + win32font->fontmap = (PangoFontMap *) cwfontmap; + g_object_add_weak_pointer (G_OBJECT (win32font->fontmap), (gpointer *) (gpointer) &win32font->fontmap); win32font->win32face = face; diff --git a/pango/pangofc-font.c b/pango/pangofc-font.c index 8bd23e2b..9acd75d6 100644 --- a/pango/pangofc-font.c +++ b/pango/pangofc-font.c @@ -529,10 +529,14 @@ pango_fc_font_get_metrics (PangoFont *font, if (!tmp_list) { + PangoFontMap *fontmap; PangoContext *context; - if (!fcfont->fontmap) + /* XXX this is racy. because weakref's are racy... */ + fontmap = fcfont->fontmap; + if (!fontmap) return pango_font_metrics_new (); + fontmap = g_object_ref (fontmap); info = g_slice_new0 (PangoFcMetricsInfo); @@ -541,12 +545,13 @@ pango_fc_font_get_metrics (PangoFont *font, info->sample_str = sample_str; - context = pango_font_map_create_context (fcfont->fontmap); + context = pango_font_map_create_context (fontmap); pango_context_set_language (context, language); info->metrics = pango_fc_font_create_metrics_for_context (fcfont, context); g_object_unref (context); + g_object_unref (fontmap); } return pango_font_metrics_ref (info->metrics); diff --git a/pango/pangofc-fontmap.c b/pango/pangofc-fontmap.c index e3963e84..0bc21b96 100644 --- a/pango/pangofc-fontmap.c +++ b/pango/pangofc-fontmap.c @@ -554,8 +554,11 @@ pango_fc_font_map_add (PangoFcFontMap *fcfontmap, FontHashKey *key_copy; g_assert (fcfont->fontmap == NULL); - - fcfont->fontmap = g_object_ref (fcfontmap); + fcfont->fontmap = (PangoFontMap *) fcfontmap; + /* In other fontmaps we add a weak pointer on ->fontmap so the + * field is unset when fontmap is finalized. We don't need it + * here though as PangoFcFontMap already cleans up fcfont->fontmap + * as part of it's caching scheme. */ font_hash_key_for_context (fcfontmap, context, &key); key.pattern = fcfont->font_pattern; @@ -597,7 +600,6 @@ _pango_fc_font_map_remove (PangoFcFontMap *fcfontmap, g_hash_table_remove (priv->font_hash, &key); fcfont->fontmap = NULL; _pango_fc_font_set_context_key (fcfont, NULL); - g_object_unref (fcfontmap); } static PangoFcFamily * @@ -1435,7 +1437,6 @@ cleanup_font (gpointer key, { _pango_fc_font_shutdown (fcfont); - g_object_unref (fcfont->fontmap); fcfont->fontmap = NULL; } diff --git a/pango/pangowin32-fontmap.c b/pango/pangowin32-fontmap.c index 055f99bd..28e0ebd0 100644 --- a/pango/pangowin32-fontmap.c +++ b/pango/pangowin32-fontmap.c @@ -667,8 +667,9 @@ pango_win32_font_neww (PangoFontMap *fontmap, result = (PangoWin32Font *)g_object_new (PANGO_TYPE_WIN32_FONT, NULL); + g_assert (result->fontmap == NULL); result->fontmap = fontmap; - g_object_ref (fontmap); + g_object_add_weak_pointer (G_OBJECT (result->fontmap), (gpointer *) (gpointer) &result->fontmap); result->size = size; _pango_win32_make_matching_logfontw (fontmap, lfp, size, &result->logfontw); @@ -713,7 +714,6 @@ pango_win32_font_map_real_find_font (PangoWin32FontMap *win32fontmap, if (!win32font) return NULL; - win32font->fontmap = fontmap; win32font->win32face = face; face->cached_fonts = g_slist_prepend (face->cached_fonts, win32font); diff --git a/pango/pangowin32.c b/pango/pangowin32.c index d2e8ad5f..1f8c1d25 100644 --- a/pango/pangowin32.c +++ b/pango/pangowin32.c @@ -835,7 +835,9 @@ pango_win32_font_finalize (GObject *object) g_hash_table_destroy (win32font->glyph_info); - g_object_unref (win32font->fontmap); + g_assert (win32font->fontmap != NULL); + g_object_remove_weak_pointer (G_OBJECT (win32font->fontmap), (gpointer *) (gpointer) &win32font->fontmap); + win32font->fontmap = NULL; G_OBJECT_CLASS (_pango_win32_font_parent_class)->finalize (object); } diff --git a/pango/pangox-fontmap.c b/pango/pangox-fontmap.c index 716374ba..1cfc0aec 100644 --- a/pango/pangox-fontmap.c +++ b/pango/pangox-fontmap.c @@ -519,7 +519,6 @@ pango_x_font_map_load_font (PangoFontMap *fontmap, { PangoXFont *xfont = pango_x_font_new (fontmap, best_match->xlfd, size); - xfont->fontmap = fontmap; xfont->xface = best_match; best_match->cached_fonts = g_slist_prepend (best_match->cached_fonts, xfont); diff --git a/pango/pangox.c b/pango/pangox.c index 92bedff8..b542f852 100644 --- a/pango/pangox.c +++ b/pango/pangox.c @@ -298,8 +298,10 @@ pango_x_font_new (PangoFontMap *fontmap, const char *spec, int size) result = g_object_new (PANGO_TYPE_X_FONT, NULL); + g_assert (result->fontmap == NULL); result->fontmap = fontmap; - g_object_ref (fontmap); + g_object_add_weak_pointer (G_OBJECT (result->fontmap), (gpointer *) (gpointer) &result->fontmap); + result->display = pango_x_fontmap_get_display (fontmap); result->fonts = g_strsplit(spec, ",", -1); @@ -1318,7 +1320,9 @@ pango_x_font_finalize (GObject *object) if (xfont->xface) pango_x_face_remove (xfont->xface, (PangoFont *)xfont); - g_object_unref (xfont->fontmap); + g_assert (xfont->fontmap != NULL); + g_object_remove_weak_pointer (G_OBJECT (xfont->fontmap), (gpointer *) (gpointer) &xfont->fontmap); + xfont->fontmap = NULL; g_strfreev (xfont->fonts); |