Mercurial > hg > nginx-ranges
diff src/http/ngx_http_copy_filter_module.c @ 539:5f4de8cf0d9d
Merge with current.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Tue, 15 Sep 2009 03:43:40 +0400 |
parents | 0161f3197817 |
children | 2b9e388c61f1 |
line wrap: on
line diff
--- a/src/http/ngx_http_copy_filter_module.c +++ b/src/http/ngx_http_copy_filter_module.c @@ -14,6 +14,15 @@ typedef struct { } ngx_http_copy_filter_conf_t; +#if (NGX_HAVE_FILE_AIO) +static void ngx_http_copy_aio_handler(ngx_output_chain_ctx_t *ctx, + ngx_file_t *file); +static void ngx_http_copy_aio_event_handler(ngx_event_t *ev); +#if (NGX_HAVE_AIO_SENDFILE) +static void ngx_http_copy_aio_sendfile_event_handler(ngx_event_t *ev); +#endif +#endif + static void *ngx_http_copy_filter_create_conf(ngx_conf_t *cf); static char *ngx_http_copy_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child); @@ -73,18 +82,17 @@ ngx_http_copy_filter(ngx_http_request_t ngx_int_t rc; ngx_connection_t *c; ngx_output_chain_ctx_t *ctx; + ngx_http_core_loc_conf_t *clcf; ngx_http_copy_filter_conf_t *conf; c = r->connection; ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, - "copy filter: \"%V?%V\"", &r->uri, &r->args); + "http copy filter: \"%V?%V\"", &r->uri, &r->args); ctx = ngx_http_get_module_ctx(r, ngx_http_copy_filter_module); if (ctx == NULL) { - conf = ngx_http_get_module_loc_conf(r, ngx_http_copy_filter_module); - ctx = ngx_pcalloc(r->pool, sizeof(ngx_output_chain_ctx_t)); if (ctx == NULL) { return NGX_ERROR; @@ -92,11 +100,16 @@ ngx_http_copy_filter(ngx_http_request_t ngx_http_set_ctx(r, ctx, ngx_http_copy_filter_module); + conf = ngx_http_get_module_loc_conf(r, ngx_http_copy_filter_module); + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + ctx->sendfile = c->sendfile; ctx->need_in_memory = r->main_filter_need_in_memory || r->filter_need_in_memory; ctx->need_in_temp = r->filter_need_temporary; + ctx->alignment = clcf->directio_alignment; + ctx->pool = r->pool; ctx->bufs = conf->bufs; ctx->tag = (ngx_buf_tag_t) &ngx_http_copy_filter_module; @@ -104,27 +117,139 @@ ngx_http_copy_filter(ngx_http_request_t ctx->output_filter = (ngx_output_chain_filter_pt) ngx_http_next_filter; ctx->filter_ctx = r; +#if (NGX_HAVE_FILE_AIO) + if (clcf->aio) { + ctx->aio_handler = ngx_http_copy_aio_handler; +#if (NGX_HAVE_AIO_SENDFILE) + c->aio_sendfile = (clcf->aio == NGX_HTTP_AIO_SENDFILE); +#endif + } +#endif + r->request_output = 1; } - rc = ngx_output_chain(ctx, in); +#if (NGX_HAVE_FILE_AIO) + ctx->aio = r->aio; +#endif - if (!c->destroyed) { + for ( ;; ) { + rc = ngx_output_chain(ctx, in); if (ctx->in == NULL) { r->buffered &= ~NGX_HTTP_COPY_BUFFERED; + } else { r->buffered |= NGX_HTTP_COPY_BUFFERED; } - ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "copy filter: %i \"%V?%V\"", rc, &r->uri, &r->args); + ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, + "http copy filter: %i \"%V?%V\"", rc, &r->uri, &r->args); + +#if (NGX_HAVE_FILE_AIO && NGX_HAVE_AIO_SENDFILE) + + if (c->busy_sendfile) { + ssize_t n; + off_t offset; + ngx_file_t *file; + ngx_http_ephemeral_t *e; + + file = c->busy_sendfile->file; + offset = c->busy_sendfile->file_pos; + + if (file->aio) { + c->aio_sendfile = (offset != file->aio->last_offset); + file->aio->last_offset = offset; + + if (c->aio_sendfile == 0) { + ngx_log_error(NGX_LOG_ALERT, c->log, 0, + "sendfile(%V) returned busy again", + &file->name); + } + } + + c->busy_sendfile = NULL; + e = (ngx_http_ephemeral_t *) &r->uri_start; + + n = ngx_file_aio_read(file, &e->aio_preload, 1, offset, r->pool); + + if (n > 0) { + in = NULL; + continue; + } + + rc = n; + + if (file->aio) { + file->aio->data = r; + file->aio->handler = ngx_http_copy_aio_sendfile_event_handler; + + r->main->blocked++; + r->aio = 1; + } + } +#endif + + return rc; } +} - return rc; + +#if (NGX_HAVE_FILE_AIO) + +static void +ngx_http_copy_aio_handler(ngx_output_chain_ctx_t *ctx, ngx_file_t *file) +{ + ngx_http_request_t *r; + + r = ctx->filter_ctx; + + file->aio->data = r; + file->aio->handler = ngx_http_copy_aio_event_handler; + + r->main->blocked++; + r->aio = 1; } +static void +ngx_http_copy_aio_event_handler(ngx_event_t *ev) +{ + ngx_event_aio_t *aio; + ngx_http_request_t *r; + + aio = ev->data; + r = aio->data; + + r->main->blocked--; + r->aio = 0; + + r->connection->write->handler(r->connection->write); +} + + +#if (NGX_HAVE_AIO_SENDFILE) + +static void +ngx_http_copy_aio_sendfile_event_handler(ngx_event_t *ev) +{ + ngx_event_aio_t *aio; + ngx_http_request_t *r; + + aio = ev->data; + r = aio->data; + + r->main->blocked--; + r->aio = 0; + ev->complete = 0; + + r->connection->write->handler(r->connection->write); +} + +#endif +#endif + + static void * ngx_http_copy_filter_create_conf(ngx_conf_t *cf) {