diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2011-12-23 00:18:36 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2011-12-23 00:18:36 +0100 |
commit | 9eb0d8bab1c475edf73c36146d1c3d31ea47f997 (patch) | |
tree | c8701f68cfd4b6e3fa2b8579b0b2596f959fc1bb | |
parent | dd1fb6528791b32ac9d6b3c2d81707cf1949ec5d (diff) | |
download | ffmpeg-9eb0d8bab1c475edf73c36146d1c3d31ea47f997.tar.gz |
fifo: Make writes atomic.
Prior to this a X bytes write could be seen as less than X bytes being
available if the check was done at an unfortunate moment.
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavutil/fifo.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/libavutil/fifo.c b/libavutil/fifo.c index 3ebd5f9b20..d1d9ba8003 100644 --- a/libavutil/fifo.c +++ b/libavutil/fifo.c @@ -83,22 +83,27 @@ int av_fifo_realloc2(AVFifoBuffer *f, unsigned int new_size) int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int (*func)(void*, void*, int)) { int total = size; + uint32_t wndx= f->wndx; + uint8_t *wptr= f->wptr; + do { - int len = FFMIN(f->end - f->wptr, size); + int len = FFMIN(f->end - wptr, size); if (func) { - if (func(src, f->wptr, len) <= 0) + if (func(src, wptr, len) <= 0) break; } else { - memcpy(f->wptr, src, len); + memcpy(wptr, src, len); src = (uint8_t*)src + len; } // Write memory barrier needed for SMP here in theory - f->wptr += len; - if (f->wptr >= f->end) - f->wptr = f->buffer; - f->wndx += len; + wptr += len; + if (wptr >= f->end) + wptr = f->buffer; + wndx += len; size -= len; } while (size > 0); + f->wndx= wndx; + f->wptr= wptr; return total - size; } |