vlc | branch: master | Rémi Denis-Courmont <[email protected]> | Tue Sep 1 18:14:47 2015 +0300| [d90462630eb00b2ab7db3c2110000254d10e4f01] | committer: Rémi Denis-Courmont
block: add block_TryRealloc() This works like block_Realloc() but retains the original block in case of failure. > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=d90462630eb00b2ab7db3c2110000254d10e4f01 --- include/vlc_block.h | 1 + src/misc/block.c | 86 ++++++++++++++++++++++++++------------------------- 2 files changed, 45 insertions(+), 42 deletions(-) diff --git a/include/vlc_block.h b/include/vlc_block.h index e8589f6..1dc6ec4 100644 --- a/include/vlc_block.h +++ b/include/vlc_block.h @@ -137,6 +137,7 @@ struct block_t ****************************************************************************/ VLC_API void block_Init( block_t *, void *, size_t ); VLC_API block_t *block_Alloc( size_t ) VLC_USED VLC_MALLOC; +block_t *block_TryRealloc(block_t *, ssize_t pre, size_t body) VLC_USED; VLC_API block_t *block_Realloc( block_t *, ssize_t i_pre, size_t i_body ) VLC_USED; static inline void block_CopyProperties( block_t *dst, block_t *src ) diff --git a/src/misc/block.c b/src/misc/block.c index ef1d557..0d856f3 100644 --- a/src/misc/block.c +++ b/src/misc/block.c @@ -145,28 +145,42 @@ block_t *block_Alloc (size_t size) return b; } -block_t *block_Realloc( block_t *p_block, ssize_t i_prebody, size_t i_body ) +block_t *block_TryRealloc (block_t *p_block, ssize_t i_prebody, size_t i_body) { - size_t requested = i_prebody + i_body; - block_Check( p_block ); /* Corner case: empty block requested */ if( i_prebody <= 0 && i_body <= (size_t)(-i_prebody) ) - { - block_Release( p_block ); - return NULL; - } + i_prebody = i_body = 0; assert( p_block->p_start <= p_block->p_buffer ); assert( p_block->p_start + p_block->i_size >= p_block->p_buffer + p_block->i_buffer ); - /* Corner case: the current payload is discarded completely */ - if( i_prebody <= 0 && p_block->i_buffer <= (size_t)-i_prebody ) - p_block->i_buffer = 0; /* discard current payload */ - if( p_block->i_buffer == 0 ) + /* First, shrink payload */ + + /* Pull payload start */ + if( i_prebody < 0 ) { + if( p_block->i_buffer >= (size_t)-i_prebody ) + { + p_block->p_buffer -= i_prebody; + p_block->i_buffer += i_prebody; + } + else /* Discard current payload entirely */ + p_block->i_buffer = 0; + i_body += i_prebody; + i_prebody = 0; + } + + /* Trim payload end */ + if( p_block->i_buffer > i_body ) + p_block->i_buffer = i_body; + + size_t requested = i_prebody + i_body; + + if( p_block->i_buffer == 0 ) + { /* Corner case: nothing to preserve */ if( requested <= p_block->i_size ) { /* Enough room: recycle buffer */ size_t extra = p_block->i_size - requested; @@ -175,54 +189,35 @@ block_t *block_Realloc( block_t *p_block, ssize_t i_prebody, size_t i_body ) p_block->i_buffer = requested; return p_block; } + /* Not enough room: allocate a new buffer */ block_t *p_rea = block_Alloc( requested ); - if( p_rea ) - BlockMetaCopy( p_rea, p_block ); + if( p_rea == NULL ) + return NULL; + + BlockMetaCopy( p_rea, p_block ); block_Release( p_block ); return p_rea; } - /* First, shrink payload */ - - /* Pull payload start */ - if( i_prebody < 0 ) - { - assert( p_block->i_buffer >= (size_t)-i_prebody ); - p_block->p_buffer -= i_prebody; - p_block->i_buffer += i_prebody; - i_body += i_prebody; - i_prebody = 0; - } - - /* Trim payload end */ - if( p_block->i_buffer > i_body ) - p_block->i_buffer = i_body; - uint8_t *p_start = p_block->p_start; uint8_t *p_end = p_start + p_block->i_size; - /* Second, reallocate the buffer if we lack space. This is done now to - * minimize the payload size for memory copy. */ + /* Second, reallocate the buffer if we lack space. */ assert( i_prebody >= 0 ); if( (size_t)(p_block->p_buffer - p_start) < (size_t)i_prebody || (size_t)(p_end - p_block->p_buffer) < i_body ) { block_t *p_rea = block_Alloc( requested ); - if( p_rea ) - { - BlockMetaCopy( p_rea, p_block ); - p_rea->p_buffer += i_prebody; - p_rea->i_buffer -= i_prebody; - memcpy( p_rea->p_buffer, p_block->p_buffer, p_block->i_buffer ); - } - block_Release( p_block ); if( p_rea == NULL ) return NULL; - p_block = p_rea; - } - /* NOTE: p_start and p_end are corrupted from this point */ + memcpy( p_rea->p_buffer + i_prebody, p_block->p_buffer, + p_block->i_buffer ); + BlockMetaCopy( p_rea, p_block ); + block_Release( p_block ); + return p_rea; + } /* Third, expand payload */ @@ -241,6 +236,13 @@ block_t *block_Realloc( block_t *p_block, ssize_t i_prebody, size_t i_body ) return p_block; } +block_t *block_Realloc (block_t *block, ssize_t prebody, size_t body) +{ + block_t *rea = block_TryRealloc (block, prebody, body); + if (rea == NULL) + block_Release(block); + return rea; +} static void block_heap_Release (block_t *block) { _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
