X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmisc%2Fblock.c;h=0a408cc26d15766b7d531542638b7a36cd2f65b4;hb=8b0dd8cfdff0d9697fb44e7849764c9274965adb;hp=f99c2a24616ff5a599e84165db8d5acac45fded9;hpb=46a8f555cc0d2205a2125354de312a7c0067b734;p=vlc diff --git a/src/misc/block.c b/src/misc/block.c index f99c2a2461..0a408cc26d 100644 --- a/src/misc/block.c +++ b/src/misc/block.c @@ -31,13 +31,12 @@ #include #include #include -#ifdef HAVE_UNISTD_H -# include -#endif +#include +#include #include #include -#include /* For 64-bits lseek() definition */ +#include /** * @section Block handling functions. @@ -74,7 +73,6 @@ static void block_Invalidate (block_t *block) block->p_next = NULL; block_Check (block); block->pf_release = BlockNoRelease; - barrier (); /* prevent compiler from optimizing this assignment out */ } #else # define block_Check(b) ((void)(b)) @@ -117,11 +115,15 @@ static void BlockMetaCopy( block_t *restrict out, const block_t *in ) out->i_length = in->i_length; } -/* Memory alignment (must be a multiple of sizeof(void*) and a power of two) */ -#define BLOCK_ALIGN 16 -/* Initial reserved header and footer size (must be multiple of alignment) */ +/** Initial memory alignment of data block. + * @note This must be a multiple of sizeof(void*) and a power of two. + * libavcodec AVX optimizations require at least 32-bytes. */ +#define BLOCK_ALIGN 32 + +/** Initial reserved header and footer size. */ #define BLOCK_PADDING 32 -/* Maximum size of reserved footer before we release with realloc() */ + +/* Maximum size of reserved footer before shrinking with realloc(). */ #define BLOCK_WASTE_SIZE 2048 block_t *block_Alloc (size_t size) @@ -335,12 +337,58 @@ block_t *block_mmap_Alloc (void *addr, size_t length) } #endif +#ifdef HAVE_SYS_SHM_H +# include + +typedef struct block_shm_t +{ + block_t self; + void *base_addr; +} block_shm_t; + +static void block_shm_Release (block_t *block) +{ + block_shm_t *p_sys = (block_shm_t *)block; + + shmdt (p_sys->base_addr); + free (p_sys); +} -#ifdef WIN32 +/** + * Creates a block from a System V shared memory segment (shmget()). + * This is provided by LibVLC so that segments can safely be deallocated + * even after the allocating plugin has been unloaded from memory. + * + * @param addr base address of the segment (as returned by shmat()) + * @param length length (bytes) of the segment (as passed to shmget()) + * @return NULL if an error occurred (in that case, shmdt(addr) is invoked + * before returning NULL). + */ +block_t *block_shm_Alloc (void *addr, size_t length) +{ + block_shm_t *block = malloc (sizeof (*block)); + if (unlikely(block == NULL)) + { + shmdt (addr); + return NULL; + } + + block_Init (&block->self, (uint8_t *)addr, length); + block->self.pf_release = block_shm_Release; + block->base_addr = addr; + return &block->self; +} +#else +block_t *block_shm_Alloc (void *addr, size_t length) +{ + (void) addr; (void) length; + abort (); +} +#endif + + +#ifdef _WIN32 # include -# ifdef UNDER_CE -# define _get_osfhandle(a) ((long) (a)) -# endif static ssize_t pread (int fd, void *buf, size_t count, off_t offset) @@ -358,35 +406,16 @@ ssize_t pread (int fd, void *buf, size_t count, off_t offset) return written; return -1; } -#elif !defined( HAVE_PREAD ) -static -ssize_t pread(int fd, const void * buf, size_t size, off_t offset) { - off_t offs0; - ssize_t rd; - if ((offs0 = lseek(fd, 0, SEEK_CUR)) == (off_t)-1) return -1; - if (lseek(fd, offset, SEEK_SET) == (off_t)-1) return -1; - rd = read(fd, (void *)buf, size); - if (lseek(fd, offs0, SEEK_SET) == (off_t)-1) return -1; - return rd; -} - -static -ssize_t pwrite(int fd, const void * buf, size_t size, off_t offset) { - off_t offs0; - ssize_t wr; - if ((offs0 = lseek(fd, 0, SEEK_CUR)) == (off_t)-1) return -1; - if (lseek(fd, offset, SEEK_SET) == (off_t)-1) return -1; - wr = write(fd, (void *)buf, size); - if (lseek(fd, offs0, SEEK_SET) == (off_t)-1) return -1; - return wr; -} #endif /** - * Loads a file into a block of memory. If possible a private file mapping is - * created. Otherwise, the file is read normally. On 32-bits platforms, this - * function will not work for very large files, due to memory space - * constraints. Cancellation point. + * Loads a file into a block of memory through a file descriptor. + * If possible a private file mapping is created. Otherwise, the file is read + * normally. This function is a cancellation point. + * + * @note On 32-bits platforms, + * this function will not work for very large files, + * due to memory space constraints. * * @param fd file descriptor to load from * @return a new block with the file content at p_buffer, and file length at @@ -419,7 +448,7 @@ block_t *block_File (int fd) } /* Prevent an integer overflow in mmap() and malloc() */ - if (st.st_size >= SIZE_MAX) + if ((uintmax_t)st.st_size >= SIZE_MAX) { errno = ENOMEM; return NULL; @@ -458,6 +487,21 @@ block_t *block_File (int fd) return block; } +/** + * Loads a file into a block of memory from the file path. + * See also block_File(). + */ +block_t *block_FilePath (const char *path) +{ + int fd = vlc_open (path, O_RDONLY); + if (fd == -1) + return NULL; + + block_t *block = block_File (fd); + close (fd); + return block; +} + /** * @section Thread-safe block queue functions */ @@ -679,14 +723,24 @@ block_t *block_FifoShow( block_fifo_t *p_fifo ) return b; } -/* FIXME: not thread-safe */ -size_t block_FifoSize( const block_fifo_t *p_fifo ) +/* FIXME: not (really) thread-safe */ +size_t block_FifoSize (block_fifo_t *fifo) { - return p_fifo->i_size; + size_t size; + + vlc_mutex_lock (&fifo->lock); + size = fifo->i_size; + vlc_mutex_unlock (&fifo->lock); + return size; } -/* FIXME: not thread-safe */ -size_t block_FifoCount( const block_fifo_t *p_fifo ) +/* FIXME: not (really) thread-safe */ +size_t block_FifoCount (block_fifo_t *fifo) { - return p_fifo->i_depth; + size_t depth; + + vlc_mutex_lock (&fifo->lock); + depth = fifo->i_depth; + vlc_mutex_unlock (&fifo->lock); + return depth; }