view src/os/unix/ngx_aio_write_chain.c @ 5115:a29c574d61fa

Status: introduced the "ngx_stat_waiting" counter. And corresponding variable $connections_waiting was added. Previously, waiting connections were counted as the difference between active connections and the sum of reading and writing connections. That made it impossible to count more than one request in one connection as reading or writing (as is the case for SPDY). Also, we no longer count connections in handshake state as waiting.
author Valentin Bartenev <vbart@nginx.com>
date Fri, 15 Mar 2013 20:00:49 +0000
parents d620f497c50f
children
line wrap: on
line source


/*
 * Copyright (C) Igor Sysoev
 * Copyright (C) Nginx, Inc.
 */


#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_event.h>


ngx_chain_t *
ngx_aio_write_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
{
    u_char       *buf, *prev;
    off_t         send, sent;
    size_t        len;
    ssize_t       n, size;
    ngx_chain_t  *cl;

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

    if (limit == 0 || limit > (off_t) (NGX_MAX_SIZE_T_VALUE - ngx_pagesize)) {
        limit = NGX_MAX_SIZE_T_VALUE - ngx_pagesize;
    }

    send = 0;
    sent = 0;
    cl = in;

    while (cl) {

        if (cl->buf->pos == cl->buf->last) {
            cl = cl->next;
            continue;
        }

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

        if (!c->write->ready) {
            return cl;
        }

        buf = cl->buf->pos;
        prev = buf;
        len = 0;

        /* coalesce the neighbouring bufs */

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

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

            if (send + size > limit) {
                size = limit - send;
            }

            len += size;
            prev = cl->buf->pos + size;
            send += size;
            cl = cl->next;
        }

        n = ngx_aio_write(c, buf, len);

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

        if (n == NGX_ERROR) {
            return NGX_CHAIN_ERROR;
        }

        if (n > 0) {
            sent += n;
            c->sent += n;
        }

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

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

            if (sent >= cl->buf->last - cl->buf->pos) {
                sent -= cl->buf->last - cl->buf->pos;
                cl->buf->pos = cl->buf->last;

                continue;
            }

            cl->buf->pos += sent;

            break;
        }
    }

    return cl;
}