diff options
author | Matthias Clasen <mclasen@redhat.com> | 2021-07-02 03:42:15 +0000 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2021-07-02 03:42:15 +0000 |
commit | b4f521235eaecc594245bdf91c3d60841c810784 (patch) | |
tree | 6c9f083597f6b5e88cf7d63f80f4783c71525ce9 /pango | |
parent | df91ff22c83eb726e7f20bf714655ad1ea24832d (diff) | |
parent | 384f0e1530d36a1ac4bb95c3666a708927ec4f0c (diff) | |
download | pango-b4f521235eaecc594245bdf91c3d60841c810784.tar.gz |
Merge branch 'fc-fontmap-crash' into 'master'
Use atomic reference counting for PangoFcPatterns
Closes #571
See merge request GNOME/pango!354
Diffstat (limited to 'pango')
-rw-r--r-- | pango/pangofc-fontmap.c | 47 |
1 files changed, 25 insertions, 22 deletions
diff --git a/pango/pangofc-fontmap.c b/pango/pangofc-fontmap.c index 0df9de9f..7ea5dc52 100644 --- a/pango/pangofc-fontmap.c +++ b/pango/pangofc-fontmap.c @@ -100,13 +100,24 @@ * FcCharSetMerge(). */ +typedef enum { + /* Initial state; Fontconfig is not initialized yet */ + DEFAULT_CONFIG_NOT_INITIALIZED, + + /* We have a thread doing Fontconfig initialization in the background */ + DEFAULT_CONFIG_INITIALIZING, + + /* FcInit() finished and its default configuration is loaded */ + DEFAULT_CONFIG_INITIALIZED +} DefaultConfig; + /* We call FcInit in a thread and set fc_initialized * when done, and are protected by a mutex. The thread * signals the cond when FcInit is done. */ static GMutex fc_init_mutex; static GCond fc_init_cond; -static int fc_initialized = 0; +static DefaultConfig fc_initialized = DEFAULT_CONFIG_NOT_INITIALIZED; typedef struct _PangoFcFontFaceData PangoFcFontFaceData; @@ -743,8 +754,6 @@ pango_fc_font_key_get_variations (const PangoFcFontKey *key) */ struct _PangoFcPatterns { - guint ref_count; - PangoFcFontMap *fontmap; /* match and fontset are initialized in a thread, @@ -883,11 +892,10 @@ pango_fc_patterns_new (FcPattern *pat, PangoFcFontMap *fontmap) if (pats) return pango_fc_patterns_ref (pats); - pats = g_slice_new0 (PangoFcPatterns); + pats = g_atomic_rc_box_new0 (PangoFcPatterns); pats->fontmap = fontmap; - pats->ref_count = 1; FcPatternReference (pat); pats->pattern = pat; @@ -909,22 +917,13 @@ pango_fc_patterns_new (FcPattern *pat, PangoFcFontMap *fontmap) static PangoFcPatterns * pango_fc_patterns_ref (PangoFcPatterns *pats) { - g_return_val_if_fail (pats->ref_count > 0, NULL); - - pats->ref_count++; - - return pats; + return g_atomic_rc_box_acquire (pats); } static void -pango_fc_patterns_unref (PangoFcPatterns *pats) +free_patterns (gpointer data) { - g_return_if_fail (pats->ref_count > 0); - - pats->ref_count--; - - if (pats->ref_count) - return; + PangoFcPatterns *pats = data; /* Only remove from fontmap hash if we are in it. This is not necessarily * the case after a cache_clear() call. */ @@ -944,8 +943,12 @@ pango_fc_patterns_unref (PangoFcPatterns *pats) g_cond_clear (&pats->cond); g_mutex_clear (&pats->mutex); +} - g_slice_free (PangoFcPatterns, pats); +static void +pango_fc_patterns_unref (PangoFcPatterns *pats) +{ + g_atomic_rc_box_release_full (pats, free_patterns); } static FcPattern * @@ -1350,7 +1353,7 @@ init_in_thread (gpointer task_data) pango_trace_mark (before, "FcInit", NULL); g_mutex_lock (&fc_init_mutex); - fc_initialized = 2; + fc_initialized = DEFAULT_CONFIG_INITIALIZED; g_cond_broadcast (&fc_init_cond); g_mutex_unlock (&fc_init_mutex); @@ -1362,11 +1365,11 @@ start_init_in_thread (PangoFcFontMap *fcfontmap) { g_mutex_lock (&fc_init_mutex); - if (fc_initialized == 0) + if (fc_initialized == DEFAULT_CONFIG_NOT_INITIALIZED) { GThread *thread; - fc_initialized = 1; + fc_initialized = DEFAULT_CONFIG_INITIALIZING; thread = g_thread_new ("[pango] FcInit", init_in_thread, NULL); g_thread_unref (thread); } @@ -1381,7 +1384,7 @@ wait_for_fc_init (void) gboolean waited = FALSE; g_mutex_lock (&fc_init_mutex); - while (fc_initialized < 2) + while (fc_initialized < DEFAULT_CONFIG_INITIALIZED) { waited = TRUE; g_cond_wait (&fc_init_cond, &fc_init_mutex); |