Fixed AIO error handling on FreeBSD.

The aio_return() must be called regardless of the error returned by
aio_error().  Not calling it resulted in various problems up to segmentation
faults (as AIO events are level-triggered and were reported again and again).

Additionally, in "aio sendfile" case r->blocked was incremented in case of
error returned from ngx_file_aio_read(), thus causing request hangs.
This commit is contained in:
Maxim Dounin 2012-01-30 07:39:47 +00:00
parent 90a7a8f5d9
commit b3e461e63c
2 changed files with 10 additions and 19 deletions

View File

@ -190,7 +190,7 @@ ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in)
rc = n; rc = n;
if (file->aio) { if (rc == NGX_AGAIN) {
file->aio->data = r; file->aio->data = r;
file->aio->handler = ngx_http_copy_aio_sendfile_event_handler; file->aio->handler = ngx_http_copy_aio_sendfile_event_handler;

View File

@ -157,24 +157,15 @@ ngx_file_aio_result(ngx_file_t *file, ngx_event_aio_t *aio, ngx_event_t *ev)
return NGX_ERROR; return NGX_ERROR;
} }
if (n != 0) { if (n == NGX_EINPROGRESS) {
if (n == NGX_EINPROGRESS) { if (ev->ready) {
if (ev->ready) { ev->ready = 0;
ev->ready = 0; ngx_log_error(NGX_LOG_ALERT, file->log, n,
ngx_log_error(NGX_LOG_ALERT, file->log, n, "aio_read(\"%V\") still in progress",
"aio_read(\"%V\") still in progress", &file->name);
&file->name);
}
return NGX_AGAIN;
} }
aio->err = n; return NGX_AGAIN;
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); n = aio_return(&aio->aiocb);
@ -182,9 +173,9 @@ ngx_file_aio_result(ngx_file_t *file, ngx_event_aio_t *aio, ngx_event_t *ev)
if (n == -1) { if (n == -1) {
err = ngx_errno; err = ngx_errno;
aio->err = err; aio->err = err;
ev->ready = 0; ev->ready = 1;
ngx_log_error(NGX_LOG_ALERT, file->log, err, ngx_log_error(NGX_LOG_CRIT, file->log, err,
"aio_return(\"%V\") failed", &file->name); "aio_return(\"%V\") failed", &file->name);
return NGX_ERROR; return NGX_ERROR;
} }