Mercurial > hg > nginx-ranges
view src/core/ngx_palloc.c @ 196:8759b346e431 NGINX_0_3_45
nginx 0.3.45
*) Feature: the "ssl_verify_client", "ssl_verify_depth", and
"ssl_client_certificate" directives.
*) Change: the $request_method variable now returns the main request
method.
*) Change: the ° symbol codes were changed in koi-win conversion
table.
*) Feature: the euro и N symbols were added to koi-win conversion table.
*) Bugfix: if nginx distributed the requests among several backends and
some backend failed, then requests intended for this backend was
directed to one live backend only instead of being distributed among
the rest.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Sat, 06 May 2006 00:00:00 +0400 |
parents | 87699398f955 |
children | 6ae1357b7b7c |
line wrap: on
line source
/* * Copyright (C) Igor Sysoev */ #include <ngx_config.h> #include <ngx_core.h> ngx_pool_t * ngx_create_pool(size_t size, ngx_log_t *log) { ngx_pool_t *p; p = ngx_alloc(size, log); if (p == NULL) { return NULL; } p->last = (u_char *) p + sizeof(ngx_pool_t); p->end = (u_char *) p + size; p->current = p; p->chain = NULL; p->next = NULL; p->large = NULL; p->cleanup = NULL; p->log = log; return p; } void ngx_destroy_pool(ngx_pool_t *pool) { ngx_pool_t *p, *n; ngx_pool_large_t *l; ngx_pool_cleanup_t *c; for (c = pool->cleanup; c; c = c->next) { if (c->handler) { c->handler(c->data); } } for (l = pool->large; l; l = l->next) { ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc); if (l->alloc) { ngx_free(l->alloc); } } #if (NGX_DEBUG) /* * we could allocate the pool->log from this pool * so we can not use this log while the free()ing the pool */ for (p = pool, n = pool->next; /* void */; p = n, n = n->next) { ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p, unused: %uz", p, p->end - p->last); if (n == NULL) { break; } } #endif for (p = pool, n = pool->next; /* void */; p = n, n = n->next) { ngx_free(p); if (n == NULL) { break; } } } void * ngx_palloc(ngx_pool_t *pool, size_t size) { u_char *m; ngx_pool_t *p, *n; ngx_pool_large_t *large; if (size <= (size_t) NGX_MAX_ALLOC_FROM_POOL && size <= (size_t) (pool->end - (u_char *) pool) - (size_t) ngx_align_ptr(sizeof(ngx_pool_t), NGX_ALIGNMENT)) { for (p = pool->current; /* void */ ; p = p->next) { if (size < sizeof(int) || (size & 1)) { m = p->last; } else { m = ngx_align_ptr(p->last, NGX_ALIGNMENT); } if ((size_t) (p->end - m) >= size) { p->last = m + size; return m; } if ((size_t) (p->end - m) < NGX_ALIGNMENT) { pool->current = p->next; } if (p->next == NULL) { break; } } /* allocate a new pool block */ n = ngx_create_pool((size_t) (p->end - (u_char *) p), p->log); if (n == NULL) { return NULL; } if (pool->current == NULL) { pool->current = n; } p->next = n; m = ngx_align_ptr(n->last, NGX_ALIGNMENT); n->last = m + size; return m; } #if 0 p = ngx_memalign(ngx_pagesize, size, pool->log); if (p == NULL) { return NULL; } #else p = ngx_alloc(size, pool->log); if (p == NULL) { return NULL; } #endif large = ngx_palloc(pool, sizeof(ngx_pool_large_t)); if (large == NULL) { return NULL; } large->alloc = p; large->next = pool->large; pool->large = large; return p; } ngx_int_t ngx_pfree(ngx_pool_t *pool, void *p) { ngx_pool_large_t *l; for (l = pool->large; l; l = l->next) { if (p == l->alloc) { ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc); ngx_free(l->alloc); l->alloc = NULL; return NGX_OK; } } return NGX_DECLINED; } void * ngx_pcalloc(ngx_pool_t *pool, size_t size) { void *p; p = ngx_palloc(pool, size); if (p) { ngx_memzero(p, size); } return p; } void * ngx_shalloc(size_t size) { u_char *p; if (size < sizeof(int) || (size & 1)) { p = ngx_cycle->shm_last; } else { p = ngx_align_ptr(ngx_cycle->shm_last, NGX_ALIGNMENT); } if ((size_t) (ngx_cycle->shm_end - p) >= size) { ngx_cycle->shm_last = p + size; return p; } ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, 0, "allocation of %uz bytes in shared memory failed, " "only %uz are available", size, ngx_cycle->shm_end - ngx_cycle->shm_last); return NULL; } void * ngx_shcalloc(size_t size) { void *p; p = ngx_shalloc(size); if (p) { ngx_memzero(p, size); } return p; } ngx_pool_cleanup_t * ngx_pool_cleanup_add(ngx_pool_t *p, size_t size) { ngx_pool_cleanup_t *c; c = ngx_palloc(p, sizeof(ngx_pool_cleanup_t)); if (c == NULL) { return NULL; } if (size) { c->data = ngx_palloc(p, size); if (c->data == NULL) { return NULL; } } else { c->data = NULL; } c->handler = NULL; c->next = p->cleanup; p->cleanup = c; ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, p->log, 0, "add cleanup: %p", c); return c; } void ngx_pool_cleanup_file(void *data) { ngx_pool_cleanup_file_t *c = data; ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, c->log, 0, "run cleanup: %p, fd:%d", c, c->fd); if (ngx_close_file(c->fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, ngx_close_file_n " \"%s\" failed", c->name); } } #if 0 static void * ngx_get_cached_block(size_t size) { void *p; ngx_cached_block_slot_t *slot; if (ngx_cycle->cache == NULL) { return NULL; } slot = &ngx_cycle->cache[(size + ngx_pagesize - 1) / ngx_pagesize]; slot->tries++; if (slot->number) { p = slot->block; slot->block = slot->block->next; slot->number--; return p; } return NULL; } #endif