[pango/threadsafe-failed-attempt: 9/11] Some more real hashtable threadsafety in pangofc



commit ae7dbbce8cbcc3801147d4130a63e0bdf482737f
Author: Behdad Esfahbod <behdad behdad org>
Date:   Mon Oct 15 21:41:59 2012 -0500

    Some more real hashtable threadsafety in pangofc

 pango/pango-threadsafe.h |   17 +++++++++++++++++
 pango/pangofc-fontmap.c  |   29 ++++++++++++++++-------------
 2 files changed, 33 insertions(+), 13 deletions(-)
---
diff --git a/pango/pango-threadsafe.h b/pango/pango-threadsafe.h
index cf8b425..57e823d 100644
--- a/pango/pango-threadsafe.h
+++ b/pango/pango-threadsafe.h
@@ -85,6 +85,23 @@ void        p_hash_table_insert            (PHashTable     *hash_table,
 }
 
 static inline
+gboolean    p_hash_table_insert_if_null    (PHashTable     *hash_table,
+                                            gpointer        key,
+                                            gpointer        value)
+{
+  gboolean ret;
+  g_mutex_lock (&hash_table->mx);
+  if (g_hash_table_lookup (hash_table->ht, key))
+    ret = FALSE;
+  else {
+    g_hash_table_insert (hash_table->ht, key, value);
+    ret = TRUE;
+  }
+  g_mutex_unlock (&hash_table->mx);
+  return ret;
+}
+
+static inline
 void        p_hash_table_replace           (PHashTable     *hash_table,
                                             gpointer        key,
                                             gpointer        value)
diff --git a/pango/pangofc-fontmap.c b/pango/pangofc-fontmap.c
index 2e031a8..22d9f0c 100644
--- a/pango/pangofc-fontmap.c
+++ b/pango/pangofc-fontmap.c
@@ -701,8 +701,8 @@ pango_fc_patterns_new (FcPattern *pat, PangoFcFontMap *fontmap)
   FcPatternReference (pat);
   pats->pattern = pat;
 
-  p_hash_table_insert (fontmap->priv->patterns_hash,
-		       pats->pattern, pats);
+  p_hash_table_insert_if_null (fontmap->priv->patterns_hash,
+			       pats->pattern, pats);
 
   return pats;
 }
@@ -712,7 +712,7 @@ pango_fc_patterns_ref (PangoFcPatterns *pats)
 {
   g_return_val_if_fail (pats->ref_count > 0, NULL);
 
-  pats->ref_count++;
+  g_atomic_int_inc (&pats->ref_count);
 
   return pats;
 }
@@ -722,9 +722,7 @@ pango_fc_patterns_unref (PangoFcPatterns *pats)
 {
   g_return_if_fail (pats->ref_count > 0);
 
-  pats->ref_count--;
-
-  if (pats->ref_count)
+  if (!g_atomic_int_dec_and_test (&pats->ref_count))
     return;
 
   /* Only remove from fontmap hash if we are in it.  This is not necessarily
@@ -1218,8 +1216,8 @@ pango_fc_font_map_add (PangoFcFontMap *fcfontmap,
 
   key_copy = pango_fc_font_key_copy (key);
   _pango_fc_font_set_font_key (fcfont, key_copy);
-  /* XXXXXXXXXXX racy here? */
-  p_hash_table_insert (priv->font_hash, key_copy, fcfont);
+  if (!p_hash_table_insert_if_null (priv->font_hash, key_copy, fcfont))
+    pango_fc_font_key_free (key_copy);
 }
 
 /* Remove mapping from fcfont->key to fcfont */
@@ -1509,7 +1507,6 @@ uniquify_pattern (PangoFcFontMap *fcfontmap,
   PangoFcFontMapPrivate *priv = fcfontmap->priv;
   FcPattern *old_pattern;
 
-  /* XXXXXX racy here? */
   old_pattern = p_hash_table_lookup (priv->pattern_hash, pattern);
   if (old_pattern)
     {
@@ -1518,7 +1515,8 @@ uniquify_pattern (PangoFcFontMap *fcfontmap,
   else
     {
       FcPatternReference (pattern);
-      p_hash_table_insert (priv->pattern_hash, pattern, pattern);
+      if (!p_hash_table_insert_if_null (priv->pattern_hash, pattern, pattern))
+        FcPatternDestroy (pattern);
       return pattern;
     }
 }
@@ -1766,7 +1764,8 @@ pango_fc_font_map_load_fontset (PangoFontMap                 *fontmap,
 	return NULL;
 
       fontset = pango_fc_fontset_new (&key, patterns);
-      p_hash_table_insert (priv->fontset_hash, pango_fc_fontset_get_key (fontset), g_object_ref (fontset));
+      if (!p_hash_table_insert_if_null (priv->fontset_hash, pango_fc_fontset_get_key (fontset), g_object_ref (fontset)))
+        g_object_unref (fontset);
 
       pango_fc_patterns_unref (patterns);
     }
@@ -1814,7 +1813,7 @@ pango_fc_font_map_get_font_face_data (PangoFcFontMap *fcfontmap,
   if (FcPatternGetInteger (font_pattern, FC_INDEX, 0, &key.id) != FcResultMatch)
     return NULL;
 
-  /* XXXXXXXXXX racy here */
+retry:
   data = p_hash_table_lookup (priv->font_face_data_hash, &key);
   if (G_LIKELY (data))
     return data;
@@ -1826,7 +1825,11 @@ pango_fc_font_map_get_font_face_data (PangoFcFontMap *fcfontmap,
   data->pattern = font_pattern;
   FcPatternReference (data->pattern);
 
-  p_hash_table_insert (priv->font_face_data_hash, data, data);
+  if (!p_hash_table_insert_if_null (priv->font_face_data_hash, data, data))
+    {
+      pango_fc_font_face_data_free (data);
+      goto retry;
+    }
 
   return data;
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]