src/os/unix/ngx_aio_write_chain.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. #include <ngx_event.h>


  8. ngx_chain_t *
  9. ngx_aio_write_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
  10. {
  11.     u_char       *buf, *prev;
  12.     off_t         send, sent;
  13.     size_t        len;
  14.     ssize_t       n, size;
  15.     ngx_chain_t  *cl;

  16.     /* the maximum limit size is the maximum size_t value - the page size */

  17.     if (limit == 0 || limit > (off_t) (NGX_MAX_SIZE_T_VALUE - ngx_pagesize)) {
  18.         limit = NGX_MAX_SIZE_T_VALUE - ngx_pagesize;
  19.     }

  20.     send = 0;
  21.     sent = 0;
  22.     cl = in;

  23.     while (cl) {

  24.         if (cl->buf->pos == cl->buf->last) {
  25.             cl = cl->next;
  26.             continue;
  27.         }

  28.         /* we can post the single aio operation only */

  29.         if (!c->write->ready) {
  30.             return cl;
  31.         }

  32.         buf = cl->buf->pos;
  33.         prev = buf;
  34.         len = 0;

  35.         /* coalesce the neighbouring bufs */

  36.         while (cl && prev == cl->buf->pos && send < limit) {
  37.             if (ngx_buf_special(cl->buf)) {
  38.                 continue;
  39.             }

  40.             size = cl->buf->last - cl->buf->pos;

  41.             if (send + size > limit) {
  42.                 size = limit - send;
  43.             }

  44.             len += size;
  45.             prev = cl->buf->pos + size;
  46.             send += size;
  47.             cl = cl->next;
  48.         }

  49.         n = ngx_aio_write(c, buf, len);

  50.         ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "aio_write: %z", n);

  51.         if (n == NGX_ERROR) {
  52.             return NGX_CHAIN_ERROR;
  53.         }

  54.         if (n > 0) {
  55.             sent += n;
  56.             c->sent += n;
  57.         }

  58.         ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
  59.                        "aio_write sent: %O", c->sent);

  60.         for (cl = in; cl; cl = cl->next) {

  61.             if (sent >= cl->buf->last - cl->buf->pos) {
  62.                 sent -= cl->buf->last - cl->buf->pos;
  63.                 cl->buf->pos = cl->buf->last;

  64.                 continue;
  65.             }

  66.             cl->buf->pos += sent;

  67.             break;
  68.         }
  69.     }

  70.     return cl;
  71. }