# HG changeset patch # User Igor Sysoev # Date 1050602375 0 # Node ID 57c2e18d357264e2d77f74bc739051d5f684eada # Parent 6127d707547114ca6f5e62e4cc76e25fa009f718 nginx-0.0.1-2003-04-17-21:59:35 import diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h --- a/src/event/ngx_event.h +++ b/src/event/ngx_event.h @@ -69,6 +69,7 @@ struct ngx_event_s { unsigned timedout:1; unsigned blocked:1; unsigned timer_set:1; + unsigned delayed:1; unsigned process:1; unsigned read_discarded:1; diff --git a/src/event/ngx_event_proxy.c b/src/event/ngx_event_proxy.c --- a/src/event/ngx_event_proxy.c +++ b/src/event/ngx_event_proxy.c @@ -31,71 +31,92 @@ ngx_log_debug(p->log, "read upstream"); for ( ;; ) { - /* use the free hunks if they exist */ + /* use the pre-read hunks if they exist */ + + if (p->preread_hunks) { + chain = p->preread_hunks; + p->preread_hunks = NULL; + n = p->preread_size; - if (p->free_hunks) { - chain = p->free_hunks; - p->free_hunks = NULL; + } else { + + /* use the free hunks if they exist */ + + if (p->free_hunks) { + chain = p->free_hunks; + p->free_hunks = NULL; ngx_log_debug(p->log, "free hunk: %08X:%d" _ chain->hunk _ chain->hunk->end - chain->hunk->last); - /* allocate a new hunk if it's still allowed */ - - } else if (p->allocated < p->max_block_size) { - ngx_test_null(h, - ngx_create_temp_hunk(p->pool, p->block_size, 20, 20), - NGX_ERROR); + /* allocate a new hunk if it's still allowed */ - p->allocated += p->block_size; + } else if (p->allocated < p->max_block_size) { + ngx_test_null(h, + ngx_create_temp_hunk(p->pool, + p->block_size, 20, 20), + NGX_ERROR); - ngx_test_null(temp, ngx_alloc_chain_entry(p->pool), NGX_ERROR); - temp->hunk = h; - temp->next = NULL; - chain = temp; + p->allocated += p->block_size; + + ngx_test_null(temp, ngx_alloc_chain_entry(p->pool), NGX_ERROR); + temp->hunk = h; + temp->next = NULL; + chain = temp; ngx_log_debug(p->log, "new hunk: %08X" _ chain->hunk); - /* use the shadow hunks if they exist */ + /* use the shadow hunks if they exist */ - } else if (p->shadow_hunks) { - chain = p->shadow_hunks; - p->shadow_hunks = NULL; + } else if (p->shadow_hunks) { + chain = p->shadow_hunks; + p->shadow_hunks = NULL; ngx_log_debug(p->log, "shadow hunk: %08X" _ chain->hunk _ chain->hunk->end - chain->hunk->last); - /* if it's allowed then save the incoming hunks to a temporary file, - move the saved hunks to a shadow chain, - and add the file hunks to an outgoing chain */ + /* if the hunks is not needed to be saved in a cache and + a downstream is ready then write the hunks to a downstream */ + + } else if (p->cachable == 0 && p->downstream->write->ready) { + + rc = ngx_event_proxy_write_to_downstream(p); - } else if (p->temp_offset < p->max_temp_size) { - rc = ngx_event_proxy_write_chain_to_temp_file(p); + continue; + + /* if it's allowed then save the incoming hunks + to a temporary file, move the saved hunks to a shadow chain, + and add the file hunks to an outgoing chain */ + + } else if (p->temp_offset < p->max_temp_file_size) { + rc = ngx_event_proxy_write_chain_to_temp_file(p); ngx_log_debug(p->log, "temp offset: %d" _ p->temp_offset); - if (rc != NGX_OK) { - return rc; - } + if (rc != NGX_OK) { + return rc; + } - chain = p->shadow_hunks; - p->shadow_hunks = NULL; + chain = p->shadow_hunks; + p->shadow_hunks = NULL; ngx_log_debug(p->log, "new shadow hunk: %08X:%d" _ chain->hunk _ chain->hunk->end - chain->hunk->last); - /* if there're no hunks to read in then disable a level event */ + /* if there're no hunks to read in then disable a level event */ - } else { - if (ngx_event_flags & NGX_USE_LEVEL_EVENT) { - p->block_upstream = 1; + } else { + if (ngx_event_flags & NGX_USE_LEVEL_EVENT) { + p->block_upstream = 1; + } + + break; } - break; + n = ngx_recv_chain(p->upstream, chain); + } - n = ngx_recv_chain(p->upstream, chain); - ngx_log_debug(p->log, "recv_chain: %d" _ n); if (n == NGX_ERROR) { @@ -112,7 +133,7 @@ ngx_log_debug(p->log, "recv_chain: %d" _ p->upstream->read->blocked = 0; } - return NGX_AGAIN; + break; } if (n == 0) { @@ -179,7 +200,7 @@ ngx_log_debug(p->log, "recv_chain: %d" _ ngx_test_null(h, ngx_alloc_hunk(p->pool), NGX_ERROR); ngx_memcpy(h, entry->hunk, sizeof(ngx_hunk_t)); h->shadow = entry->hunk; - h->type |= NGX_HUNK_LAST_SHADOW; + h->type |= NGX_HUNK_LAST_SHADOW|NGX_HUNK_RECYCLED; entry->hunk->shadow = h; ngx_test_null(temp, ngx_alloc_chain_entry(p->pool), @@ -307,12 +328,12 @@ ngx_log_debug(p->log, "eof: %d block: %d } } - if (p->out_hunks && p->client->write->ready) { - rc = ngx_event_proxy_write_to_client(p); + if (p->out_hunks && p->downstream->write->ready) { + rc = ngx_event_proxy_write_to_downstream(p); } - } else if ((p->out_hunks || p->in_hunks) && p->client->write->ready) { - rc = ngx_event_proxy_write_to_client(p); + } else if ((p->out_hunks || p->in_hunks) && p->downstream->write->ready) { + rc = ngx_event_proxy_write_to_downstream(p); } p->level--; @@ -336,13 +357,13 @@ ngx_log_debug(p->log, "level: %d" _ p->l } -int ngx_event_proxy_write_to_client(ngx_event_proxy_t *p) +int ngx_event_proxy_write_to_downstream(ngx_event_proxy_t *p) { int rc; ngx_hunk_t *h; ngx_chain_t *entry; -ngx_log_debug(p->log, "write to client"); +ngx_log_debug(p->log, "write to downstream"); h = p->busy_hunk; @@ -491,7 +512,7 @@ ngx_log_debug(p->log, "write to file"); do { size += entry->hunk->last - entry->hunk->pos; - if (size >= p->file_block_size) { + if (size >= p->temp_file_write_size) { break; } entry = entry->next; @@ -538,7 +559,11 @@ ngx_log_debug(p->log, "write to file"); ngx_log_debug(p->log, "event proxy file hunk: %08X:%08X" _ h _ h->shadow); if (h->type & NGX_HUNK_LAST_SHADOW) { +#if 0 h->shadow->last = h->shadow->pos; +#else + h->shadow->last = h->shadow->pos = h->shadow->start; +#endif } if (p->out_hunks) { @@ -591,7 +616,7 @@ static int ngx_event_proxy_copy_input_fi ngx_test_null(h, ngx_alloc_hunk(p->pool), NGX_ERROR); ngx_memcpy(h, entry->hunk, sizeof(ngx_hunk_t)); h->shadow = entry->hunk; - h->type |= NGX_HUNK_LAST_SHADOW; + h->type |= NGX_HUNK_LAST_SHADOW|NGX_HUNK_RECYCLED; entry->hunk->shadow = h; ngx_test_null(temp, ngx_alloc_chain_entry(p->pool), NGX_ERROR); diff --git a/src/event/ngx_event_proxy.h b/src/event/ngx_event_proxy.h --- a/src/event/ngx_event_proxy.h +++ b/src/event/ngx_event_proxy.h @@ -20,12 +20,20 @@ typedef int (*ngx_event_proxy_output_fil struct ngx_event_proxy_s { ngx_chain_t *read_hunks; ngx_chain_t *last_read_hunk; + + ngx_chain_t *shadow_hunks; + ngx_chain_t *in_hunks; ngx_chain_t *last_in_hunk; - ngx_chain_t *shadow_hunks; + ngx_chain_t *out_hunks; ngx_chain_t *last_out_hunk; + ngx_chain_t *free_hunks; +#if 0 + ngx_chain_t *last_free_hunk; +#endif + ngx_hunk_t *busy_hunk; ngx_event_proxy_input_filter_pt input_filter; @@ -38,8 +46,8 @@ struct ngx_event_proxy_s { unsigned block_upstream:1; unsigned upstream_eof:1; unsigned upstream_error:1; - unsigned client_eof:1; - unsigned client_error:1; + unsigned downstream_eof:1; + unsigned downstream_error:1; int level; @@ -48,15 +56,21 @@ struct ngx_event_proxy_s { int max_block_size; off_t temp_offset; - off_t max_temp_size; - int file_block_size; + off_t max_temp_file_size; + int temp_file_write_size; ngx_connection_t *upstream; - ngx_connection_t *client; + ngx_connection_t *downstream; ngx_pool_t *pool; ngx_log_t *log; + ngx_chain_t *preread_hunks; +#if 0 + ngx_chain_t *last_preread_hunk; +#endif + int preread_size; + ngx_file_t *temp_file; ngx_path_t *temp_path; int number; @@ -66,7 +80,7 @@ struct ngx_event_proxy_s { int ngx_event_proxy_read_upstream(ngx_event_proxy_t *p); -int ngx_event_proxy_write_to_client(ngx_event_proxy_t *p); +int ngx_event_proxy_write_to_downstream(ngx_event_proxy_t *p); int ngx_event_proxy_write_chain_to_temp_file(ngx_event_proxy_t *p); diff --git a/src/event/ngx_event_timer.c b/src/event/ngx_event_timer.c --- a/src/event/ngx_event_timer.c +++ b/src/event/ngx_event_timer.c @@ -129,7 +129,15 @@ void ngx_event_expire_timers(ngx_msec_t delta -= ev->timer_delta; ngx_del_timer(ev); - ev->timedout = 1; + if (ev->delayed) { + ev->delayed = 0; + if (ev->ready == 0) { + continue; + } + + } else { + ev->timedout = 1; + } if (ev->event_handler(ev) == NGX_ERROR) { ev->close_handler(ev); diff --git a/src/http/modules/proxy/ngx_http_event_proxy_handler.c b/src/http/modules/proxy/ngx_http_event_proxy_handler.c --- a/src/http/modules/proxy/ngx_http_event_proxy_handler.c +++ b/src/http/modules/proxy/ngx_http_event_proxy_handler.c @@ -721,6 +721,11 @@ static int ngx_http_proxy_init_upstream( r = p->request; ngx_test_null(p->header_in, + ngx_create_temp_hunk(r->pool, p->lcf->header_size, 0, 0), + NGX_ERROR); + +#if 0 + ngx_test_null(p->header_in, ngx_create_temp_hunk(r->pool, p->lcf->header_size - sizeof(ngx_cache_header_t), @@ -729,6 +734,7 @@ static int ngx_http_proxy_init_upstream( NGX_ERROR); p->header_in->type = NGX_HUNK_MEMORY|NGX_HUNK_IN_MEMORY; +#endif #if 0 ngx_test_null(p->headers_in, @@ -757,6 +763,7 @@ static int ngx_http_proxy_read_upstream_ { int i, n, rc; ngx_event_t *rev; + ngx_chain_t *temp; ngx_table_elt_t *ch, *ph; ngx_event_proxy_t *ep; ngx_http_request_t *r; @@ -846,7 +853,9 @@ static int ngx_http_proxy_read_upstream_ rc = ngx_http_send_header(r); #if 1 +#if 0 rc = ngx_http_output_filter(r, p->header_in); +#endif ngx_test_null(ep, ngx_pcalloc(r->pool, sizeof(ngx_event_proxy_t)), NGX_ERROR); @@ -856,9 +865,8 @@ static int ngx_http_proxy_read_upstream_ ep->output_data = r; ep->block_size = p->lcf->block_size; ep->max_block_size = p->lcf->max_block_size; - ep->file_block_size = p->lcf->file_block_size; ep->upstream = p->connection; - ep->client = r->connection; + ep->downstream = r->connection; ep->pool = r->pool; ep->log = p->log; ep->temp_path = p->lcf->temp_path; @@ -871,10 +879,21 @@ static int ngx_http_proxy_read_upstream_ ep->number = 10; ep->random = 5; - ep->max_temp_size = p->lcf->max_temp_file_size; + ep->max_temp_file_size = p->lcf->max_temp_file_size; + ep->temp_file_write_size = p->lcf->temp_file_write_size; ep->temp_file_warn = "an upstream response is buffered " "to a temporary file"; + ngx_test_null(ep->preread_hunks, ngx_alloc_chain_entry(r->pool), + NGX_ERROR); + ep->preread_hunks->hunk = p->header_in; + ep->preread_hunks->next = NULL; +#if 0 + ep->last_preread_hunk = ep->preread_hunks; +#endif + + ep->preread_size = p->header_in->last - p->header_in->pos; + p->event_proxy = ep; lcx = p->log->data; @@ -1100,7 +1119,7 @@ static int ngx_http_proxy_read_upstream_ static int ngx_http_proxy_write_upstream_body(ngx_http_proxy_ctx_t *p) { - return ngx_event_proxy_write_to_client(p->event_proxy); + return ngx_event_proxy_write_to_downstream(p->event_proxy); } @@ -1762,18 +1781,18 @@ static void *ngx_http_proxy_create_loc_c conf->connect_timeout = 10000; conf->send_timeout = 10000; conf->read_timeout = 10000; - conf->header_size = 1024; - -#if 0 + conf->header_size = 2048; + +#if 1 conf->block_size = 4096; conf->max_block_size = 4096 * 3; conf->max_temp_file_size = 4096 * 5; - conf->file_block_size = 4096 * 2; + conf->temp_file_write_size = 4096 * 2; #else conf->block_size = 2048; conf->max_block_size = 4096 * 6; conf->max_temp_file_size = 4096 * 5; - conf->file_block_size = 4096 * 5; + conf->temp_file_write_size = 4096 * 5; #endif ngx_test_null(conf->temp_path, ngx_pcalloc(pool, sizeof(ngx_path_t)), NULL); diff --git a/src/http/modules/proxy/ngx_http_event_proxy_handler.h b/src/http/modules/proxy/ngx_http_event_proxy_handler.h --- a/src/http/modules/proxy/ngx_http_event_proxy_handler.h +++ b/src/http/modules/proxy/ngx_http_event_proxy_handler.h @@ -72,7 +72,7 @@ typedef struct { int block_size; int max_block_size; int max_temp_file_size; - int file_block_size; + int temp_file_write_size; ngx_path_t *temp_path; int temp_file_warn; diff --git a/src/http/ngx_http_event.c b/src/http/ngx_http_event.c --- a/src/http/ngx_http_event.c +++ b/src/http/ngx_http_event.c @@ -183,6 +183,7 @@ static int ngx_http_init_request(ngx_eve static int ngx_http_process_request(ngx_event_t *rev) { int n, rc; + ngx_event_t *wev; ngx_connection_t *c; ngx_http_request_t *r; ngx_http_log_ctx_t *lcx; @@ -260,9 +261,16 @@ static int ngx_http_process_request(ngx_ return ngx_http_finalize_request(r, rc); } - lcx = r->connection->log->data; + lcx = c->log->data; lcx->action = "processing client request"; +#if 0 + wev = c->write; + ngx_add_timer(wev, 5000); + wev->delayed = 1; + wev->timer_set = 1; +#endif + rc = ngx_http_handler(r); /* a handler does its own processing */ @@ -657,13 +665,18 @@ int ngx_http_finalize_request(ngx_http_r /* NGX_AGAIN: a handler has done its work but the transfer is still not completed */ + wev = r->connection->write; + wev->event_handler = ngx_http_writer; + + if (wev->delayed && wev->ready) { + return NGX_AGAIN; + } + lcf = (ngx_http_core_loc_conf_t *) ngx_http_get_module_loc_conf(r->main ? r->main : r, ngx_http_core_module_ctx); - wev = r->connection->write; - wev->event_handler = ngx_http_writer; + ngx_add_timer(wev, lcf->send_timeout); wev->timer_set = 1; - ngx_add_timer(wev, lcf->send_timeout); #if (USE_KQUEUE) diff --git a/src/http/ngx_http_write_filter.c b/src/http/ngx_http_write_filter.c --- a/src/http/ngx_http_write_filter.c +++ b/src/http/ngx_http_write_filter.c @@ -134,6 +134,10 @@ int ngx_http_write_filter(ngx_http_reque return NGX_OK; } + if (r->connection->write->delayed) { + return NGX_AGAIN; + } + chain = ngx_write_chain(r->connection, ctx->out, flush); #if (NGX_DEBUG_WRITE_FILTER)