From f001853ba97220d35897e2c1bcef2ed4f2d5c005 Mon Sep 17 00:00:00 2001 From: Mikhail Fludkov Date: Fri, 6 Oct 2017 13:47:51 +0200 Subject: [PATCH] Fix the race around accessing cairo_image_traps_compositor https://bugs.freedesktop.org/show_bug.cgi?id=103037 --- src/cairo-image-compositor.c | 59 ++++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/src/cairo-image-compositor.c b/src/cairo-image-compositor.c index bfa1e92..4227ccf 100644 --- a/src/cairo-image-compositor.c +++ b/src/cairo-image-compositor.c @@ -1244,34 +1244,39 @@ check_composite (const cairo_composite_rectangles_t *extents) const cairo_compositor_t * _cairo_image_traps_compositor_get (void) { - static cairo_traps_compositor_t compositor; - - if (compositor.base.delegate == NULL) { - _cairo_traps_compositor_init (&compositor, - &__cairo_no_compositor); - compositor.acquire = acquire; - compositor.release = release; - compositor.set_clip_region = set_clip_region; - compositor.pattern_to_surface = _cairo_image_source_create_for_pattern; - compositor.draw_image_boxes = draw_image_boxes; - //compositor.copy_boxes = copy_boxes; - compositor.fill_boxes = fill_boxes; - compositor.check_composite = check_composite; - compositor.composite = composite; - compositor.lerp = lerp; - //compositor.check_composite_boxes = check_composite_boxes; - compositor.composite_boxes = composite_boxes; - //compositor.check_composite_traps = check_composite_traps; - compositor.composite_traps = composite_traps; - //compositor.check_composite_tristrip = check_composite_traps; -#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,22,0) - compositor.composite_tristrip = composite_tristrip; -#endif - compositor.check_composite_glyphs = check_composite_glyphs; - compositor.composite_glyphs = composite_glyphs; - } + static int init = FALSE; + static int done = FALSE; + static cairo_traps_compositor_t compositor; + + if (_cairo_atomic_int_cmpxchg (&init, FALSE, TRUE)) { + _cairo_traps_compositor_init (&compositor, + &__cairo_no_compositor); + compositor.acquire = acquire; + compositor.release = release; + compositor.set_clip_region = set_clip_region; + compositor.pattern_to_surface = _cairo_image_source_create_for_pattern; + compositor.draw_image_boxes = draw_image_boxes; + //compositor.copy_boxes = copy_boxes; + compositor.fill_boxes = fill_boxes; + compositor.check_composite = check_composite; + compositor.composite = composite; + compositor.lerp = lerp; + //compositor.check_composite_boxes = check_composite_boxes; + compositor.composite_boxes = composite_boxes; + //compositor.check_composite_traps = check_composite_traps; + compositor.composite_traps = composite_traps; + //compositor.check_composite_tristrip = check_composite_traps; + #if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,22,0) + compositor.composite_tristrip = composite_tristrip; + #endif + compositor.check_composite_glyphs = check_composite_glyphs; + compositor.composite_glyphs = composite_glyphs; + _cairo_atomic_int_set_relaxed (&done, TRUE); + } else { + while (!_cairo_atomic_int_get(&done)) {} + } - return &compositor.base; + return &compositor.base; } const cairo_compositor_t * -- 2.7.4