Retry only for https protocol
[elinks.git] / src / util / memory.h
blob5b531f5e829e328128f60b776076eb17b488ea55
1 #ifndef EL__UTIL_MEMORY_H
2 #define EL__UTIL_MEMORY_H
4 /* If defined, we'll crash if ALLOC_MAXTRIES is attained,
5 * if not defined, we'll try to continue. */
6 /* #define CRASH_IF_ALLOC_MAXTRIES */
8 /** Max. number of retry in case of memory allocation failure. */
9 #define ALLOC_MAXTRIES 3
11 /** Delay in seconds between each alloc try. */
12 #define ALLOC_DELAY 3
14 #define fmem_alloc(x) mem_alloc(x)
15 #define fmem_free(x) mem_free(x)
18 /** Cygwin wants some size_t definition here... let's try to make it happy
19 * then. Hrmpf. */
20 #include <sys/types.h>
21 #include <stddef.h>
23 #ifdef HAVE_MMAP
24 void *mem_mmap_alloc(size_t size);
25 void mem_mmap_free(void *p, size_t size);
26 void *mem_mmap_realloc(void *p, size_t old_size, size_t new_size);
27 #else
28 #define mem_mmap_alloc(x) mem_alloc(x)
29 #define mem_mmap_free(x, y) mem_free(x)
30 #define mem_mmap_realloc(x, y, z) mem_realloc(x, z)
31 #endif
34 #ifdef DEBUG_MEMLEAK
36 #include "util/memdebug.h"
38 #define mem_alloc(x) debug_mem_alloc(__FILE__, __LINE__, x)
39 #define mem_calloc(x, y) debug_mem_calloc(__FILE__, __LINE__, x, y)
40 #define mem_free(x) debug_mem_free(__FILE__, __LINE__, x)
41 #define mem_realloc(x, y) debug_mem_realloc(__FILE__, __LINE__, x, y)
43 #else
45 #ifndef CONFIG_FASTMEM
47 void *mem_alloc(size_t);
48 void *mem_calloc(size_t, size_t);
49 void mem_free(void *);
50 void *mem_realloc(void *, size_t);
52 #else
54 # include <stdlib.h>
56 /* TODO: For enhanced portability, checks at configure time:
57 * malloc(0) -> NULL
58 * realloc(NULL, 0) -> NULL
59 * realloc(p, 0) <-> free(p)
60 * realloc(NULL, n) <-> malloc(n)
61 * Some old implementations may not respect these rules.
62 * For these we need some replacement functions.
63 * This should not be an issue on most modern systems.
65 # define mem_alloc(size) malloc(size)
66 # define mem_calloc(count, size) calloc(count, size)
67 # define mem_free(p) free(p)
68 # define mem_realloc(p, size) realloc(p, size)
70 /* fmem_* functions should be use for allocation and freeing of memory
71 * inside a function.
72 * See alloca(3) manpage. */
74 #undef fmem_alloc
75 #undef fmem_free
77 #ifdef HAVE_ALLOCA
79 #ifdef HAVE_ALLOCA_H
80 #include <alloca.h>
81 #endif
82 #define fmem_alloc(x) alloca(x)
83 #define fmem_free(x)
85 #else /* HAVE_ALLOCA */
87 #define fmem_alloc(x) mem_alloc(x)
88 #define fmem_free(x) mem_free(x)
90 #endif /* HAVE_ALLOCA */
92 #endif /* CONFIG_FASTMEM */
94 #endif /* DEBUG_MEMLEAK */
97 /** @name Granular memory allocation.
98 * The granularity used by the aligned memory functions below must be a mask
99 * with all bits set from but not including the most significant bit and down.
100 * So if an alignment of 256 is wanted use 0xFF.
101 * @{ */
103 /** The 'old' style granularity. XXX: Must be power of 2 */
104 #define ALLOC_GR 0x100
106 #include <string.h> /* for memset() */
108 #define ALIGN_MEMORY_SIZE(x, gr) (((x) + (gr)) & ~(gr))
110 static inline void *
111 mem_align_alloc__(
112 #ifdef DEBUG_MEMLEAK
113 const unsigned char *file, int line,
114 #endif
115 void **ptr, size_t old, size_t new_, size_t objsize, size_t mask)
117 size_t newsize = ALIGN_MEMORY_SIZE(new_, mask);
118 size_t oldsize = ALIGN_MEMORY_SIZE(old, mask);
120 if (newsize > oldsize) {
121 unsigned char *data;
123 newsize *= objsize;
124 oldsize *= objsize;
126 #ifdef DEBUG_MEMLEAK
127 data = debug_mem_realloc(file, line, *ptr, newsize);
128 #else
129 data = mem_realloc(*ptr, newsize);
130 #endif
131 if (!data) return NULL;
133 *ptr = (void *) data;
134 memset(&data[oldsize], 0, newsize - oldsize);
137 return *ptr;
140 #ifdef DEBUG_MEMLEAK
141 #define mem_align_alloc(ptr, old, new_, mask) \
142 mem_align_alloc__(__FILE__, __LINE__, (void **) ptr, old, new_, sizeof(**ptr), mask)
143 #else
144 #define mem_align_alloc(ptr, old, new_, mask) \
145 mem_align_alloc__((void **) ptr, old, new_, sizeof(**ptr), mask)
146 #endif
148 /** @} */
151 /** @name Maybe-free macros
152 * @todo TODO: Think about making what they do more obvious in their
153 * identifier, they could be obfuscating their users a little for the
154 * newcomers otherwise.
155 * @{ */
157 #define mem_free_set(x, v) do { if (*(x)) mem_free(*(x)); *(x) = (v); } while (0)
158 #define mem_free_if(x) do { register void *p = (x); if (p) mem_free(p); } while (0)
160 #if 0
161 /* This may help to find bugs. */
162 #undef mem_free_if
163 #define mem_free_if(x) mem_free_set(&x, NULL)
164 #endif
165 /** @} */
168 /* This is out of place, but there is no better place. */
170 #ifdef DEBUG_MEMLEAK
171 #define intdup(i) intdup__(__FILE__, __LINE__, i)
172 #else
173 #define intdup(i) intdup__(i)
174 #endif
176 static inline int *
177 intdup__(
178 #ifdef DEBUG_MEMLEAK
179 unsigned char *file, int line,
180 #endif
181 int i)
183 #ifdef DEBUG_MEMLEAK
184 int *p = debug_mem_alloc(file, line, sizeof(*p));
185 #else
186 int *p = mem_alloc(sizeof(*p));
187 #endif
189 if (p) *p = i;
191 return p;
194 #endif