summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2021-07-02 03:42:15 +0000
committerMatthias Clasen <mclasen@redhat.com>2021-07-02 03:42:15 +0000
commitb4f521235eaecc594245bdf91c3d60841c810784 (patch)
tree6c9f083597f6b5e88cf7d63f80f4783c71525ce9
parentdf91ff22c83eb726e7f20bf714655ad1ea24832d (diff)
parent384f0e1530d36a1ac4bb95c3666a708927ec4f0c (diff)
downloadpango-b4f521235eaecc594245bdf91c3d60841c810784.tar.gz
Merge branch 'fc-fontmap-crash' into 'master'
Use atomic reference counting for PangoFcPatterns Closes #571 See merge request GNOME/pango!354
-rw-r--r--pango/pangofc-fontmap.c47
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);