History

Merge commit 'fbd6c97f9ca858140df16dd07200ea0d4bdc1a83'

* commit 'fbd6c97f9ca858140df16dd07200ea0d4bdc1a83': lavu: fix memory leaks by using a mutex instead of atomics Conflicts: libavutil/buffer.c The atomics code is left in place as a fallback for synchronization in the absence of p/w32 threads. Our ABI did not requires applications to only use threads (and matching ones) to what libavutil was build with Our code also was not affected by the leak this change fixes, though no question the atomics based implementation is not pretty at all. First and foremost the code must work, being pretty comes after that. If this causes problems, for example when libavutil is used by multiple applications each using a different kind of threading system then the default possibly has to be changed to the uglier atomics.

Michael Niedermayer committed 11 years ago

Commit 6db8cd82 parents f00e9c4 fbd6c972 files · +39 −3Browse files

Showing the changes to libavutil/buffer.c (1 of 2 files). Show all

Unified · Split

libavutil/buffer.c+35−1
@@ -23,6 +23,9 @@ · 22 unmodified lines
23#include "buffer_internal.h"23#include "buffer_internal.h"
24#include "common.h"24#include "common.h"
25#include "mem.h"25#include "mem.h"
26#include "thread.h"
27
28#define USE_ATOMICS !(HAVE_PTHREADS || HAVE_W32THREADS)
26 29
27AVBufferRef *av_buffer_create(uint8_t *data, int size,30AVBufferRef *av_buffer_create(uint8_t *data, int size,
28 void (*free)(void *opaque, uint8_t *data),31 void (*free)(void *opaque, uint8_t *data),
@@ -209,6 +212,8 @@ AVBufferPool *av_buffer_pool_init(int size, AVBufferRef* (*alloc)(int size)) · 180 unmodified lines
209 if (!pool)212 if (!pool)
210 return NULL;213 return NULL;
211 214
215 ff_mutex_init(&pool->mutex, NULL);
216
212 pool->size = size;217 pool->size = size;
213 pool->alloc = alloc ? alloc : av_buffer_alloc;218 pool->alloc = alloc ? alloc : av_buffer_alloc;
214 219
@@ -230,6 +235,7 @@ static void buffer_pool_free(AVBufferPool *pool) · 15 unmodified lines
230 buf->free(buf->opaque, buf->data);235 buf->free(buf->opaque, buf->data);
231 av_freep(&buf);236 av_freep(&buf);
232 }237 }
238 ff_mutex_destroy(&pool->mutex);
233 av_freep(&pool);239 av_freep(&pool);
234}240}
235 241
@@ -290,7 +296,15 @@ static void pool_release_buffer(void *opaque, uint8_t *data) · 54 unmodified lines
290 if(CONFIG_MEMORY_POISONING)296 if(CONFIG_MEMORY_POISONING)
291 memset(buf->data, FF_MEMORY_POISON, pool->size);297 memset(buf->data, FF_MEMORY_POISON, pool->size);
292 298
299#if USE_ATOMICS
293 add_to_pool(buf);300 add_to_pool(buf);
301#else
302 ff_mutex_lock(&pool->mutex);
303 buf->next = pool->pool;
304 pool->pool = buf;
305 ff_mutex_unlock(&pool->mutex);
306#endif
307
294 if (!avpriv_atomic_int_add_and_fetch(&pool->refcount, -1))308 if (!avpriv_atomic_int_add_and_fetch(&pool->refcount, -1))
295 buffer_pool_free(pool);309 buffer_pool_free(pool);
296}310}
@@ -320,8 +334,10 @@ static AVBufferRef *pool_alloc_buffer(AVBufferPool *pool) · 23 unmodified lines
320 ret->buffer->opaque = buf;334 ret->buffer->opaque = buf;
321 ret->buffer->free = pool_release_buffer;335 ret->buffer->free = pool_release_buffer;
322 336
337#if USE_ATOMICS
323 avpriv_atomic_int_add_and_fetch(&pool->refcount, 1);338 avpriv_atomic_int_add_and_fetch(&pool->refcount, 1);
324 avpriv_atomic_int_add_and_fetch(&pool->nb_allocated, 1);339 avpriv_atomic_int_add_and_fetch(&pool->nb_allocated, 1);
340#endif
325 341
326 return ret;342 return ret;
327}343}
@@ -331,6 +347,7 @@ AVBufferRef *av_buffer_pool_get(AVBufferPool *pool) · 3 unmodified lines
331 AVBufferRef *ret;347 AVBufferRef *ret;
332 BufferPoolEntry *buf;348 BufferPoolEntry *buf;
333 349
350#if USE_ATOMICS
334 /* check whether the pool is empty */351 /* check whether the pool is empty */
335 buf = get_pool(pool);352 buf = get_pool(pool);
336 if (!buf && pool->refcount <= pool->nb_allocated) {353 if (!buf && pool->refcount <= pool->nb_allocated) {
@@ -352,7 +369,24 @@ AVBufferRef *av_buffer_pool_get(AVBufferPool *pool) · 15 unmodified lines
352 add_to_pool(buf);369 add_to_pool(buf);
353 return NULL;370 return NULL;
354 }371 }
355 avpriv_atomic_int_add_and_fetch(&pool->refcount, 1);372#else
373 ff_mutex_lock(&pool->mutex);
374 buf = pool->pool;
375 if (buf) {
376 ret = av_buffer_create(buf->data, pool->size, pool_release_buffer,
377 buf, 0);
378 if (ret) {
379 pool->pool = buf->next;
380 buf->next = NULL;
381 }
382 } else {
383 ret = pool_alloc_buffer(pool);
384 }
385 ff_mutex_unlock(&pool->mutex);
386#endif
387
388 if (ret)
389 avpriv_atomic_int_add_and_fetch(&pool->refcount, 1);
356 390
357 return ret;391 return ret;
358}392}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t