summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBehdad Esfahbod <behdad@gnome.org>2006-11-20 19:04:16 +0000
committerBehdad Esfahbod <behdad@src.gnome.org>2006-11-20 19:04:16 +0000
commita62260e8eacefe62ae1b1ee20b197fca5cb43cce (patch)
tree01a7a2677dd01cf171ecea683c826204cc6ac85d
parente1ba1aab1627d2fabaa781ac51c48a93394724dd (diff)
downloadpango-a62260e8eacefe62ae1b1ee20b197fca5cb43cce.tar.gz
Bug 356666 – pango is not thread-safe, nautilus does not honour that
2006-11-20 Behdad Esfahbod <behdad@gnome.org> Bug 356666 – pango is not thread-safe, nautilus does not honour that * pango/pangocairo-render.c (acquire_renderer), (release_renderer), (_pango_cairo_do_glyph_string), (_pango_cairo_do_layout_line), (_pango_cairo_do_layout): Instead of using a per-fontmap renderer, use a locally cached one, but make sure only one thread uses the cached renderer. Fixes the raciest point in pangocairo.
-rw-r--r--ChangeLog10
-rw-r--r--pango/pangocairo-render.c96
2 files changed, 57 insertions, 49 deletions
diff --git a/ChangeLog b/ChangeLog
index 2bf451ec..5150388e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2006-11-20 Behdad Esfahbod <behdad@gnome.org>
+
+ Bug 356666 – pango is not thread-safe, nautilus does not honour that
+
+ * pango/pangocairo-render.c (acquire_renderer), (release_renderer),
+ (_pango_cairo_do_glyph_string), (_pango_cairo_do_layout_line),
+ (_pango_cairo_do_layout): Instead of using a per-fontmap renderer, use
+ a locally cached one, but make sure only one thread uses the cached
+ renderer. Fixes the raciest point in pangocairo.
+
2006-11-14 Behdad Esfahbod <behdad@gnome.org>
Bug 352795 – configure.in: Bug in "checking Whether to write
diff --git a/pango/pangocairo-render.c b/pango/pangocairo-render.c
index 7b7b59ac..dd4d6cf3 100644
--- a/pango/pangocairo-render.c
+++ b/pango/pangocairo-render.c
@@ -394,6 +394,44 @@ pango_cairo_renderer_class_init (PangoCairoRendererClass *klass)
renderer_class->draw_error_underline = pango_cairo_renderer_draw_error_underline;
}
+static PangoCairoRenderer *cached_renderer = NULL;
+static GStaticMutex cached_renderer_mutex = G_STATIC_MUTEX_INIT;
+
+static PangoCairoRenderer *
+acquire_renderer (void)
+{
+ PangoCairoRenderer *renderer;
+
+ /* renderer = _pango_cairo_font_map_get_renderer (PANGO_CAIRO_FONT_MAP (fontmap)); */
+
+ if (G_LIKELY (g_static_mutex_trylock (&cached_renderer_mutex)))
+ {
+ if (G_UNLIKELY (!cached_renderer))
+ cached_renderer = g_object_new (PANGO_TYPE_CAIRO_RENDERER, NULL);
+
+ renderer = cached_renderer;
+ }
+ else
+ renderer = g_object_new (PANGO_TYPE_CAIRO_RENDERER, NULL);
+
+ return renderer;
+}
+
+release_renderer (PangoCairoRenderer *renderer)
+{
+ if (G_LIKELY (renderer == cached_renderer))
+ {
+ renderer->cr = NULL;
+ renderer->do_path = FALSE;
+ renderer->x_offset = 0.;
+ renderer->y_offset = 0.;
+
+ g_static_mutex_unlock (&cached_renderer_mutex);
+ }
+ else
+ g_object_unref (renderer);
+}
+
/* convenience wrappers using the default renderer */
@@ -404,20 +442,8 @@ _pango_cairo_do_glyph_string (cairo_t *cr,
PangoGlyphString *glyphs,
gboolean do_path)
{
- PangoFontMap *fontmap;
- PangoCairoRenderer *crenderer;
- PangoRenderer *renderer;
- gboolean unref_renderer = FALSE;
-
- fontmap = pango_font_get_font_map (font);
- renderer = _pango_cairo_font_map_get_renderer (PANGO_CAIRO_FONT_MAP (fontmap));
- if (G_UNLIKELY (!renderer))
- {
- renderer = g_object_new (PANGO_TYPE_CAIRO_RENDERER, NULL);
- unref_renderer = TRUE;
- }
-
- crenderer = PANGO_CAIRO_RENDERER (renderer);
+ PangoCairoRenderer *crenderer = acquire_renderer ();
+ PangoRenderer *renderer = (PangoRenderer *) crenderer;
crenderer->cr = cr;
crenderer->do_path = do_path;
@@ -444,15 +470,7 @@ _pango_cairo_do_glyph_string (cairo_t *cr,
pango_renderer_deactivate (renderer);
}
- if (G_UNLIKELY (unref_renderer))
- g_object_unref (renderer);
- else
- {
- crenderer->cr = NULL;
- crenderer->do_path = FALSE;
- crenderer->x_offset = 0.;
- crenderer->y_offset = 0.;
- }
+ release_renderer (crenderer);
}
static void
@@ -460,15 +478,8 @@ _pango_cairo_do_layout_line (cairo_t *cr,
PangoLayoutLine *line,
gboolean do_path)
{
- PangoContext *context;
- PangoFontMap *fontmap;
- PangoRenderer *renderer;
- PangoCairoRenderer *crenderer;
-
- context = pango_layout_get_context (line->layout);
- fontmap = pango_context_get_font_map (context);
- renderer = _pango_cairo_font_map_get_renderer (PANGO_CAIRO_FONT_MAP (fontmap));
- crenderer = PANGO_CAIRO_RENDERER (renderer);
+ PangoCairoRenderer *crenderer = acquire_renderer ();
+ PangoRenderer *renderer = (PangoRenderer *) crenderer;
crenderer->cr = cr;
crenderer->do_path = do_path;
@@ -476,10 +487,7 @@ _pango_cairo_do_layout_line (cairo_t *cr,
pango_renderer_draw_layout_line (renderer, line, 0, 0);
- crenderer->cr = NULL;
- crenderer->do_path = FALSE;
- crenderer->x_offset = 0.;
- crenderer->y_offset = 0.;
+ release_renderer (crenderer);
}
static void
@@ -487,15 +495,8 @@ _pango_cairo_do_layout (cairo_t *cr,
PangoLayout *layout,
gboolean do_path)
{
- PangoContext *context;
- PangoFontMap *fontmap;
- PangoRenderer *renderer;
- PangoCairoRenderer *crenderer;
-
- context = pango_layout_get_context (layout);
- fontmap = pango_context_get_font_map (context);
- renderer = _pango_cairo_font_map_get_renderer (PANGO_CAIRO_FONT_MAP (fontmap));
- crenderer = PANGO_CAIRO_RENDERER (renderer);
+ PangoCairoRenderer *crenderer = acquire_renderer ();
+ PangoRenderer *renderer = (PangoRenderer *) crenderer;
crenderer->cr = cr;
crenderer->do_path = do_path;
@@ -503,10 +504,7 @@ _pango_cairo_do_layout (cairo_t *cr,
pango_renderer_draw_layout (renderer, layout, 0, 0);
- crenderer->cr = NULL;
- crenderer->do_path = FALSE;
- crenderer->x_offset = 0.;
- crenderer->y_offset = 0.;
+ release_renderer (crenderer);
}
static void