diff options
author | Christian Hergert <chergert@redhat.com> | 2021-02-24 10:33:02 -0800 |
---|---|---|
committer | Christian Hergert <chergert@redhat.com> | 2021-02-24 10:33:02 -0800 |
commit | 92481ff02739b7b6db3a6b060db49414ddfdb0ad (patch) | |
tree | 0e795df5b524c711dc6e6f55598a15c32838ffbe | |
parent | 4a3eac9f139b5697ef454491ac590d75473c96a9 (diff) | |
download | pango-wip/chergert/fontmap-cleanup.tar.gz |
fontmap: be more defensive in patterns finalizationwip/chergert/fontmap-cleanup
This clears a few pointers defensively in cleanup. It also uses a weak
pointer on the PangoFcFontMap so that we don't dereference the raw
pointer if we race during finalization.
-rw-r--r-- | pango/pangofc-fontmap.c | 36 |
1 files changed, 20 insertions, 16 deletions
diff --git a/pango/pangofc-fontmap.c b/pango/pangofc-fontmap.c index aa90345e..febaf51c 100644 --- a/pango/pangofc-fontmap.c +++ b/pango/pangofc-fontmap.c @@ -816,9 +816,9 @@ thread_data_free (gpointer data) ThreadData *td = data; g_clear_pointer (&td->fonts, FcFontSetDestroy); - FcPatternDestroy (td->pattern); - FcConfigDestroy (td->config); - pango_fc_patterns_unref (td->patterns); + g_clear_pointer (&td->pattern, FcPatternDestroy); + g_clear_pointer (&td->config, FcConfigDestroy); + g_clear_pointer (&td->patterns, pango_fc_patterns_unref); g_free (td); } @@ -887,6 +887,9 @@ pango_fc_patterns_new (FcPattern *pat, PangoFcFontMap *fontmap) pats->fontmap = fontmap; + g_object_add_weak_pointer (G_OBJECT (fontmap), + (gpointer *)&pats->fontmap); + pats->ref_count = 1; FcPatternReference (pat); pats->pattern = pat; @@ -932,21 +935,22 @@ pango_fc_patterns_unref (PangoFcPatterns *pats) if (pats->ref_count) return; - /* Only remove from fontmap hash if we are in it. This is not necessarily - * the case after a cache_clear() call. */ - if (pats->fontmap->priv->patterns_hash && - pats == g_hash_table_lookup (pats->fontmap->priv->patterns_hash, pats->pattern)) - g_hash_table_remove (pats->fontmap->priv->patterns_hash, - pats->pattern); - - if (pats->pattern) - FcPatternDestroy (pats->pattern); + if (pats->fontmap) + { + g_object_remove_weak_pointer (G_OBJECT (pats->fontmap), + (gpointer *)&pats->fontmap); - if (pats->match) - FcPatternDestroy (pats->match); + /* Only remove from fontmap hash if we are in it. This is not necessarily + * the case after a cache_clear() call. */ + if (pats->fontmap->priv->patterns_hash && + pats == g_hash_table_lookup (pats->fontmap->priv->patterns_hash, pats->pattern)) + g_hash_table_remove (pats->fontmap->priv->patterns_hash, + pats->pattern); + } - if (pats->fontset) - FcFontSetDestroy (pats->fontset); + g_clear_pointer (&pats->pattern, FcPatternDestroy); + g_clear_pointer (&pats->match, FcPatternDestroy); + g_clear_pointer (&pats->fontset, FcFontSetDestroy); g_cond_clear (&pats->cond); g_mutex_clear (&pats->mutex); |