Make pango threadsafe!
authorBehdad Esfahbod <behdad@behdad.org>
Thu, 3 Jan 2013 09:52:09 +0000 (03:52 -0600)
committerBehdad Esfahbod <behdad@behdad.org>
Thu, 3 Jan 2013 09:52:09 +0000 (03:52 -0600)
By way of declaring fontmaps NOT threadsafe, and making
pango_cairo_font_map_get_default() return a thread-private fontmap.

test-pangocairo-threads doesn't crash anymore, if used with fontconfig
master.

pango/pangocairo-fontmap.c

index 1c235ac..461de9f 100644 (file)
@@ -66,9 +66,6 @@ pango_cairo_font_map_default_init (PangoCairoFontMapIface *iface)
 PangoFontMap *
 pango_cairo_font_map_new (void)
 {
-  /* Make sure that the type system is initialized */
-  g_type_init ();
-
 #if defined(HAVE_CORE_TEXT) && defined (HAVE_CAIRO_QUARTZ)
   return g_object_new (PANGO_TYPE_CAIRO_CORE_TEXT_FONT_MAP, NULL);
 #elif defined(HAVE_CAIRO_WIN32)
@@ -102,9 +99,6 @@ pango_cairo_font_map_new (void)
 PangoFontMap *
 pango_cairo_font_map_new_for_font_type (cairo_font_type_t fonttype)
 {
-  /* Make sure that the type system is initialized */
-  g_type_init ();
-
   switch ((int) fonttype)
   {
 #if defined(HAVE_CORE_TEXT) && defined (HAVE_CAIRO_QUARTZ)
@@ -124,7 +118,7 @@ pango_cairo_font_map_new_for_font_type (cairo_font_type_t fonttype)
   }
 }
 
-static PangoFontMap *default_font_map = NULL; /* MT-safe */
+static GPrivate default_font_map = G_PRIVATE_INIT (g_object_unref); /* MT-safe */
 
 /**
  * pango_cairo_font_map_get_default:
@@ -149,10 +143,15 @@ static PangoFontMap *default_font_map = NULL; /* MT-safe */
 PangoFontMap *
 pango_cairo_font_map_get_default (void)
 {
-  if (g_once_init_enter ((gsize*)&default_font_map))
-    g_once_init_leave((gsize*)&default_font_map, (gsize)pango_cairo_font_map_new ());
+  PangoFontMap *fontmap = g_private_get (&default_font_map);
 
-  return default_font_map;
+  if (G_UNLIKELY (!fontmap))
+    {
+      fontmap = pango_cairo_font_map_new ();
+      g_private_replace (&default_font_map, fontmap);
+    }
+
+  return fontmap;
 }
 
 /**
@@ -174,21 +173,9 @@ pango_cairo_font_map_get_default (void)
 void
 pango_cairo_font_map_set_default (PangoCairoFontMap *fontmap)
 {
-  PangoCairoFontMap *def;
-
   g_return_if_fail (fontmap == NULL || PANGO_IS_CAIRO_FONT_MAP (fontmap));
 
-retry:
-  def = g_atomic_pointer_get (&default_font_map);
-
-  if (!g_atomic_pointer_compare_and_exchange (&default_font_map, def, fontmap))
-    goto retry;
-
-  if (fontmap)
-    g_object_ref (fontmap);
-
-  if (def)
-    g_object_unref (def);
+  g_private_replace (&default_font_map, g_object_ref (fontmap));
 }
 
 /**