blob: efbc24452bd08cd81cfad38839caa8670b1796f7 [file] [log] [blame]
Igor Sysoev6de5c2c2002-08-06 16:39:45 +00001
Igor Sysoevd90282d2004-09-28 08:34:51 +00002/*
Igor Sysoevff8da912004-09-29 16:00:49 +00003 * Copyright (C) Igor Sysoev
Maxim Konovalovf8d59e32012-01-18 15:07:43 +00004 * Copyright (C) Nginx, Inc.
Igor Sysoevd90282d2004-09-28 08:34:51 +00005 */
6
7
Igor Sysoev6de5c2c2002-08-06 16:39:45 +00008#include <ngx_config.h>
Igor Sysoev1c104622003-06-03 15:42:58 +00009#include <ngx_core.h>
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000010
11
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +000012static void *ngx_palloc_block(ngx_pool_t *pool, size_t size);
13static void *ngx_palloc_large(ngx_pool_t *pool, size_t size);
14
15
Igor Sysoevc1571722005-03-19 12:38:37 +000016ngx_pool_t *
17ngx_create_pool(size_t size, ngx_log_t *log)
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000018{
Igor Sysoevd9d0ca12003-11-21 06:30:49 +000019 ngx_pool_t *p;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000020
Igor Sysoev04799a62009-12-17 12:25:46 +000021 p = ngx_memalign(NGX_POOL_ALIGNMENT, size, log);
Igor Sysoevc1571722005-03-19 12:38:37 +000022 if (p == NULL) {
Igor Sysoev5192b362005-07-08 14:34:20 +000023 return NULL;
Igor Sysoevd9d0ca12003-11-21 06:30:49 +000024 }
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000025
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +000026 p->d.last = (u_char *) p + sizeof(ngx_pool_t);
27 p->d.end = (u_char *) p + size;
28 p->d.next = NULL;
Igor Sysoev7f9305c2009-06-05 13:27:12 +000029 p->d.failed = 0;
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +000030
Igor Sysoev3cc03612008-06-21 06:40:32 +000031 size = size - sizeof(ngx_pool_t);
32 p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;
33
Igor Sysoevc31a9bb2005-11-26 10:11:11 +000034 p->current = p;
35 p->chain = NULL;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000036 p->large = NULL;
Igor Sysoev899b44e2005-05-12 14:58:06 +000037 p->cleanup = NULL;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000038 p->log = log;
39
40 return p;
41}
42
Igor Sysoevf1079102003-10-23 06:13:16 +000043
Igor Sysoevc1571722005-03-19 12:38:37 +000044void
45ngx_destroy_pool(ngx_pool_t *pool)
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000046{
Igor Sysoev899b44e2005-05-12 14:58:06 +000047 ngx_pool_t *p, *n;
48 ngx_pool_large_t *l;
49 ngx_pool_cleanup_t *c;
50
51 for (c = pool->cleanup; c; c = c->next) {
52 if (c->handler) {
Igor Sysoev249cbe72007-12-17 17:29:36 +000053 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
54 "run cleanup: %p", c);
Igor Sysoev899b44e2005-05-12 14:58:06 +000055 c->handler(c->data);
56 }
57 }
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000058
Igor Sysoeve0268b92002-09-11 15:18:33 +000059 for (l = pool->large; l; l = l->next) {
Igor Sysoev54498db2004-02-11 17:08:49 +000060
Igor Sysoev1b735832004-11-11 14:07:14 +000061 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc);
Igor Sysoev54498db2004-02-11 17:08:49 +000062
Igor Sysoevf1079102003-10-23 06:13:16 +000063 if (l->alloc) {
Igor Sysoevb1dfe472004-12-21 12:30:30 +000064 ngx_free(l->alloc);
Igor Sysoevf1079102003-10-23 06:13:16 +000065 }
Igor Sysoeve0268b92002-09-11 15:18:33 +000066 }
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000067
Igor Sysoev54498db2004-02-11 17:08:49 +000068#if (NGX_DEBUG)
69
Igor Sysoeve77c0c32003-08-08 15:13:24 +000070 /*
Igor Sysoev54498db2004-02-11 17:08:49 +000071 * we could allocate the pool->log from this pool
Ruslan Ermilova823c552011-09-19 14:48:29 +000072 * so we cannot use this log while free()ing the pool
Igor Sysoeve77c0c32003-08-08 15:13:24 +000073 */
Igor Sysoev31ef3512003-08-06 14:43:50 +000074
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +000075 for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
Igor Sysoevf7abd722004-09-23 06:32:00 +000076 ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +000077 "free: %p, unused: %uz", p, p->d.end - p->d.last);
Igor Sysoev14827c72003-09-24 19:51:12 +000078
79 if (n == NULL) {
80 break;
81 }
Igor Sysoeve77c0c32003-08-08 15:13:24 +000082 }
Igor Sysoev54498db2004-02-11 17:08:49 +000083
Igor Sysoev3a17f242002-12-24 17:30:59 +000084#endif
Igor Sysoeve77c0c32003-08-08 15:13:24 +000085
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +000086 for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
Igor Sysoevb1dfe472004-12-21 12:30:30 +000087 ngx_free(p);
Igor Sysoeve77c0c32003-08-08 15:13:24 +000088
89 if (n == NULL) {
90 break;
91 }
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000092 }
93}
94
Igor Sysoevf1079102003-10-23 06:13:16 +000095
Igor Sysoev65eba4b2008-11-25 14:25:20 +000096void
97ngx_reset_pool(ngx_pool_t *pool)
98{
99 ngx_pool_t *p;
100 ngx_pool_large_t *l;
101
102 for (l = pool->large; l; l = l->next) {
103 if (l->alloc) {
104 ngx_free(l->alloc);
105 }
106 }
107
108 pool->large = NULL;
109
110 for (p = pool; p; p = p->d.next) {
111 p->d.last = (u_char *) p + sizeof(ngx_pool_t);
112 }
113}
114
115
Igor Sysoevc1571722005-03-19 12:38:37 +0000116void *
117ngx_palloc(ngx_pool_t *pool, size_t size)
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000118{
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +0000119 u_char *m;
120 ngx_pool_t *p;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000121
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +0000122 if (size <= pool->max) {
123
Igor Sysoev84bab052006-12-18 20:46:49 +0000124 p = pool->current;
Igor Sysoev84bab052006-12-18 20:46:49 +0000125
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +0000126 do {
127 m = ngx_align_ptr(p->d.last, NGX_ALIGNMENT);
Igor Sysoev24025022005-12-16 15:07:08 +0000128
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +0000129 if ((size_t) (p->d.end - m) >= size) {
130 p->d.last = m + size;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000131
132 return m;
133 }
134
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +0000135 p = p->d.next;
Igor Sysoevc31a9bb2005-11-26 10:11:11 +0000136
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +0000137 } while (p);
Igor Sysoev84bab052006-12-18 20:46:49 +0000138
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +0000139 return ngx_palloc_block(pool, size);
Igor Sysoevf1079102003-10-23 06:13:16 +0000140 }
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000141
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +0000142 return ngx_palloc_large(pool, size);
143}
144
145
146void *
147ngx_pnalloc(ngx_pool_t *pool, size_t size)
148{
149 u_char *m;
150 ngx_pool_t *p;
151
152 if (size <= pool->max) {
153
154 p = pool->current;
155
156 do {
157 m = p->d.last;
158
159 if ((size_t) (p->d.end - m) >= size) {
160 p->d.last = m + size;
161
162 return m;
163 }
164
165 p = p->d.next;
166
167 } while (p);
168
169 return ngx_palloc_block(pool, size);
170 }
171
172 return ngx_palloc_large(pool, size);
173}
174
175
176static void *
177ngx_palloc_block(ngx_pool_t *pool, size_t size)
178{
179 u_char *m;
Igor Sysoev5a4c6162008-06-20 20:57:40 +0000180 size_t psize;
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +0000181 ngx_pool_t *p, *new, *current;
182
Igor Sysoev5a4c6162008-06-20 20:57:40 +0000183 psize = (size_t) (pool->d.end - (u_char *) pool);
184
Igor Sysoev04799a62009-12-17 12:25:46 +0000185 m = ngx_memalign(NGX_POOL_ALIGNMENT, psize, pool->log);
Igor Sysoev11864a72008-06-20 21:06:53 +0000186 if (m == NULL) {
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +0000187 return NULL;
188 }
189
Igor Sysoev11864a72008-06-20 21:06:53 +0000190 new = (ngx_pool_t *) m;
191
192 new->d.end = m + psize;
Igor Sysoev5a4c6162008-06-20 20:57:40 +0000193 new->d.next = NULL;
Igor Sysoev7f9305c2009-06-05 13:27:12 +0000194 new->d.failed = 0;
Igor Sysoev5a4c6162008-06-20 20:57:40 +0000195
Igor Sysoev11864a72008-06-20 21:06:53 +0000196 m += sizeof(ngx_pool_data_t);
Igor Sysoev8329a5b2008-11-06 16:14:24 +0000197 m = ngx_align_ptr(m, NGX_ALIGNMENT);
Igor Sysoev11864a72008-06-20 21:06:53 +0000198 new->d.last = m + size;
199
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +0000200 current = pool->current;
201
202 for (p = current; p->d.next; p = p->d.next) {
Igor Sysoev7f9305c2009-06-05 13:27:12 +0000203 if (p->d.failed++ > 4) {
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +0000204 current = p->d.next;
205 }
206 }
207
208 p->d.next = new;
209
210 pool->current = current ? current : new;
211
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +0000212 return m;
213}
214
215
216static void *
217ngx_palloc_large(ngx_pool_t *pool, size_t size)
218{
219 void *p;
Igor Sysoev5a2898f2009-06-03 13:57:28 +0000220 ngx_uint_t n;
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +0000221 ngx_pool_large_t *large;
222
Igor Sysoevece77cd2009-11-16 12:47:44 +0000223 p = ngx_alloc(size, pool->log);
Igor Sysoevc1571722005-03-19 12:38:37 +0000224 if (p == NULL) {
Igor Sysoev3eb19952004-06-08 16:26:37 +0000225 return NULL;
226 }
Igor Sysoev385af282008-07-30 12:34:04 +0000227
Igor Sysoev5a2898f2009-06-03 13:57:28 +0000228 n = 0;
229
230 for (large = pool->large; large; large = large->next) {
231 if (large->alloc == NULL) {
232 large->alloc = p;
233 return p;
234 }
235
236 if (n++ > 3) {
237 break;
238 }
239 }
240
Igor Sysoev385af282008-07-30 12:34:04 +0000241 large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
242 if (large == NULL) {
243 ngx_free(p);
244 return NULL;
245 }
246
247 large->alloc = p;
248 large->next = pool->large;
249 pool->large = large;
250
251 return p;
252}
253
254
255void *
256ngx_pmemalign(ngx_pool_t *pool, size_t size, size_t alignment)
257{
258 void *p;
259 ngx_pool_large_t *large;
260
261 p = ngx_memalign(alignment, size, pool->log);
262 if (p == NULL) {
263 return NULL;
264 }
Igor Sysoevf1079102003-10-23 06:13:16 +0000265
Igor Sysoev6d16e1e2006-04-05 13:40:54 +0000266 large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
267 if (large == NULL) {
Igor Sysoevcbf72c12007-07-19 19:07:13 +0000268 ngx_free(p);
Igor Sysoev6d16e1e2006-04-05 13:40:54 +0000269 return NULL;
Igor Sysoevf1079102003-10-23 06:13:16 +0000270 }
271
272 large->alloc = p;
Igor Sysoev6d16e1e2006-04-05 13:40:54 +0000273 large->next = pool->large;
274 pool->large = large;
Igor Sysoevf1079102003-10-23 06:13:16 +0000275
276 return p;
277}
278
279
Igor Sysoevc1571722005-03-19 12:38:37 +0000280ngx_int_t
281ngx_pfree(ngx_pool_t *pool, void *p)
Igor Sysoevf1079102003-10-23 06:13:16 +0000282{
283 ngx_pool_large_t *l;
284
285 for (l = pool->large; l; l = l->next) {
286 if (p == l->alloc) {
Igor Sysoev54498db2004-02-11 17:08:49 +0000287 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
Igor Sysoev1b735832004-11-11 14:07:14 +0000288 "free: %p", l->alloc);
Igor Sysoevb1dfe472004-12-21 12:30:30 +0000289 ngx_free(l->alloc);
Igor Sysoevf1079102003-10-23 06:13:16 +0000290 l->alloc = NULL;
Igor Sysoevf7abd722004-09-23 06:32:00 +0000291
292 return NGX_OK;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000293 }
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000294 }
Igor Sysoevf7abd722004-09-23 06:32:00 +0000295
296 return NGX_DECLINED;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000297}
298
Igor Sysoevf1079102003-10-23 06:13:16 +0000299
Igor Sysoevc1571722005-03-19 12:38:37 +0000300void *
301ngx_pcalloc(ngx_pool_t *pool, size_t size)
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000302{
303 void *p;
304
305 p = ngx_palloc(pool, size);
Igor Sysoev3a17f242002-12-24 17:30:59 +0000306 if (p) {
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000307 ngx_memzero(p, size);
Igor Sysoev3a17f242002-12-24 17:30:59 +0000308 }
Igor Sysoev6de5c2c2002-08-06 16:39:45 +0000309
310 return p;
311}
Igor Sysoev0ab91b92004-06-06 19:49:18 +0000312
Igor Sysoev899b44e2005-05-12 14:58:06 +0000313
314ngx_pool_cleanup_t *
Igor Sysoevc2068d02005-10-19 12:33:58 +0000315ngx_pool_cleanup_add(ngx_pool_t *p, size_t size)
Igor Sysoev899b44e2005-05-12 14:58:06 +0000316{
317 ngx_pool_cleanup_t *c;
318
319 c = ngx_palloc(p, sizeof(ngx_pool_cleanup_t));
320 if (c == NULL) {
321 return NULL;
322 }
323
Igor Sysoevc2068d02005-10-19 12:33:58 +0000324 if (size) {
325 c->data = ngx_palloc(p, size);
326 if (c->data == NULL) {
327 return NULL;
328 }
329
330 } else {
331 c->data = NULL;
332 }
333
334 c->handler = NULL;
Igor Sysoev899b44e2005-05-12 14:58:06 +0000335 c->next = p->cleanup;
336
337 p->cleanup = c;
338
Igor Sysoevc2068d02005-10-19 12:33:58 +0000339 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, p->log, 0, "add cleanup: %p", c);
340
Igor Sysoev899b44e2005-05-12 14:58:06 +0000341 return c;
342}
343
344
345void
Igor Sysoev52859f22009-03-23 13:14:51 +0000346ngx_pool_run_cleanup_file(ngx_pool_t *p, ngx_fd_t fd)
347{
348 ngx_pool_cleanup_t *c;
349 ngx_pool_cleanup_file_t *cf;
350
351 for (c = p->cleanup; c; c = c->next) {
352 if (c->handler == ngx_pool_cleanup_file) {
353
354 cf = c->data;
355
356 if (cf->fd == fd) {
357 c->handler(cf);
358 c->handler = NULL;
359 return;
360 }
361 }
362 }
363}
364
365
366void
Igor Sysoev899b44e2005-05-12 14:58:06 +0000367ngx_pool_cleanup_file(void *data)
368{
369 ngx_pool_cleanup_file_t *c = data;
370
Igor Sysoev249cbe72007-12-17 17:29:36 +0000371 ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, c->log, 0, "file cleanup: fd:%d",
372 c->fd);
Igor Sysoevc2068d02005-10-19 12:33:58 +0000373
Igor Sysoev899b44e2005-05-12 14:58:06 +0000374 if (ngx_close_file(c->fd) == NGX_FILE_ERROR) {
375 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
376 ngx_close_file_n " \"%s\" failed", c->name);
377 }
378}
379
380
Igor Sysoevcd5b99a2007-01-25 08:45:04 +0000381void
382ngx_pool_delete_file(void *data)
383{
384 ngx_pool_cleanup_file_t *c = data;
385
386 ngx_err_t err;
387
Igor Sysoev249cbe72007-12-17 17:29:36 +0000388 ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, c->log, 0, "file cleanup: fd:%d %s",
389 c->fd, c->name);
Igor Sysoevcd5b99a2007-01-25 08:45:04 +0000390
391 if (ngx_delete_file(c->name) == NGX_FILE_ERROR) {
392 err = ngx_errno;
393
394 if (err != NGX_ENOENT) {
395 ngx_log_error(NGX_LOG_CRIT, c->log, err,
396 ngx_delete_file_n " \"%s\" failed", c->name);
397 }
398 }
399
400 if (ngx_close_file(c->fd) == NGX_FILE_ERROR) {
401 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
402 ngx_close_file_n " \"%s\" failed", c->name);
403 }
404}
405
406
Igor Sysoev0ab91b92004-06-06 19:49:18 +0000407#if 0
408
Igor Sysoevc1571722005-03-19 12:38:37 +0000409static void *
410ngx_get_cached_block(size_t size)
Igor Sysoev0ab91b92004-06-06 19:49:18 +0000411{
412 void *p;
413 ngx_cached_block_slot_t *slot;
414
415 if (ngx_cycle->cache == NULL) {
416 return NULL;
417 }
418
419 slot = &ngx_cycle->cache[(size + ngx_pagesize - 1) / ngx_pagesize];
420
421 slot->tries++;
422
423 if (slot->number) {
424 p = slot->block;
425 slot->block = slot->block->next;
426 slot->number--;
427 return p;
428 }
429
430 return NULL;
431}
432
433#endif