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>
This commit is contained in:
Michael Niedermayer 2011-12-23 00:18:36 +01:00
parent dd1fb65287
commit 9eb0d8bab1

View File

@ -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 av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int (*func)(void*, void*, int))
{ {
int total = size; int total = size;
uint32_t wndx= f->wndx;
uint8_t *wptr= f->wptr;
do { do {
int len = FFMIN(f->end - f->wptr, size); int len = FFMIN(f->end - wptr, size);
if (func) { if (func) {
if (func(src, f->wptr, len) <= 0) if (func(src, wptr, len) <= 0)
break; break;
} else { } else {
memcpy(f->wptr, src, len); memcpy(wptr, src, len);
src = (uint8_t*)src + len; src = (uint8_t*)src + len;
} }
// Write memory barrier needed for SMP here in theory // Write memory barrier needed for SMP here in theory
f->wptr += len; wptr += len;
if (f->wptr >= f->end) if (wptr >= f->end)
f->wptr = f->buffer; wptr = f->buffer;
f->wndx += len; wndx += len;
size -= len; size -= len;
} while (size > 0); } while (size > 0);
f->wndx= wndx;
f->wptr= wptr;
return total - size; return total - size;
} }