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 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             *ll = NULL;
0141             return NGX_ERROR;
0142         }
0143 
0144         cl->buf = in->buf;
0145         *ll = cl;
0146         ll = &cl->next;
0147         in = in->next;
0148     }
0149 
0150     *ll = NULL;
0151 
0152     return NGX_OK;
0153 }
0154 
0155 
0156 ngx_chain_t *
0157 ngx_chain_get_free_buf(ngx_pool_t *p, ngx_chain_t **free)
0158 {
0159     ngx_chain_t  *cl;
0160 
0161     if (*free) {
0162         cl = *free;
0163         *free = cl->next;
0164         cl->next = NULL;
0165         return cl;
0166     }
0167 
0168     cl = ngx_alloc_chain_link(p);
0169     if (cl == NULL) {
0170         return NULL;
0171     }
0172 
0173     cl->buf = ngx_calloc_buf(p);
0174     if (cl->buf == NULL) {
0175         return NULL;
0176     }
0177 
0178     cl->next = NULL;
0179 
0180     return cl;
0181 }
0182 
0183 
0184 void
0185 ngx_chain_update_chains(ngx_pool_t *p, ngx_chain_t **free, ngx_chain_t **busy,
0186     ngx_chain_t **out, ngx_buf_tag_t tag)
0187 {
0188     ngx_chain_t  *cl;
0189 
0190     if (*out) {
0191         if (*busy == NULL) {
0192             *busy = *out;
0193 
0194         } else {
0195             for (cl = *busy; cl->next; cl = cl->next) { /* void */ }
0196 
0197             cl->next = *out;
0198         }
0199 
0200         *out = NULL;
0201     }
0202 
0203     while (*busy) {
0204         cl = *busy;
0205 
0206         if (ngx_buf_size(cl->buf) != 0) {
0207             break;
0208         }
0209 
0210         if (cl->buf->tag != tag) {
0211             *busy = cl->next;
0212             ngx_free_chain(p, cl);
0213             continue;
0214         }
0215 
0216         cl->buf->pos = cl->buf->start;
0217         cl->buf->last = cl->buf->start;
0218 
0219         *busy = cl->next;
0220         cl->next = *free;
0221         *free = cl;
0222     }
0223 }
0224 
0225 
0226 off_t
0227 ngx_chain_coalesce_file(ngx_chain_t **in, off_t limit)
0228 {
0229     off_t         total, size, aligned, fprev;
0230     ngx_fd_t      fd;
0231     ngx_chain_t  *cl;
0232 
0233     total = 0;
0234 
0235     cl = *in;
0236     fd = cl->buf->file->fd;
0237 
0238     do {
0239         size = cl->buf->file_last - cl->buf->file_pos;
0240 
0241         if (size > limit - total) {
0242             size = limit - total;
0243 
0244             aligned = (cl->buf->file_pos + size + ngx_pagesize - 1)
0245                        & ~((off_t) ngx_pagesize - 1);
0246 
0247             if (aligned <= cl->buf->file_last) {
0248                 size = aligned - cl->buf->file_pos;
0249             }
0250 
0251             total += size;
0252             break;
0253         }
0254 
0255         total += size;
0256         fprev = cl->buf->file_pos + size;
0257         cl = cl->next;
0258 
0259     } while (cl
0260              && cl->buf->in_file
0261              && total < limit
0262              && fd == cl->buf->file->fd
0263              && fprev == cl->buf->file_pos);
0264 
0265     *in = cl;
0266 
0267     return total;
0268 }
0269 
0270 
0271 ngx_chain_t *
0272 ngx_chain_update_sent(ngx_chain_t *in, off_t sent)
0273 {
0274     off_t  size;
0275 
0276     for ( /* void */ ; in; in = in->next) {
0277 
0278         if (ngx_buf_special(in->buf)) {
0279             continue;
0280         }
0281 
0282         if (sent == 0) {
0283             break;
0284         }
0285 
0286         size = ngx_buf_size(in->buf);
0287 
0288         if (sent >= size) {
0289             sent -= size;
0290 
0291             if (ngx_buf_in_memory(in->buf)) {
0292                 in->buf->pos = in->buf->last;
0293             }
0294 
0295             if (in->buf->in_file) {
0296                 in->buf->file_pos = in->buf->file_last;
0297             }
0298 
0299             continue;
0300         }
0301 
0302         if (ngx_buf_in_memory(in->buf)) {
0303             in->buf->pos += (size_t) sent;
0304         }
0305 
0306         if (in->buf->in_file) {
0307             in->buf->file_pos += sent;
0308         }
0309 
0310         break;
0311     }
0312 
0313     return in;
0314 }