Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib/data-stack.h @ 9191:b340ecb24469 HEAD
Fix VPATH build of RQUOTA support.
Some rpcgen derive #include "..." paths from the infile argument.
This will be off for VPATH builds, as the generated rquota_xdr.c
code will look in $(srcdir), but we'll generate the rquota.h file in
$(builddir). Play safe and copy rquota.x to $(builddir) first.
This fixes the build on openSUSE 11.1.
author | Matthias Andree <matthias.andree@gmx.de> |
---|---|
date | Tue, 07 Jul 2009 21:01:36 +0200 |
parents | 81806d402514 |
children |
rev | line source |
---|---|
6410
e4eb71ae8e96
Changed .h ifdef/defines to use <NAME>_H format.
Timo Sirainen <tss@iki.fi>
parents:
5362
diff
changeset
|
1 #ifndef DATA_STACK_H |
e4eb71ae8e96
Changed .h ifdef/defines to use <NAME>_H format.
Timo Sirainen <tss@iki.fi>
parents:
5362
diff
changeset
|
2 #define DATA_STACK_H |
399
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
3 |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
4 /* Data stack makes it very easy to implement functions returning dynamic data |
6932 | 5 without having to worry much about memory management like freeing the |
6 result or having large enough buffers for the result. | |
399
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
7 |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
8 t_ prefix was chosen to describe functions allocating memory from data |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
9 stack. "t" meaning temporary. |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
10 |
6932 | 11 Advantages over control stack and alloca(): |
399
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
12 - Functions can return a value allocated from data stack |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
13 - We can portably specify how much data we want to allocate at runtime |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
14 |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
15 Advantages over malloc(): |
401 | 16 - FAST, most of the time allocating memory means only updating a couple of |
399
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
17 pointers and integers. Freeing the memory all at once also is a fast |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
18 operation. |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
19 - No need to free() each allocation resulting in prettier code |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
20 - No memory leaks |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
21 - No memory fragmentation |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
22 |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
23 Disadvantages: |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
24 - Allocating memory inside loops can accidentally allocate a lot of memory |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
25 if the loops are long and you forgot to place t_push() and t_pop() there. |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
26 - t_malloc()ed data could be accidentally stored into permanent location |
6932 | 27 and accessed after it's already been freed. const'ing the return values |
399
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
28 helps for most uses though (see the t_malloc() description). |
7027
ae06eb5e2638
Removed DISABLE_DATA_STACK. Using it was probably broken anyway and it was
Timo Sirainen <tss@iki.fi>
parents:
6939
diff
changeset
|
29 - Debugging invalid memory usage may be difficult using existing tools, |
ae06eb5e2638
Removed DISABLE_DATA_STACK. Using it was probably broken anyway and it was
Timo Sirainen <tss@iki.fi>
parents:
6939
diff
changeset
|
30 although compiling with DEBUG enabled helps finding simple buffer |
ae06eb5e2638
Removed DISABLE_DATA_STACK. Using it was probably broken anyway and it was
Timo Sirainen <tss@iki.fi>
parents:
6939
diff
changeset
|
31 overflows. |
399
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
32 */ |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
33 |
536
37893ed97492
changed t_push() and t_pop() to return unsigned int. added global
Timo Sirainen <tss@iki.fi>
parents:
402
diff
changeset
|
34 extern unsigned int data_stack_frame; |
37893ed97492
changed t_push() and t_pop() to return unsigned int. added global
Timo Sirainen <tss@iki.fi>
parents:
402
diff
changeset
|
35 |
6932 | 36 /* All t_..() allocations between t_push() and t_pop() are freed after t_pop() |
37 is called. Returns the current stack frame number, which can be used | |
399
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
38 to detect missing t_pop() calls: |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
39 |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
40 x = t_push(); .. if (t_pop() != x) abort(); |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
41 */ |
536
37893ed97492
changed t_push() and t_pop() to return unsigned int. added global
Timo Sirainen <tss@iki.fi>
parents:
402
diff
changeset
|
42 unsigned int t_push(void); |
37893ed97492
changed t_push() and t_pop() to return unsigned int. added global
Timo Sirainen <tss@iki.fi>
parents:
402
diff
changeset
|
43 unsigned int t_pop(void); |
6939
c7b42fea5fcc
Added T_FRAME*() macros. It's too easy to accidentally break t_push/t_pop
Timo Sirainen <tss@iki.fi>
parents:
6932
diff
changeset
|
44 /* Simplifies the if (t_pop() != x) check by comparing it internally and |
c7b42fea5fcc
Added T_FRAME*() macros. It's too easy to accidentally break t_push/t_pop
Timo Sirainen <tss@iki.fi>
parents:
6932
diff
changeset
|
45 panicking if it doesn't match. */ |
c7b42fea5fcc
Added T_FRAME*() macros. It's too easy to accidentally break t_push/t_pop
Timo Sirainen <tss@iki.fi>
parents:
6932
diff
changeset
|
46 void t_pop_check(unsigned int *id); |
c7b42fea5fcc
Added T_FRAME*() macros. It's too easy to accidentally break t_push/t_pop
Timo Sirainen <tss@iki.fi>
parents:
6932
diff
changeset
|
47 |
7226
e6693a0ec8e1
Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents:
7027
diff
changeset
|
48 /* Usage: T_BEGIN { code } T_END */ |
e6693a0ec8e1
Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents:
7027
diff
changeset
|
49 #define T_BEGIN \ |
6939
c7b42fea5fcc
Added T_FRAME*() macros. It's too easy to accidentally break t_push/t_pop
Timo Sirainen <tss@iki.fi>
parents:
6932
diff
changeset
|
50 STMT_START { unsigned int _data_stack_cur_id = t_push(); |
7226
e6693a0ec8e1
Renamed T_FRAME_BEGIN/END to T_BEGIN/END. Removed T_FRAME() macro and
Timo Sirainen <tss@iki.fi>
parents:
7027
diff
changeset
|
51 #define T_END \ |
6939
c7b42fea5fcc
Added T_FRAME*() macros. It's too easy to accidentally break t_push/t_pop
Timo Sirainen <tss@iki.fi>
parents:
6932
diff
changeset
|
52 t_pop_check(&_data_stack_cur_id); } STMT_END |
c7b42fea5fcc
Added T_FRAME*() macros. It's too easy to accidentally break t_push/t_pop
Timo Sirainen <tss@iki.fi>
parents:
6932
diff
changeset
|
53 |
6932 | 54 /* WARNING: Be careful when using these functions, it's too easy to |
399
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
55 accidentally save the returned value somewhere permanently. |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
56 |
6932 | 57 You probably should never use these functions directly, rather |
399
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
58 create functions that return 'const xxx*' types and use t_malloc() |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
59 internally in them. This is a lot safer, since usually compiler |
402 | 60 warns if you try to place them in xxx*. See strfuncs.c for examples. |
61 | |
6932 | 62 t_malloc() calls never fail. If there's not enough memory left, |
63 i_panic() will be called. */ | |
6411
6a64e64fa3a3
Renamed __attr_*__ to ATTR_*. Renamed __attrs_used__ to ATTRS_DEFINED.
Timo Sirainen <tss@iki.fi>
parents:
6410
diff
changeset
|
64 void *t_malloc(size_t size) ATTR_MALLOC; |
6a64e64fa3a3
Renamed __attr_*__ to ATTR_*. Renamed __attrs_used__ to ATTRS_DEFINED.
Timo Sirainen <tss@iki.fi>
parents:
6410
diff
changeset
|
65 void *t_malloc0(size_t size) ATTR_MALLOC; |
399
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
66 |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
67 /* Try growing allocated memory. Returns TRUE if successful. Works only |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
68 for last allocated memory in current stack frame. */ |
3863
55df57c028d4
Added "bool" type and changed all ints that were used as booleans to bool.
Timo Sirainen <tss@iki.fi>
parents:
3232
diff
changeset
|
69 bool t_try_realloc(void *mem, size_t size); |
399
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
70 |
3232 | 71 /* Returns the number of bytes available in data stack without allocating |
72 more memory. */ | |
7912
81806d402514
Added more consts, ATTR_CONSTs and ATTR_PUREs.
Timo Sirainen <tss@iki.fi>
parents:
7326
diff
changeset
|
73 size_t t_get_bytes_available(void) ATTR_PURE; |
3232 | 74 |
399
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
75 #define t_new(type, count) \ |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
76 ((type *) t_malloc0(sizeof(type) * (count))) |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
77 |
6932 | 78 /* Returns pointer to a temporary buffer you can use. The buffer will be |
399
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
79 invalid as soon as next t_malloc() is called! |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
80 |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
81 If you wish to grow the buffer, you must give the full wanted size |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
82 in the size parameter. If return value doesn't point to the same value |
6932 | 83 as last time, you need to memcpy() data from the old buffer to the |
399
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
84 new one (or do some other trickery). See t_buffer_reget(). */ |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
85 #define t_buffer_get_type(type, size) \ |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
86 t_buffer_get(sizeof(type) * (size)) |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
87 void *t_buffer_get(size_t size); |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
88 |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
89 /* Grow the buffer, memcpy()ing the memory to new location if needed. */ |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
90 #define t_buffer_reget_type(buffer, type, size) \ |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
91 t_buffer_reget(buffer, sizeof(type) * (size)) |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
92 void *t_buffer_reget(void *buffer, size_t size); |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
93 |
6932 | 94 /* Make the last t_buffer_get()ed buffer permanent. Note that size MUST be |
399
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
95 less or equal than the size you gave with last t_buffer_get() or the |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
96 result will be undefined. */ |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
97 #define t_buffer_alloc_type(type, size) \ |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
98 t_buffer_alloc(sizeof(type) * (size)) |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
99 void t_buffer_alloc(size_t size); |
7326
5017c74367e3
Added t_buffer_alloc_last_full().
Timo Sirainen <tss@iki.fi>
parents:
7226
diff
changeset
|
100 /* Allocate the last t_buffer_get()ed data entirely. */ |
5017c74367e3
Added t_buffer_alloc_last_full().
Timo Sirainen <tss@iki.fi>
parents:
7226
diff
changeset
|
101 void t_buffer_alloc_last_full(void); |
399
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
102 |
5362
9e86dbe68663
Added data_stack_set_clean_after_pop()
Timo Sirainen <tss@iki.fi>
parents:
4720
diff
changeset
|
103 /* If enabled, all the used memory is cleared after t_pop(). */ |
9e86dbe68663
Added data_stack_set_clean_after_pop()
Timo Sirainen <tss@iki.fi>
parents:
4720
diff
changeset
|
104 void data_stack_set_clean_after_pop(bool enable); |
9e86dbe68663
Added data_stack_set_clean_after_pop()
Timo Sirainen <tss@iki.fi>
parents:
4720
diff
changeset
|
105 |
399
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
106 void data_stack_init(void); |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
107 void data_stack_deinit(void); |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
108 |
383503837741
s/temporary memory pool/data stack/ which is the correct name for it.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
109 #endif |