aboutsummaryrefslogtreecommitdiff
path: root/src/liblzma/api/lzma/memlimit.h
blob: 26ec50fe9b86e6d4a3567bbaa20606de952a3f7e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/**
 * \file        lzma/memlimit.h
 * \brief       Memory usage limitter
 *
 * \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 limitting 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 limitter functions are not tied to limitting 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);


/**
 * \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);


/**
 * \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);


/**
 * \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);


/**
 * \brief       Removes the pointer from memory limitting 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 limitter
 *
 * \param       mem             Pointer to memory limitter
 * \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);