diff options
author | Mikhail Fludkov <misha@pexip.com> | 2017-10-06 13:47:51 +0200 |
---|---|---|
committer | Adrian Johnson <ajohnson@redneon.com> | 2017-10-15 18:51:04 +1030 |
commit | 90104809b0e03d28ac1152034fd4f05fc8e97b9a (patch) | |
tree | 3b2cd2961a1d85c56e8edaaf3c3cdb9f435ac7d0 /src/cairo-image-compositor.c | |
parent | 79e0e25e441a74e3ec207d95bd83437457ba1885 (diff) | |
download | cairo-90104809b0e03d28ac1152034fd4f05fc8e97b9a.tar.gz |
Surround initialisations with atomic critical section
Fixes the race condition when one thread uses cairo_mask_compositor_t
pointer returned by _cairo_image_mask_compositor_get, while another one
started but has not finished it's initialisation yet
Usage:
static cairo_atomic_once_t once = CAIRO_ATOMIC_ONCE_INIT;
if (_cairo_atomic_init_once_enter(&once)) {
/* Initialization code */
_cairo_atomic_init_once_leave(&once);
}
https://bugs.freedesktop.org/show_bug.cgi?id=103037
Diffstat (limited to 'src/cairo-image-compositor.c')
-rw-r--r-- | src/cairo-image-compositor.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/src/cairo-image-compositor.c b/src/cairo-image-compositor.c index bfa1e92d4..2d25a31bb 100644 --- a/src/cairo-image-compositor.c +++ b/src/cairo-image-compositor.c @@ -1244,11 +1244,12 @@ check_composite (const cairo_composite_rectangles_t *extents) const cairo_compositor_t * _cairo_image_traps_compositor_get (void) { + static cairo_atomic_once_t once = CAIRO_ATOMIC_ONCE_INIT; static cairo_traps_compositor_t compositor; - if (compositor.base.delegate == NULL) { - _cairo_traps_compositor_init (&compositor, - &__cairo_no_compositor); + if (_cairo_atomic_init_once_enter(&once)) { + _cairo_traps_compositor_init(&compositor, + &__cairo_no_compositor); compositor.acquire = acquire; compositor.release = release; compositor.set_clip_region = set_clip_region; @@ -1269,6 +1270,8 @@ _cairo_image_traps_compositor_get (void) #endif compositor.check_composite_glyphs = check_composite_glyphs; compositor.composite_glyphs = composite_glyphs; + + _cairo_atomic_init_once_leave(&once); } return &compositor.base; @@ -1277,9 +1280,10 @@ _cairo_image_traps_compositor_get (void) const cairo_compositor_t * _cairo_image_mask_compositor_get (void) { + static cairo_atomic_once_t once = CAIRO_ATOMIC_ONCE_INIT; static cairo_mask_compositor_t compositor; - if (compositor.base.delegate == NULL) { + if (_cairo_atomic_init_once_enter(&once)) { _cairo_mask_compositor_init (&compositor, _cairo_image_traps_compositor_get ()); compositor.acquire = acquire; @@ -1296,6 +1300,8 @@ _cairo_image_mask_compositor_get (void) compositor.composite_boxes = composite_boxes; compositor.check_composite_glyphs = check_composite_glyphs; compositor.composite_glyphs = composite_glyphs; + + _cairo_atomic_init_once_leave(&once); } return &compositor.base; @@ -3105,10 +3111,11 @@ span_renderer_fini (cairo_abstract_span_renderer_t *_r, const cairo_compositor_t * _cairo_image_spans_compositor_get (void) { + static cairo_atomic_once_t once = CAIRO_ATOMIC_ONCE_INIT; static cairo_spans_compositor_t spans; static cairo_compositor_t shape; - if (spans.base.delegate == NULL) { + if (_cairo_atomic_init_once_enter(&once)) { _cairo_shape_mask_compositor_init (&shape, _cairo_image_traps_compositor_get()); shape.glyphs = NULL; @@ -3131,6 +3138,8 @@ _cairo_image_spans_compositor_get (void) //spans.check_span_renderer = check_span_renderer; spans.renderer_init = span_renderer_init; spans.renderer_fini = span_renderer_fini; + + _cairo_atomic_init_once_leave(&once); } return &spans.base; |