Mercurial > hg > nginx-vendor-current
diff src/os/unix/ngx_aio_read_chain.c @ 0:f0b350454894 NGINX_0_1_0
nginx 0.1.0
*) The first public version.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 04 Oct 2004 00:00:00 +0400 |
parents | |
children | 72eb30262aac |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/src/os/unix/ngx_aio_read_chain.c @@ -0,0 +1,78 @@ + +/* + * Copyright (C) Igor Sysoev + */ + + +#include <ngx_config.h> +#include <ngx_core.h> +#include <ngx_event.h> +#include <ngx_aio.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; + ngx_err_t err; + + 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; +}