Mercurial > hg > nginx-vendor-1-0
view src/os/unix/ngx_file_aio_read.c @ 638:692f4d4d7f10 NGINX_1_0_9
nginx 1.0.9
*) Change: now the 0x7F-0x1F characters are escaped as \xXX in an
access_log.
*) Change: now SIGWINCH signal works only in daemon mode.
*) Feature: "proxy/fastcgi/scgi/uwsgi_ignore_headers" directives support
the following additional values: X-Accel-Limit-Rate,
X-Accel-Buffering, X-Accel-Charset.
*) Feature: decrease of memory consumption if SSL is used.
*) Feature: accept filters are now supported on NetBSD.
*) Feature: the "uwsgi_buffering" and "scgi_buffering" directives.
Thanks to Peter Smit.
*) Bugfix: a segmentation fault occurred on start or while
reconfiguration if the "ssl" directive was used at http level and
there was no "ssl_certificate" defined.
*) Bugfix: some UTF-8 characters were processed incorrectly.
Thanks to Alexey Kuts.
*) Bugfix: the ngx_http_rewrite_module directives specified at "server"
level were executed twice if no matching locations were defined.
*) Bugfix: a socket leak might occurred if "aio sendfile" was used.
*) Bugfix: connections with fast clients might be closed after
send_timeout if file AIO was used.
*) Bugfix: in the ngx_http_autoindex_module.
*) Bugfix: the module ngx_http_mp4_module did not support seeking on
32-bit platforms.
*) Bugfix: non-cacheable responses might be cached if
"proxy_cache_bypass" directive was used.
Thanks to John Ferlito.
*) Bugfix: cached responses with an empty body were returned
incorrectly; the bug had appeared in 0.8.31.
*) Bugfix: 201 responses of the ngx_http_dav_module were incorrect; the
bug had appeared in 0.8.32.
*) Bugfix: in the "return" directive.
*) Bugfix: the "ssl_verify_client", "ssl_verify_depth", and
"ssl_prefer_server_ciphers" directives might work incorrectly if SNI
was used.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Tue, 01 Nov 2011 00:00:00 +0400 |
parents | 0d6525917227 |
children | ad25218fd14b |
line wrap: on
line source
/* * Copyright (C) Igor Sysoev */ #include <ngx_config.h> #include <ngx_core.h> #include <ngx_event.h> /* * FreeBSD file AIO features and quirks: * * if an asked data are already in VM cache, then aio_error() returns 0, * and the data are already copied in buffer; * * aio_read() preread in VM cache as minimum 16K (probably BKVASIZE); * the first AIO preload may be up to 128K; * * aio_read/aio_error() may return EINPROGRESS for just written data; * * kqueue EVFILT_AIO filter is level triggered only: an event repeats * until aio_return() will be called; * * aio_cancel() cannot cancel file AIO: it returns AIO_NOTCANCELED always. */ extern int ngx_kqueue; static ssize_t ngx_file_aio_result(ngx_file_t *file, ngx_event_aio_t *aio, ngx_event_t *ev); static void ngx_file_aio_event_handler(ngx_event_t *ev); ssize_t ngx_file_aio_read(ngx_file_t *file, u_char *buf, size_t size, off_t offset, ngx_pool_t *pool) { int n; ngx_event_t *ev; ngx_event_aio_t *aio; if (!ngx_file_aio) { return ngx_read_file(file, buf, size, offset); } aio = file->aio; if (aio == NULL) { aio = ngx_pcalloc(pool, sizeof(ngx_event_aio_t)); if (aio == NULL) { return NGX_ERROR; } aio->file = file; aio->fd = file->fd; aio->event.data = aio; aio->event.ready = 1; aio->event.log = file->log; #if (NGX_HAVE_AIO_SENDFILE) aio->last_offset = -1; #endif file->aio = aio; } ev = &aio->event; if (!ev->ready) { ngx_log_error(NGX_LOG_ALERT, file->log, 0, "second aio post for \"%V\"", &file->name); return NGX_AGAIN; } ngx_log_debug4(NGX_LOG_DEBUG_CORE, file->log, 0, "aio complete:%d @%O:%z %V", ev->complete, offset, size, &file->name); if (ev->complete) { ev->complete = 0; ngx_set_errno(aio->err); if (aio->err == 0) { return aio->nbytes; } ngx_log_error(NGX_LOG_CRIT, file->log, ngx_errno, "aio read \"%s\" failed", file->name.data); return NGX_ERROR; } ngx_memzero(&aio->aiocb, sizeof(struct aiocb)); aio->aiocb.aio_fildes = file->fd; aio->aiocb.aio_offset = offset; aio->aiocb.aio_buf = buf; aio->aiocb.aio_nbytes = size; #if (NGX_HAVE_KQUEUE) aio->aiocb.aio_sigevent.sigev_notify_kqueue = ngx_kqueue; aio->aiocb.aio_sigevent.sigev_notify = SIGEV_KEVENT; aio->aiocb.aio_sigevent.sigev_value.sigval_ptr = ev; #endif ev->handler = ngx_file_aio_event_handler; n = aio_read(&aio->aiocb); if (n == -1) { n = ngx_errno; if (n == NGX_EAGAIN) { return ngx_read_file(file, buf, size, offset); } ngx_log_error(NGX_LOG_CRIT, file->log, n, "aio_read(\"%V\") failed", &file->name); if (n == NGX_ENOSYS) { ngx_file_aio = 0; return ngx_read_file(file, buf, size, offset); } return NGX_ERROR; } ngx_log_debug2(NGX_LOG_DEBUG_CORE, file->log, 0, "aio_read: fd:%d %d", file->fd, n); ev->active = 1; ev->ready = 0; ev->complete = 0; return ngx_file_aio_result(aio->file, aio, ev); } static ssize_t ngx_file_aio_result(ngx_file_t *file, ngx_event_aio_t *aio, ngx_event_t *ev) { int n; ngx_err_t err; n = aio_error(&aio->aiocb); ngx_log_debug2(NGX_LOG_DEBUG_CORE, file->log, 0, "aio_error: fd:%d %d", file->fd, n); if (n == -1) { err = ngx_errno; aio->err = err; ngx_log_error(NGX_LOG_ALERT, file->log, err, "aio_error(\"%V\") failed", &file->name); return NGX_ERROR; } if (n != 0) { if (n == NGX_EINPROGRESS) { if (ev->ready) { ev->ready = 0; ngx_log_error(NGX_LOG_ALERT, file->log, n, "aio_read(\"%V\") still in progress", &file->name); } return NGX_AGAIN; } aio->err = n; ev->ready = 0; ngx_log_error(NGX_LOG_CRIT, file->log, n, "aio_read(\"%V\") failed", &file->name); return NGX_ERROR; } n = aio_return(&aio->aiocb); if (n == -1) { err = ngx_errno; aio->err = err; ev->ready = 0; ngx_log_error(NGX_LOG_ALERT, file->log, err, "aio_return(\"%V\") failed", &file->name); return NGX_ERROR; } aio->err = 0; aio->nbytes = n; ev->ready = 1; ev->active = 0; ngx_log_debug2(NGX_LOG_DEBUG_CORE, file->log, 0, "aio_return: fd:%d %d", file->fd, n); return n; } static void ngx_file_aio_event_handler(ngx_event_t *ev) { ngx_event_aio_t *aio; aio = ev->data; ngx_log_debug2(NGX_LOG_DEBUG_CORE, ev->log, 0, "aio event handler fd:%d %V", aio->fd, &aio->file->name); if (ngx_file_aio_result(aio->file, aio, ev) != NGX_AGAIN) { aio->handler(ev); } }