Back to home page

Nginx displayed by LXR

Source navigation ]
Diff markup ]
Identifier search ]
general search ]
 
 
Version: nginx-1.13.12 ]​[ nginx-1.12.2 ]​

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 ngx_buf_t *
0013 ngx_create_temp_buf(ngx_pool_t *pool, size_t size)
0014 {
0015     ngx_buf_t *b;
0016 
0017     b = ngx_calloc_buf(pool);
0018     if (b == NULL) {
0019         return NULL;
0020     }
0021 
0022     b->start = ngx_palloc(pool, size);
0023     if (b->start == NULL) {
0024         return NULL;
0025     }
0026 
0027     /*
0028      * set by ngx_calloc_buf():
0029      *
0030      *     b->file_pos = 0;
0031      *     b->file_last = 0;
0032      *     b->file = NULL;
0033      *     b->shadow = NULL;
0034      *     b->tag = 0;
0035      *     and flags
0036      */
0037 
0038     b->pos = b->start;
0039     b->last = b->start;
0040     b->end = b->last + size;
0041     b->temporary = 1;
0042 
0043     return b;
0044 }
0045 
0046 
0047 ngx_chain_t *
0048 ngx_alloc_chain_link(ngx_pool_t *pool)
0049 {
0050     ngx_chain_t  *cl;
0051 
0052     cl = pool->chain;
0053 
0054     if (cl) {
0055         pool->chain = cl->next;
0056         return cl;
0057     }
0058 
0059     cl = ngx_palloc(pool, sizeof(ngx_chain_t));
0060     if (cl == NULL) {
0061         return NULL;
0062     }
0063 
0064     return cl;
0065 }
0066 
0067 
0068 ngx_chain_t *
0069 ngx_create_chain_of_bufs(ngx_pool_t *pool, ngx_bufs_t *bufs)
0070 {
0071     u_char       *p;
0072     ngx_int_t     i;
0073     ngx_buf_t    *b;
0074     ngx_chain_t  *chain, *cl, **ll;
0075 
0076     p = ngx_palloc(pool, bufs->num * bufs->size);
0077     if (p == NULL) {
0078         return NULL;
0079     }
0080 
0081     ll = &chain;
0082 
0083     for (i = 0; i < bufs->num; i++) {
0084 
0085         b = ngx_calloc_buf(pool);
0086         if (b == NULL) {
0087             return NULL;
0088         }
0089 
0090         /*
0091          * set by ngx_calloc_buf():
0092          *
0093          *     b->file_pos = 0;
0094          *     b->file_last = 0;
0095          *     b->file = NULL;
0096          *     b->shadow = NULL;
0097          *     b->tag = 0;
0098          *     and flags
0099          *
0100          */
0101 
0102         b->pos = p;
0103         b->last = p;
0104         b->temporary = 1;
0105 
0106         b->start = p;
0107         p += bufs->size;
0108         b->end = p;
0109 
0110         cl = ngx_alloc_chain_link(pool);
0111         if (cl == NULL) {
0112             return NULL;
0113         }
0114 
0115         cl->buf = b;
0116         *ll = cl;
0117         ll = &cl->next;
0118     }
0119 
0120     *ll = NULL;
0121 
0122     return chain;
0123 }
0124 
0125 
0126 ngx_int_t
0127 ngx_chain_add_copy(ngx_pool_t *pool, ngx_chain_t **chain, ngx_chain_t *in)
0128 {
0129     ngx_chain_t  *cl, **ll;
0130 
0131     ll = chain;
0132 
0133     for (cl = *chain; cl; cl = cl->next) {
0134         ll = &cl->next;
0135     }
0136 
0137     while (in) {
0138         cl = ngx_alloc_chain_link(pool);
0139         if (cl == NULL) {
0140             return NGX_ERROR;
0141         }
0142 
0143         cl->buf = in->buf;
0144         *ll = cl;
0145         ll = &cl->next;
0146         in = in->next;
0147     }
0148 
0149     *ll = NULL;
0150 
0151     return NGX_OK;
0152 }
0153 
0154 
0155 ngx_chain_t *
0156 ngx_chain_get_free_buf(ngx_pool_t *p, ngx_chain_t **free)
0157 {
0158     ngx_chain_t  *cl;
0159 
0160     if (*free) {
0161         cl = *free;
0162         *free = cl->next;
0163         cl->next = NULL;
0164         return cl;
0165     }
0166 
0167     cl = ngx_alloc_chain_link(p);
0168     if (cl == NULL) {
0169         return NULL;
0170     }
0171 
0172     cl->buf = ngx_calloc_buf(p);
0173     if (cl->buf == NULL) {
0174         return NULL;
0175     }
0176 
0177     cl->next = NULL;
0178 
0179     return cl;
0180 }
0181 
0182 
0183 void
0184 ngx_chain_update_chains(ngx_pool_t *p, ngx_chain_t **free, ngx_chain_t **busy,
0185     ngx_chain_t **out, ngx_buf_tag_t tag)
0186 {
0187     ngx_chain_t  *cl;
0188 
0189     if (*out) {
0190         if (*busy == NULL) {
0191             *busy = *out;
0192 
0193         } else {
0194             for (cl = *busy; cl->next; cl = cl->next) { /* void */ }
0195 
0196             cl->next = *out;
0197         }
0198 
0199         *out = NULL;
0200     }
0201 
0202     while (*busy) {
0203         cl = *busy;
0204 
0205         if (ngx_buf_size(cl->buf) != 0) {
0206             break;
0207         }
0208 
0209         if (cl->buf->tag != tag) {
0210             *busy = cl->next;
0211             ngx_free_chain(p, cl);
0212             continue;
0213         }
0214 
0215         cl->buf->pos = cl->buf->start;
0216         cl->buf->last = cl->buf->start;
0217 
0218         *busy = cl->next;
0219         cl->next = *free;
0220         *free = cl;
0221     }
0222 }
0223 
0224 
0225 off_t
0226 ngx_chain_coalesce_file(ngx_chain_t **in, off_t limit)
0227 {
0228     off_t         total, size, aligned, fprev;
0229     ngx_fd_t      fd;
0230     ngx_chain_t  *cl;
0231 
0232     total = 0;
0233 
0234     cl = *in;
0235     fd = cl->buf->file->fd;
0236 
0237     do {
0238         size = cl->buf->file_last - cl->buf->file_pos;
0239 
0240         if (size > limit - total) {
0241             size = limit - total;
0242 
0243             aligned = (cl->buf->file_pos + size + ngx_pagesize - 1)
0244                        & ~((off_t) ngx_pagesize - 1);
0245 
0246             if (aligned <= cl->buf->file_last) {
0247                 size = aligned - cl->buf->file_pos;
0248             }
0249 
0250             total += size;
0251             break;
0252         }
0253 
0254         total += size;
0255         fprev = cl->buf->file_pos + size;
0256         cl = cl->next;
0257 
0258     } while (cl
0259              && cl->buf->in_file
0260              && total < limit
0261              && fd == cl->buf->file->fd
0262              && fprev == cl->buf->file_pos);
0263 
0264     *in = cl;
0265 
0266     return total;
0267 }
0268 
0269 
0270 ngx_chain_t *
0271 ngx_chain_update_sent(ngx_chain_t *in, off_t sent)
0272 {
0273     off_t  size;
0274 
0275     for ( /* void */ ; in; in = in->next) {
0276 
0277         if (ngx_buf_special(in->buf)) {
0278             continue;
0279         }
0280 
0281         if (sent == 0) {
0282             break;
0283         }
0284 
0285         size = ngx_buf_size(in->buf);
0286 
0287         if (sent >= size) {
0288             sent -= size;
0289 
0290             if (ngx_buf_in_memory(in->buf)) {
0291                 in->buf->pos = in->buf->last;
0292             }
0293 
0294             if (in->buf->in_file) {
0295                 in->buf->file_pos = in->buf->file_last;
0296             }
0297 
0298             continue;
0299         }
0300 
0301         if (ngx_buf_in_memory(in->buf)) {
0302             in->buf->pos += (size_t) sent;
0303         }
0304 
0305         if (in->buf->in_file) {
0306             in->buf->file_pos += sent;
0307         }
0308 
0309         break;
0310     }
0311 
0312     return in;
0313 }