From: RĂ©mi Denis-Courmont Date: Fri, 28 Dec 2007 17:01:56 +0000 (+0000) Subject: block_mmap_Alloc: commoditize block allocation from mmap X-Git-Tag: 0.9.0-test0~3841 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=189bc59e7b442c9d898f2d460f4f780d8a079461;p=vlc block_mmap_Alloc: commoditize block allocation from mmap Only the file access uses this, but I don't like "wild" callbacks into plugins. --- diff --git a/include/vlc_block.h b/include/vlc_block.h index 8d46178831..fda20ce643 100644 --- a/include/vlc_block.h +++ b/include/vlc_block.h @@ -148,6 +148,18 @@ static inline void block_Release( block_t *p_block ) p_block->pf_release( p_block ); } +/** + * Creates a block from a virtual address memory mapping (mmap). + * This is provided by LibVLC so that mmap blocks can safely be deallocated + * even after the allocating plugin has been unloaded from memory. + * + * @param addr base address of the mapping (as returned by mmap) + * @param length length (bytes) of the mapping (as passed to mmap) + * @return NULL if addr is MAP_FAILED, or an error occurred (in the later + * case, munmap(addr, length) is invoked before returning). + */ +VLC_EXPORT( block_t *, block_mmap_Alloc, (void *addr, size_t length) ); + /**************************************************************************** * Chains of blocks functions helper **************************************************************************** diff --git a/modules/access/file.c b/modules/access/file.c index eceb4cc542..eac81228ce 100644 --- a/modules/access/file.c +++ b/modules/access/file.c @@ -345,23 +345,6 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len ) #ifdef HAVE_MMAP # define MMAP_SIZE (1 << 20) -struct block_sys_t -{ - block_t self; - //vlc_object_t *owner; - void *base_addr; - size_t length; -}; - -static void mmapRelease (block_t *block) -{ - block_sys_t *p_sys = (block_sys_t *)block; - - munmap (p_sys->base_addr, p_sys->length); - //vlc_object_release (p_sys->owner); - free (p_sys); -} - static block_t *mmapBlock (access_t *p_access) { access_sys_t *p_sys = p_access->p_sys; @@ -420,36 +403,31 @@ static block_t *mmapBlock (access_t *p_access) } p_access->info.i_pos = offset + length; - msg_Dbg (p_access, "mapped 0x%lx bytes at %p from offset 0x%lx", - (unsigned long)length, addr, (unsigned long)offset); - block_sys_t *block = malloc (sizeof (*block)); + block_t *block = block_mmap_Alloc (addr, length); if (block == NULL) - { - munmap (addr, length); return NULL; - } - block_Init (&block->self, ((uint8_t *)addr) + align, length - align); - block->self.pf_release = mmapRelease; - block->base_addr = addr; - block->length = length; - //vlc_object_yield (block->owner = VLC_OBJECT (p_access)); + block->p_buffer += align; + block->i_buffer -= align; #ifndef NDEBUG + msg_Dbg (p_access, "mapped 0x%lx bytes at %p from offset 0x%lx", + (unsigned long)length, addr, (unsigned long)offset); + /* Compare normal I/O with memory mapping */ - char *buf = malloc (block->self.i_buffer); - ssize_t i_read = read (p_sys->fd, buf, block->self.i_buffer); + char *buf = malloc (block->i_buffer); + ssize_t i_read = read (p_sys->fd, buf, block->i_buffer); - if (i_read != (ssize_t)block->self.i_buffer) + if (i_read != (ssize_t)block->i_buffer) msg_Err (p_access, "read %u instead of %u bytes", (unsigned)i_read, - (unsigned)block->self.i_buffer); - if (memcmp (buf, block->self.p_buffer, block->self.i_buffer)) + (unsigned)block->i_buffer); + if (memcmp (buf, block->p_buffer, block->i_buffer)) msg_Err (p_access, "inconsistent data buffer"); free (buf); #endif - return &block->self; + return block; } #endif diff --git a/src/libvlc.sym b/src/libvlc.sym index 750369db41..a593f09cd2 100644 --- a/src/libvlc.sym +++ b/src/libvlc.sym @@ -42,6 +42,7 @@ block_FifoShow block_FifoSize block_FifoWake block_Init +block_mmap_Alloc block_Realloc config_ChainCreate config_ChainDestroy diff --git a/src/misc/block.c b/src/misc/block.c index abd10e8b5e..7be282e958 100644 --- a/src/misc/block.c +++ b/src/misc/block.c @@ -155,6 +155,44 @@ block_t *block_Realloc( block_t *p_block, ssize_t i_prebody, size_t i_body ) return p_block; } +#ifdef HAVE_MMAP +# include + +typedef struct block_mmap_t +{ + block_t self; + void *base_addr; + size_t length; +} block_mmap_t; + +static void block_mmap_Release (block_t *block) +{ + block_mmap_t *p_sys = (block_mmap_t *)block; + + munmap (p_sys->base_addr, p_sys->length); + free (p_sys); +} + +block_t *block_mmap_Alloc (void *addr, size_t length) +{ + if (addr == MAP_FAILED) + return NULL; + + block_mmap_t *block = malloc (sizeof (*block)); + if (block == NULL) + { + munmap (addr, length); + return NULL; + } + + block_Init (&block->self, (uint8_t *)addr, length); + block->self.pf_release = block_mmap_Release; + block->base_addr = addr; + block->length = length; + return &block->self; +} +#endif + /***************************************************************************** * block_fifo_t management *****************************************************************************/