Back to home page

Nginx displayed by LXR

Source navigation ]
Diff markup ]
Identifier search ]
general search ]
 
 
Version: nginx-1.15.12 ]​[ nginx-1.16.0 ]​

0001 
0002 /*
0003  * Copyright (C) Igor Sysoev
0004  * Copyright (C) Nginx, Inc.
0005  */
0006 
0007 
0008 #include <ngx_config.h>
0009 #include <ngx_core.h>
0010 
0011 
0012 static ngx_inline void *ngx_palloc_small(ngx_pool_t *pool, size_t size,
0013     ngx_uint_t align);
0014 static void *ngx_palloc_block(ngx_pool_t *pool, size_t size);
0015 static void *ngx_palloc_large(ngx_pool_t *pool, size_t size);
0016 
0017 
0018 ngx_pool_t *
0019 ngx_create_pool(size_t size, ngx_log_t *log)
0020 {
0021     ngx_pool_t  *p;
0022 
0023     p = ngx_memalign(NGX_POOL_ALIGNMENT, size, log);
0024     if (p == NULL) {
0025         return NULL;
0026     }
0027 
0028     p->d.last = (u_char *) p + sizeof(ngx_pool_t);
0029     p->d.end = (u_char *) p + size;
0030     p->d.next = NULL;
0031     p->d.failed = 0;
0032 
0033     size = size - sizeof(ngx_pool_t);
0034     p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;
0035 
0036     p->current = p;
0037     p->chain = NULL;
0038     p->large = NULL;
0039     p->cleanup = NULL;
0040     p->log = log;
0041 
0042     return p;
0043 }
0044 
0045 
0046 void
0047 ngx_destroy_pool(ngx_pool_t *pool)
0048 {
0049     ngx_pool_t          *p, *n;
0050     ngx_pool_large_t    *l;
0051     ngx_pool_cleanup_t  *c;
0052 
0053     for (c = pool->cleanup; c; c = c->next) {
0054         if (c->handler) {
0055             ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
0056                            "run cleanup: %p", c);
0057             c->handler(c->data);
0058         }
0059     }
0060 
0061 #if (NGX_DEBUG)
0062 
0063     /*
0064      * we could allocate the pool->log from this pool
0065      * so we cannot use this log while free()ing the pool
0066      */
0067 
0068     for (l = pool->large; l; l = l->next) {
0069         ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc);
0070     }
0071 
0072     for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
0073         ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
0074                        "free: %p, unused: %uz", p, p->d.end - p->d.last);
0075 
0076         if (n == NULL) {
0077             break;
0078         }
0079     }
0080 
0081 #endif
0082 
0083     for (l = pool->large; l; l = l->next) {
0084         if (l->alloc) {
0085             ngx_free(l->alloc);
0086         }
0087     }
0088 
0089     for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
0090         ngx_free(p);
0091 
0092         if (n == NULL) {
0093             break;
0094         }
0095     }
0096 }
0097 
0098 
0099 void
0100 ngx_reset_pool(ngx_pool_t *pool)
0101 {
0102     ngx_pool_t        *p;
0103     ngx_pool_large_t  *l;
0104 
0105     for (l = pool->large; l; l = l->next) {
0106         if (l->alloc) {
0107             ngx_free(l->alloc);
0108         }
0109     }
0110 
0111     for (p = pool; p; p = p->d.next) {
0112         p->d.last = (u_char *) p + sizeof(ngx_pool_t);
0113         p->d.failed = 0;
0114     }
0115 
0116     pool->current = pool;
0117     pool->chain = NULL;
0118     pool->large = NULL;
0119 }
0120 
0121 
0122 void *
0123 ngx_palloc(ngx_pool_t *pool, size_t size)
0124 {
0125 #if !(NGX_DEBUG_PALLOC)
0126     if (size <= pool->max) {
0127         return ngx_palloc_small(pool, size, 1);
0128     }
0129 #endif
0130 
0131     return ngx_palloc_large(pool, size);
0132 }
0133 
0134 
0135 void *
0136 ngx_pnalloc(ngx_pool_t *pool, size_t size)
0137 {
0138 #if !(NGX_DEBUG_PALLOC)
0139     if (size <= pool->max) {
0140         return ngx_palloc_small(pool, size, 0);
0141     }
0142 #endif
0143 
0144     return ngx_palloc_large(pool, size);
0145 }
0146 
0147 
0148 static ngx_inline void *
0149 ngx_palloc_small(ngx_pool_t *pool, size_t size, ngx_uint_t align)
0150 {
0151     u_char      *m;
0152     ngx_pool_t  *p;
0153 
0154     p = pool->current;
0155 
0156     do {
0157         m = p->d.last;
0158 
0159         if (align) {
0160             m = ngx_align_ptr(m, NGX_ALIGNMENT);
0161         }
0162 
0163         if ((size_t) (p->d.end - m) >= size) {
0164             p->d.last = m + size;
0165 
0166             return m;
0167         }
0168 
0169         p = p->d.next;
0170 
0171     } while (p);
0172 
0173     return ngx_palloc_block(pool, size);
0174 }
0175 
0176 
0177 static void *
0178 ngx_palloc_block(ngx_pool_t *pool, size_t size)
0179 {
0180     u_char      *m;
0181     size_t       psize;
0182     ngx_pool_t  *p, *new;
0183 
0184     psize = (size_t) (pool->d.end - (u_char *) pool);
0185 
0186     m = ngx_memalign(NGX_POOL_ALIGNMENT, psize, pool->log);
0187     if (m == NULL) {
0188         return NULL;
0189     }
0190 
0191     new = (ngx_pool_t *) m;
0192 
0193     new->d.end = m + psize;
0194     new->d.next = NULL;
0195     new->d.failed = 0;
0196 
0197     m += sizeof(ngx_pool_data_t);
0198     m = ngx_align_ptr(m, NGX_ALIGNMENT);
0199     new->d.last = m + size;
0200 
0201     for (p = pool->current; p->d.next; p = p->d.next) {
0202         if (p->d.failed++ > 4) {
0203             pool->current = p->d.next;
0204         }
0205     }
0206 
0207     p->d.next = new;
0208 
0209     return m;
0210 }
0211 
0212 
0213 static void *
0214 ngx_palloc_large(ngx_pool_t *pool, size_t size)
0215 {
0216     void              *p;
0217     ngx_uint_t         n;
0218     ngx_pool_large_t  *large;
0219 
0220     p = ngx_alloc(size, pool->log);
0221     if (p == NULL) {
0222         return NULL;
0223     }
0224 
0225     n = 0;
0226 
0227     for (large = pool->large; large; large = large->next) {
0228         if (large->alloc == NULL) {
0229             large->alloc = p;
0230             return p;
0231         }
0232 
0233         if (n++ > 3) {
0234             break;
0235         }
0236     }
0237 
0238     large = ngx_palloc_small(pool, sizeof(ngx_pool_large_t), 1);
0239     if (large == NULL) {
0240         ngx_free(p);
0241         return NULL;
0242     }
0243 
0244     large->alloc = p;
0245     large->next = pool->large;
0246     pool->large = large;
0247 
0248     return p;
0249 }
0250 
0251 
0252 void *
0253 ngx_pmemalign(ngx_pool_t *pool, size_t size, size_t alignment)
0254 {
0255     void              *p;
0256     ngx_pool_large_t  *large;
0257 
0258     p = ngx_memalign(alignment, size, pool->log);
0259     if (p == NULL) {
0260         return NULL;
0261     }
0262 
0263     large = ngx_palloc_small(pool, sizeof(ngx_pool_large_t), 1);
0264     if (large == NULL) {
0265         ngx_free(p);
0266         return NULL;
0267     }
0268 
0269     large->alloc = p;
0270     large->next = pool->large;
0271     pool->large = large;
0272 
0273     return p;
0274 }
0275 
0276 
0277 ngx_int_t
0278 ngx_pfree(ngx_pool_t *pool, void *p)
0279 {
0280     ngx_pool_large_t  *l;
0281 
0282     for (l = pool->large; l; l = l->next) {
0283         if (p == l->alloc) {
0284             ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
0285                            "free: %p", l->alloc);
0286             ngx_free(l->alloc);
0287             l->alloc = NULL;
0288 
0289             return NGX_OK;
0290         }
0291     }
0292 
0293     return NGX_DECLINED;
0294 }
0295 
0296 
0297 void *
0298 ngx_pcalloc(ngx_pool_t *pool, size_t size)
0299 {
0300     void *p;
0301 
0302     p = ngx_palloc(pool, size);
0303     if (p) {
0304         ngx_memzero(p, size);
0305     }
0306 
0307     return p;
0308 }
0309 
0310 
0311 ngx_pool_cleanup_t *
0312 ngx_pool_cleanup_add(ngx_pool_t *p, size_t size)
0313 {
0314     ngx_pool_cleanup_t  *c;
0315 
0316     c = ngx_palloc(p, sizeof(ngx_pool_cleanup_t));
0317     if (c == NULL) {
0318         return NULL;
0319     }
0320 
0321     if (size) {
0322         c->data = ngx_palloc(p, size);
0323         if (c->data == NULL) {
0324             return NULL;
0325         }
0326 
0327     } else {
0328         c->data = NULL;
0329     }
0330 
0331     c->handler = NULL;
0332     c->next = p->cleanup;
0333 
0334     p->cleanup = c;
0335 
0336     ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, p->log, 0, "add cleanup: %p", c);
0337 
0338     return c;
0339 }
0340 
0341 
0342 void
0343 ngx_pool_run_cleanup_file(ngx_pool_t *p, ngx_fd_t fd)
0344 {
0345     ngx_pool_cleanup_t       *c;
0346     ngx_pool_cleanup_file_t  *cf;
0347 
0348     for (c = p->cleanup; c; c = c->next) {
0349         if (c->handler == ngx_pool_cleanup_file) {
0350 
0351             cf = c->data;
0352 
0353             if (cf->fd == fd) {
0354                 c->handler(cf);
0355                 c->handler = NULL;
0356                 return;
0357             }
0358         }
0359     }
0360 }
0361 
0362 
0363 void
0364 ngx_pool_cleanup_file(void *data)
0365 {
0366     ngx_pool_cleanup_file_t  *c = data;
0367 
0368     ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, c->log, 0, "file cleanup: fd:%d",
0369                    c->fd);
0370 
0371     if (ngx_close_file(c->fd) == NGX_FILE_ERROR) {
0372         ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
0373                       ngx_close_file_n " \"%s\" failed", c->name);
0374     }
0375 }
0376 
0377 
0378 void
0379 ngx_pool_delete_file(void *data)
0380 {
0381     ngx_pool_cleanup_file_t  *c = data;
0382 
0383     ngx_err_t  err;
0384 
0385     ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, c->log, 0, "file cleanup: fd:%d %s",
0386                    c->fd, c->name);
0387 
0388     if (ngx_delete_file(c->name) == NGX_FILE_ERROR) {
0389         err = ngx_errno;
0390 
0391         if (err != NGX_ENOENT) {
0392             ngx_log_error(NGX_LOG_CRIT, c->log, err,
0393                           ngx_delete_file_n " \"%s\" failed", c->name);
0394         }
0395     }
0396 
0397     if (ngx_close_file(c->fd) == NGX_FILE_ERROR) {
0398         ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
0399                       ngx_close_file_n " \"%s\" failed", c->name);
0400     }
0401 }
0402 
0403 
0404 #if 0
0405 
0406 static void *
0407 ngx_get_cached_block(size_t size)
0408 {
0409     void                     *p;
0410     ngx_cached_block_slot_t  *slot;
0411 
0412     if (ngx_cycle->cache == NULL) {
0413         return NULL;
0414     }
0415 
0416     slot = &ngx_cycle->cache[(size + ngx_pagesize - 1) / ngx_pagesize];
0417 
0418     slot->tries++;
0419 
0420     if (slot->number) {
0421         p = slot->block;
0422         slot->block = slot->block->next;
0423         slot->number--;
0424         return p;
0425     }
0426 
0427     return NULL;
0428 }
0429 
0430 #endif