diff options
author | Wan-Teh Chang <wtc@google.com> | 2016-03-01 17:48:55 -0800 |
---|---|---|
committer | Uli Schlachter <psychon@znc.in> | 2016-03-05 14:35:17 +0100 |
commit | 3538ac3e68f997d95d76865247717c90ae73630d (patch) | |
tree | 26b5a9f0fa70f78dd1d4aa07311cf89bbc2c40ba /src/cairo-freed-pool-private.h | |
parent | af42fc724e794aeb3b26eb0e8df453a5abd5c640 (diff) | |
download | cairo-3538ac3e68f997d95d76865247717c90ae73630d.tar.gz |
Fix data race in freed_pool
This adds _cairo_atomic_int_get_relaxed and _cairo_atomic_int_set_relaxed which
are meant to have a behaviour of relaxed read/writes in C11's memory model. This
patch also uses these new function to fix a data race with freed_pool_t's |top|
data member.
Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=90318
Signed-off-by: Wan-Teh Chang <wtc@google.com>
Signed-off-by: Uli Schlachter <psychon@znc.in>
Diffstat (limited to 'src/cairo-freed-pool-private.h')
-rw-r--r-- | src/cairo-freed-pool-private.h | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/src/cairo-freed-pool-private.h b/src/cairo-freed-pool-private.h index 0ec6de3d1..8a7af523d 100644 --- a/src/cairo-freed-pool-private.h +++ b/src/cairo-freed-pool-private.h @@ -51,7 +51,7 @@ CAIRO_BEGIN_DECLS #define MAX_FREED_POOL_SIZE 16 typedef struct { void *pool[MAX_FREED_POOL_SIZE]; - int top; + cairo_atomic_int_t top; } freed_pool_t; static cairo_always_inline void * @@ -81,13 +81,13 @@ _freed_pool_get (freed_pool_t *pool) void *ptr; int i; - i = pool->top - 1; + i = _cairo_atomic_int_get_relaxed (&pool->top) - 1; if (i < 0) i = 0; ptr = _atomic_fetch (&pool->pool[i]); if (likely (ptr != NULL)) { - pool->top = i; + _cairo_atomic_int_set_relaxed (&pool->top, i); return ptr; } @@ -103,11 +103,11 @@ _freed_pool_put (freed_pool_t *pool, void *ptr) { int i; - i = pool->top; + i = _cairo_atomic_int_get_relaxed (&pool->top); if (likely (i < ARRAY_LENGTH (pool->pool) && _atomic_store (&pool->pool[i], ptr))) { - pool->top = i + 1; + _cairo_atomic_int_set_relaxed (&pool->top, i + 1); return; } |