src/core/ngx_buf.c - nginx-1.7.10

Functions defined

Source code


  1. /*
  2. * Copyright (C) Igor Sysoev
  3. * Copyright (C) Nginx, Inc.
  4. */


  5. #include <ngx_config.h>
  6. #include <ngx_core.h>


  7. ngx_buf_t *
  8. ngx_create_temp_buf(ngx_pool_t *pool, size_t size)
  9. {
  10.     ngx_buf_t *b;

  11.     b = ngx_calloc_buf(pool);
  12.     if (b == NULL) {
  13.         return NULL;
  14.     }

  15.     b->start = ngx_palloc(pool, size);
  16.     if (b->start == NULL) {
  17.         return NULL;
  18.     }

  19.     /*
  20.      * set by ngx_calloc_buf():
  21.      *
  22.      *     b->file_pos = 0;
  23.      *     b->file_last = 0;
  24.      *     b->file = NULL;
  25.      *     b->shadow = NULL;
  26.      *     b->tag = 0;
  27.      *     and flags
  28.      */

  29.     b->pos = b->start;
  30.     b->last = b->start;
  31.     b->end = b->last + size;
  32.     b->temporary = 1;

  33.     return b;
  34. }


  35. ngx_chain_t *
  36. ngx_alloc_chain_link(ngx_pool_t *pool)
  37. {
  38.     ngx_chain_t  *cl;

  39.     cl = pool->chain;

  40.     if (cl) {
  41.         pool->chain = cl->next;
  42.         return cl;
  43.     }

  44.     cl = ngx_palloc(pool, sizeof(ngx_chain_t));
  45.     if (cl == NULL) {
  46.         return NULL;
  47.     }

  48.     return cl;
  49. }


  50. ngx_chain_t *
  51. ngx_create_chain_of_bufs(ngx_pool_t *pool, ngx_bufs_t *bufs)
  52. {
  53.     u_char       *p;
  54.     ngx_int_t     i;
  55.     ngx_buf_t    *b;
  56.     ngx_chain_t  *chain, *cl, **ll;

  57.     p = ngx_palloc(pool, bufs->num * bufs->size);
  58.     if (p == NULL) {
  59.         return NULL;
  60.     }

  61.     ll = &chain;

  62.     for (i = 0; i < bufs->num; i++) {

  63.         b = ngx_calloc_buf(pool);
  64.         if (b == NULL) {
  65.             return NULL;
  66.         }

  67.         /*
  68.          * set by ngx_calloc_buf():
  69.          *
  70.          *     b->file_pos = 0;
  71.          *     b->file_last = 0;
  72.          *     b->file = NULL;
  73.          *     b->shadow = NULL;
  74.          *     b->tag = 0;
  75.          *     and flags
  76.          *
  77.          */

  78.         b->pos = p;
  79.         b->last = p;
  80.         b->temporary = 1;

  81.         b->start = p;
  82.         p += bufs->size;
  83.         b->end = p;

  84.         cl = ngx_alloc_chain_link(pool);
  85.         if (cl == NULL) {
  86.             return NULL;
  87.         }

  88.         cl->buf = b;
  89.         *ll = cl;
  90.         ll = &cl->next;
  91.     }

  92.     *ll = NULL;

  93.     return chain;
  94. }


  95. ngx_int_t
  96. ngx_chain_add_copy(ngx_pool_t *pool, ngx_chain_t **chain, ngx_chain_t *in)
  97. {
  98.     ngx_chain_t  *cl, **ll;

  99.     ll = chain;

  100.     for (cl = *chain; cl; cl = cl->next) {
  101.         ll = &cl->next;
  102.     }

  103.     while (in) {
  104.         cl = ngx_alloc_chain_link(pool);
  105.         if (cl == NULL) {
  106.             return NGX_ERROR;
  107.         }

  108.         cl->buf = in->buf;
  109.         *ll = cl;
  110.         ll = &cl->next;
  111.         in = in->next;
  112.     }

  113.     *ll = NULL;

  114.     return NGX_OK;
  115. }


  116. ngx_chain_t *
  117. ngx_chain_get_free_buf(ngx_pool_t *p, ngx_chain_t **free)
  118. {
  119.     ngx_chain_t  *cl;

  120.     if (*free) {
  121.         cl = *free;
  122.         *free = cl->next;
  123.         cl->next = NULL;
  124.         return cl;
  125.     }

  126.     cl = ngx_alloc_chain_link(p);
  127.     if (cl == NULL) {
  128.         return NULL;
  129.     }

  130.     cl->buf = ngx_calloc_buf(p);
  131.     if (cl->buf == NULL) {
  132.         return NULL;
  133.     }

  134.     cl->next = NULL;

  135.     return cl;
  136. }


  137. void
  138. ngx_chain_update_chains(ngx_pool_t *p, ngx_chain_t **free, ngx_chain_t **busy,
  139.     ngx_chain_t **out, ngx_buf_tag_t tag)
  140. {
  141.     ngx_chain_t  *cl;

  142.     if (*busy == NULL) {
  143.         *busy = *out;

  144.     } else {
  145.         for (cl = *busy; cl->next; cl = cl->next) { /* void */ }

  146.         cl->next = *out;
  147.     }

  148.     *out = NULL;

  149.     while (*busy) {
  150.         cl = *busy;

  151.         if (ngx_buf_size(cl->buf) != 0) {
  152.             break;
  153.         }

  154.         if (cl->buf->tag != tag) {
  155.             *busy = cl->next;
  156.             ngx_free_chain(p, cl);
  157.             continue;
  158.         }

  159.         cl->buf->pos = cl->buf->start;
  160.         cl->buf->last = cl->buf->start;

  161.         *busy = cl->next;
  162.         cl->next = *free;
  163.         *free = cl;
  164.     }
  165. }


  166. off_t
  167. ngx_chain_coalesce_file(ngx_chain_t **in, off_t limit)
  168. {
  169.     off_t         total, size, aligned, fprev;
  170.     ngx_fd_t      fd;
  171.     ngx_chain_t  *cl;

  172.     total = 0;

  173.     cl = *in;
  174.     fd = cl->buf->file->fd;

  175.     do {
  176.         size = cl->buf->file_last - cl->buf->file_pos;

  177.         if (size > limit - total) {
  178.             size = limit - total;

  179.             aligned = (cl->buf->file_pos + size + ngx_pagesize - 1)
  180.                        & ~((off_t) ngx_pagesize - 1);

  181.             if (aligned <= cl->buf->file_last) {
  182.                 size = aligned - cl->buf->file_pos;
  183.             }
  184.         }

  185.         total += size;
  186.         fprev = cl->buf->file_pos + size;
  187.         cl = cl->next;

  188.     } while (cl
  189.              && cl->buf->in_file
  190.              && total < limit
  191.              && fd == cl->buf->file->fd
  192.              && fprev == cl->buf->file_pos);

  193.     *in = cl;

  194.     return total;
  195. }


  196. ngx_chain_t *
  197. ngx_chain_update_sent(ngx_chain_t *in, off_t sent)
  198. {
  199.     off_t  size;

  200.     for ( /* void */ ; in; in = in->next) {

  201.         if (ngx_buf_special(in->buf)) {
  202.             continue;
  203.         }

  204.         if (sent == 0) {
  205.             break;
  206.         }

  207.         size = ngx_buf_size(in->buf);

  208.         if (sent >= size) {
  209.             sent -= size;

  210.             if (ngx_buf_in_memory(in->buf)) {
  211.                 in->buf->pos = in->buf->last;
  212.             }

  213.             if (in->buf->in_file) {
  214.                 in->buf->file_pos = in->buf->file_last;
  215.             }

  216.             continue;
  217.         }

  218.         if (ngx_buf_in_memory(in->buf)) {
  219.             in->buf->pos += (size_t) sent;
  220.         }

  221.         if (in->buf->in_file) {
  222.             in->buf->file_pos += sent;
  223.         }

  224.         break;
  225.     }

  226.     return in;
  227. }