summaryrefslogtreecommitdiff
path: root/src/cairo-freed-pool-private.h
diff options
context:
space:
mode:
authorWan-Teh Chang <wtc@google.com>2016-03-01 17:48:55 -0800
committerUli Schlachter <psychon@znc.in>2016-03-05 14:35:17 +0100
commit3538ac3e68f997d95d76865247717c90ae73630d (patch)
tree26b5a9f0fa70f78dd1d4aa07311cf89bbc2c40ba /src/cairo-freed-pool-private.h
parentaf42fc724e794aeb3b26eb0e8df453a5abd5c640 (diff)
downloadcairo-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.h10
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;
}