summaryrefslogtreecommitdiff
path: root/libavutil/buffer.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2013-03-17 18:36:16 +0100
committerMichael Niedermayer <michaelni@gmx.at>2013-03-18 19:19:22 +0100
commitcea3a63ba3d89d8403eef008f7a7c54d645cff70 (patch)
tree3b2e553d6edec8c8ea3fbf1e3546231d3b3e34a2 /libavutil/buffer.c
parent73ef12757b9471474bfebda20792448e9bc4e3cc (diff)
avutil/buffer: Fix race in pool.
This race will always happen sooner or later in a multi-threaded environment and it will over time lead to OOM. This fix works by spinning, there are other ways by which this can be fixed, like simply detecting the issue after it happened and freeing the over-allocated memory or simply using a mutex. Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavutil/buffer.c')
-rw-r--r--libavutil/buffer.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/libavutil/buffer.c b/libavutil/buffer.c
index 5c753abce5..854733b32d 100644
--- a/libavutil/buffer.c
+++ b/libavutil/buffer.c
@@ -307,6 +307,7 @@ static AVBufferRef *pool_alloc_buffer(AVBufferPool *pool)
ret->buffer->free = pool_release_buffer;
avpriv_atomic_int_add_and_fetch(&pool->refcount, 1);
+ avpriv_atomic_int_add_and_fetch(&pool->nb_allocated, 1);
return ret;
}
@@ -318,6 +319,12 @@ AVBufferRef *av_buffer_pool_get(AVBufferPool *pool)
/* check whether the pool is empty */
buf = get_pool(pool);
+ if (!buf && pool->refcount <= pool->nb_allocated) {
+ av_log(NULL, AV_LOG_DEBUG, "Pool race dectected, spining to avoid overallocation and eventual OOM\n");
+ while (!buf && avpriv_atomic_int_get(&pool->refcount) <= avpriv_atomic_int_get(&pool->nb_allocated))
+ buf = get_pool(pool);
+ }
+
if (!buf)
return pool_alloc_buffer(pool);