Commit 189bc59e authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

block_mmap_Alloc: commoditize block allocation from mmap

Only the file access uses this, but I don't like "wild" callbacks into plugins.
parent bbfa9d88
...@@ -148,6 +148,18 @@ static inline void block_Release( block_t *p_block ) ...@@ -148,6 +148,18 @@ static inline void block_Release( block_t *p_block )
p_block->pf_release( 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 * Chains of blocks functions helper
**************************************************************************** ****************************************************************************
......
...@@ -345,23 +345,6 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len ) ...@@ -345,23 +345,6 @@ static ssize_t Read( access_t *p_access, uint8_t *p_buffer, size_t i_len )
#ifdef HAVE_MMAP #ifdef HAVE_MMAP
# define MMAP_SIZE (1 << 20) # 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) static block_t *mmapBlock (access_t *p_access)
{ {
access_sys_t *p_sys = p_access->p_sys; access_sys_t *p_sys = p_access->p_sys;
...@@ -420,36 +403,31 @@ static block_t *mmapBlock (access_t *p_access) ...@@ -420,36 +403,31 @@ static block_t *mmapBlock (access_t *p_access)
} }
p_access->info.i_pos = offset + length; 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) if (block == NULL)
{
munmap (addr, length);
return NULL; return NULL;
}
block_Init (&block->self, ((uint8_t *)addr) + align, length - align); block->p_buffer += align;
block->self.pf_release = mmapRelease; block->i_buffer -= align;
block->base_addr = addr;
block->length = length;
//vlc_object_yield (block->owner = VLC_OBJECT (p_access));
#ifndef NDEBUG #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 */ /* Compare normal I/O with memory mapping */
char *buf = malloc (block->self.i_buffer); char *buf = malloc (block->i_buffer);
ssize_t i_read = read (p_sys->fd, buf, block->self.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, msg_Err (p_access, "read %u instead of %u bytes", (unsigned)i_read,
(unsigned)block->self.i_buffer); (unsigned)block->i_buffer);
if (memcmp (buf, block->self.p_buffer, block->self.i_buffer)) if (memcmp (buf, block->p_buffer, block->i_buffer))
msg_Err (p_access, "inconsistent data buffer"); msg_Err (p_access, "inconsistent data buffer");
free (buf); free (buf);
#endif #endif
return &block->self; return block;
} }
#endif #endif
......
...@@ -42,6 +42,7 @@ block_FifoShow ...@@ -42,6 +42,7 @@ block_FifoShow
block_FifoSize block_FifoSize
block_FifoWake block_FifoWake
block_Init block_Init
block_mmap_Alloc
block_Realloc block_Realloc
config_ChainCreate config_ChainCreate
config_ChainDestroy config_ChainDestroy
......
...@@ -155,6 +155,44 @@ block_t *block_Realloc( block_t *p_block, ssize_t i_prebody, size_t i_body ) ...@@ -155,6 +155,44 @@ block_t *block_Realloc( block_t *p_block, ssize_t i_prebody, size_t i_body )
return p_block; return p_block;
} }
#ifdef HAVE_MMAP
# include <sys/mman.h>
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 * block_fifo_t management
*****************************************************************************/ *****************************************************************************/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment