diff options
author | Behdad Esfahbod <behdad@gnome.org> | 2006-11-20 19:05:42 +0000 |
---|---|---|
committer | Behdad Esfahbod <behdad@src.gnome.org> | 2006-11-20 19:05:42 +0000 |
commit | 02189298f21336049c8374f6ce7f80f824adca53 (patch) | |
tree | 1a6efe29cef587f09b02b2c312247543ce0b8078 /pango/pangocairo-render.c | |
parent | bd01949fa8525ce740924eb307e694b695cee4dc (diff) | |
download | pango-02189298f21336049c8374f6ce7f80f824adca53.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.
Diffstat (limited to 'pango/pangocairo-render.c')
-rw-r--r-- | pango/pangocairo-render.c | 96 |
1 files changed, 47 insertions, 49 deletions
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 |