aboutsummaryrefslogblamecommitdiff
path: root/src/liblzma/api/lzma/memlimit.h
blob: 836b0854513c34c59d66ec7916ca951835a9fe16 (plain) (tree)
1
2
3

                               
                                    




















                                                                     
                                                                              















                                                                          
                                                                     

















                                                                               

                                                        



















                                                                         

                                                         








                                                                        

                                                          


   


































                                                                             
                                                                          




                                                                     

                                                           


   


















                                                                            

                                                              


   
                                                             


























                                                                             
                                                                              
  
                                                         







                                                                             
/**
 * \file        lzma/memlimit.h
 * \brief       Memory usage limiter
 *
 * \author      Copyright (C) 1999-2006 Igor Pavlov
 * \author      Copyright (C) 2007 Lasse Collin
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 */

#ifndef LZMA_H_INTERNAL
#	error Never include this file directly. Use <lzma.h> instead.
#endif


/**
 * \brief       Opaque data type used with the memory usage limiting functions
 */
typedef struct lzma_memlimit_s lzma_memlimit;


/**
 * \brief       Allocates and initializes a new lzma_memlimit structure
 *
 * It is easy to make liblzma to use huge amounts of memory. This can
 * be a problem especially with the decoder, since it a file requiring
 * huge amounts of memory to uncompress could allow even a denial of
 * service attack if the memory usage wasn't limited.
 *
 * liblzma provides a set of functions to control memory usage. Pointers
 * to these functions can be used in lzma_allocator structure, which makes
 * it easy to limit memory usage with liblzma.
 *
 * The memory limiter functions are not tied to limiting memory usage
 * with liblzma itself. You can use them with anything you like.
 *
 * In multi-threaded applications, only one thread at once may use the same
 * lzma_memlimit structure. If there is a need, this limitation may
 * be removed in future versions without breaking the libary API/ABI.
 *
 * \param       limit   Initial memory usage limit in bytes
 *
 * \return      Pointer to allocated and initialized lzma_memlimit
 *              structure. On error, NULL is returned. The reason behind
 *              an error is either that malloc() failed or that the given
 *              limit was so small that it didn't allow allocating even
 *              the lzma_memlimit structure itself.
 *
 * \note        Excluding lzma_memlimit_usage(), the functions whose name begin
 *              lzma_memlimit_ can be used even if lzma_init() hasn't been
 *              called.
 */
extern lzma_memlimit *lzma_memlimit_create(size_t limit)
		lzma_attr_warn_unused_result;


/**
 * \brief       Sets a new memory usage limit
 *
 * \param       mem     Pointer to a lzma_memlimit structure returned
 *                      earlier by lzma_memry_limit_create().
 * \param       limit   New memory usage limit
 *
 * The new usage limit may be smaller than the amount of memory currently
 * allocated via *mem: New allocations will fail until enough memory has
 * been freed or a new limit is set, but the existing allocatations will
 * stay untouched.
 */
extern void lzma_memlimit_set(lzma_memlimit *mem, size_t limit);


/**
 * \brief       Gets the current memory usage limit
 */
extern size_t lzma_memlimit_get(const lzma_memlimit *mem)
		lzma_attr_pure;


/**
 * \brief       Gets the amount of currently allocated memory
 *
 * \note        This value includes the sizes of some helper structures,
 *              thus it will always be larger than the total number of
 *              bytes allocated via lzma_memlimit_alloc().
 */
extern size_t lzma_memlimit_used(const lzma_memlimit *mem)
		lzma_attr_pure;


/**
 * \brief       Gets the maximum amount of memory required in total
 *
 * Returns how much memory was or would have been allocated at the same time.
 * If lzma_memlimit_alloc() was requested so much memory that the limit
 * would have been exceeded or malloc() simply ran out of memory, the
 * requested amount is still included to the value returned by
 * lzma_memlimit_max(). This may be used as a hint how much bigger memory
 * limit would have been needed.
 *
 * If the clear flag is set, the internal variable holding the maximum
 * value is set to the current memory usage (the same value as returned
 * by lzma_memlimit_used()).
 *
 * \note        Usually liblzma needs to allocate many chunks of memory, and
 *              displaying a message like "memory usage limit reached, at
 *              least 1024 bytes would have been needed" may be confusing,
 *              because the next allocation could have been e.g. 8 MiB.
 *
 * \todo        The description of this function is unclear.
 */
extern size_t lzma_memlimit_max(lzma_memlimit *mem, lzma_bool clear);


/**
 * \brief       Checks if memory limit was reached at some point
 *
 * This function is useful to find out if the reason for LZMA_MEM_ERROR
 * was running out of memory or hitting the memory usage limit imposed
 * by lzma_memlimit_alloc(). If the clear argument is true, the internal
 * flag, that indicates that limit was reached, is cleared.
 */
extern lzma_bool lzma_memlimit_reached(lzma_memlimit *mem, lzma_bool clear);


/**
 * \brief       Gets the number of allocations owned by the memory limiter
 *
 * The count does not include the helper structures; if no memory has
 * been allocated with lzma_memlimit_alloc() or all memory allocated
 * has been freed or detached, this will return zero.
 */
extern size_t lzma_memlimit_count(const lzma_memlimit *mem)
		lzma_attr_pure;


/**
 * \brief       Allocates memory with malloc() if memory limit allows
 *
 * \param       mem     Pointer to a lzma_memlimit structure returned
 *                      earlier by lzma_memry_limit_create().
 * \param       nmemb   Number of elements to allocate. While liblzma always
 *                      sets this to one, this function still takes the
 *                      value of nmemb into account to keep the function
 *                      usable with zlib and libbzip2.
 * \param       size    Size of an element.
 *
 * \return      Pointer to memory allocated with malloc(nmemb * size),
 *              except if nmemb * size == 0 which returns malloc(1).
 *              On error, NULL is returned.
 *
 * \note        This function assumes that nmemb * size is at maximum of
 *              SIZE_MAX. If it isn't, an overflow will occur resulting
 *              invalid amount of memory being allocated.
 */
extern void *lzma_memlimit_alloc(
		lzma_memlimit *mem, size_t nmemb, size_t size)
		lzma_attr_warn_unused_result;


/**
 * \brief       Removes the pointer from memory limiting list
 *
 * \param       mem     Pointer to a lzma_memlimit structure returned
 *                      earlier by lzma_memry_limit_create().
 * \param       ptr     Pointer returned earlier by lzma_memlimit_alloc().
 *
 * This function removes ptr from the internal list and decreases the
 * counter of used memory accordingly. The ptr itself isn't freed. This is
 * useful when Extra Records allocated by liblzma using lzma_memlimit
 * are needed by the application and must not be freed when the
 * lzma_memlimit structure is destroyed.
 *
 * It is OK to call this function with ptr that hasn't been allocated with
 * lzma_memlimit_alloc(). In that case, this has no effect other than wasting
 * a few CPU cycles.
 */
extern void lzma_memlimit_detach(lzma_memlimit *mem, void *ptr);


/**
 * \brief       Frees memory and updates the memory limit list
 *
 * This is like lzma_memlimit_detach() but also frees the given pointer.
 */
extern void lzma_memlimit_free(lzma_memlimit *mem, void *ptr);


/**
 * \brief       Frees the memory allocated for and by the memory usage limiter
 *
 * \param       mem             Pointer to memory limiter
 * \param       free_allocated  If this is non-zero, all the memory allocated
 *                              by lzma_memlimit_alloc() using *mem is also
 *                              freed if it hasn't already been freed with
 *                              lzma_memlimit_free(). Usually this should be
 *                              set to true.
 */
extern void lzma_memlimit_end(
		lzma_memlimit *mem, lzma_bool free_allocated);