aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2011-12-23 00:18:36 +0100
committerMichael Niedermayer <michaelni@gmx.at>2011-12-23 00:18:36 +0100
commit9eb0d8bab1c475edf73c36146d1c3d31ea47f997 (patch)
treec8701f68cfd4b6e3fa2b8579b0b2596f959fc1bb
parentdd1fb6528791b32ac9d6b3c2d81707cf1949ec5d (diff)
downloadffmpeg-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.c19
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;
}