view src/os/unix/ngx_aio_read_chain.c @ 5267:13c006f0c40e

Events: honor NGX_USE_GREEDY_EVENT when kqueue support is enabled. Currently this flag is needed for epoll and rtsig, and though these methods usually present on different platforms than kqueue, nginx can be compiled to support all of them.
author Valentin Bartenev <vbart@nginx.com>
date Sat, 13 Jul 2013 03:24:30 +0400
parents d620f497c50f
children ec81934727a1
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>


ssize_t
ngx_aio_read_chain(ngx_connection_t *c, ngx_chain_t *cl)
{
    int           n;
    u_char       *buf, *prev;
    size_t        size;
    ssize_t       total;

    if (c->read->pending_eof) {
        c->read->ready = 0;
        return 0;
    }

    total = 0;

    while (cl) {

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

        if (!c->read->ready) {
            return total ? total : NGX_AGAIN;
        }

        buf = cl->buf->last;
        prev = cl->buf->last;
        size = 0;

        /* coalesce the neighbouring bufs */

        while (cl && prev == cl->buf->last) {
            size += cl->buf->end - cl->buf->last;
            prev = cl->buf->end;
            cl = cl->next;
        }

        n = ngx_aio_read(c, buf, size);

        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "aio_read: %d", n);

        if (n == NGX_AGAIN) {
            return total ? total : NGX_AGAIN;
        }

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

        if (n == 0) {
            c->read->pending_eof = 1;
            if (total) {
                c->read->eof = 0;
                c->read->ready = 1;
            }
            return total;
        }

        if (n > 0) {
            total += n;
        }

        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
                       "aio_read total: %d", total);
    }

    return total ? total : NGX_AGAIN;
}