nginx-0.0.1-2003-10-09-11:00:45 import

This commit is contained in:
Igor Sysoev 2003-10-09 07:00:45 +00:00
parent 3ae32483cd
commit 1342d9cc29
10 changed files with 174 additions and 55 deletions

View File

@ -75,6 +75,14 @@ typedef struct {
#define ngx_hunk_in_memory_only(h) \
((h->type & (NGX_HUNK_IN_MEMORY|NGX_HUNK_FILE)) == NGX_HUNK_IN_MEMORY)
/*
((h->type & (NGX_HUNK_TEMP|NGX_HUNK_MEMORY|NGX_HUNK_MMAP|NGX_HUNK_FILE)) \
== (h->type & (NGX_HUNK_TEMP|NGX_HUNK_MEMORY|NGX_HUNK_MMAP)))
*/
#define ngx_hunk_special(h) \
(h->type == (h->type & (NGX_HUNK_FLUSH|NGX_HUNK_LAST)))
ngx_hunk_t *ngx_create_temp_hunk(ngx_pool_t *pool, int size,

View File

@ -39,7 +39,7 @@ static int ngx_http_not_modified_header_filter(ngx_http_request_t *r)
if (r->headers_out.status != NGX_HTTP_OK
|| r->headers_in.if_modified_since == NULL
|| r->headers_out.last_modified_time == NULL)
|| r->headers_out.last_modified_time == -1)
{
return next_header_filter(r);
}
@ -50,7 +50,7 @@ static int ngx_http_not_modified_header_filter(ngx_http_request_t *r)
ngx_log_debug(r->connection->log, "%d %d" _
ims _ r->headers_out.last_modified_time);
/* I think that the date equality is correcter */
/* I think that the equality of the dates is correcter */
if (ims != NGX_ERROR && ims == r->headers_out.last_modified_time) {
r->headers_out.status = NGX_HTTP_NOT_MODIFIED;

View File

@ -118,6 +118,7 @@ int ngx_http_static_handler(ngx_http_request_t *r)
}
/* we need to allocate all before the header would be sent */
ngx_test_null(h, ngx_pcalloc(r->pool, sizeof(ngx_hunk_t)),
NGX_HTTP_INTERNAL_SERVER_ERROR);
@ -132,18 +133,28 @@ int ngx_http_static_handler(ngx_http_request_t *r)
}
if (r->header_only) {
ngx_http_finalize_request(r, rc);
#if 0
if (rc == NGX_AGAIN) {
ngx_http_set_write_handler(r);
} else {
ngx_http_finalize_request(r, 0);
}
#endif
return NGX_OK;
}
h->type = NGX_HUNK_FILE|NGX_HUNK_LAST;
#if 0
h->type = r->main ? NGX_HUNK_FILE : NGX_HUNK_FILE|NGX_HUNK_LAST;
#else
h->type = NGX_HUNK_FILE;
#endif
h->file_pos = 0;
h->file_last = ngx_file_size(r->file.info);
@ -152,6 +163,9 @@ int ngx_http_static_handler(ngx_http_request_t *r)
rc = ngx_http_output_filter(r, h);
ngx_http_finalize_request(r, rc);
#if 0
if (r->main == NULL) {
if (rc == NGX_AGAIN) {
ngx_http_set_write_handler(r);
@ -160,6 +174,7 @@ int ngx_http_static_handler(ngx_http_request_t *r)
ngx_http_finalize_request(r, 0);
}
}
#endif
return NGX_OK;
}

View File

@ -54,6 +54,7 @@ void ngx_http_finalize_request(ngx_http_request_t *r, int error);
void ngx_http_set_write_handler(ngx_http_request_t *r);
int ngx_http_send_last(ngx_http_request_t *r);
void ngx_http_close_request(ngx_http_request_t *r, int error);
void ngx_http_close_connection(ngx_connection_t *c);

View File

@ -72,10 +72,11 @@ ngx_module_t ngx_http_output_filter_module = {
#define ngx_next_filter (*ngx_http_top_body_filter)
#define need_to_copy(r, hunk) \
(((r->filter & NGX_HTTP_FILTER_NEED_IN_MEMORY) \
(!ngx_hunk_special(hunk) \
&& (((r->filter & NGX_HTTP_FILTER_NEED_IN_MEMORY) \
&& (hunk->type & NGX_HUNK_IN_MEMORY) == 0) \
|| ((r->filter & NGX_HTTP_FILTER_NEED_TEMP) \
&& (hunk->type & (NGX_HUNK_MEMORY|NGX_HUNK_MMAP))))
&& (hunk->type & (NGX_HUNK_MEMORY|NGX_HUNK_MMAP)))))
@ -201,6 +202,8 @@ int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
*ctx->last_out = ce;
ctx->last_out = &ce->next;
ctx->hunk = NULL;
break;
}
if (ctx->out == NULL && last != NGX_NONE) {

View File

@ -785,6 +785,10 @@ void ngx_http_finalize_request(ngx_http_request_t *r, int error)
int rc;
ngx_event_t *rev, *wev;
if (r->main) {
return;
}
rc = error;
if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
@ -813,9 +817,25 @@ void ngx_http_finalize_request(ngx_http_request_t *r, int error)
return;
}
#if 1
return;
#endif
} else if (rc == NGX_ERROR) {
r->keepalive = 0;
r->lingering_close = 0;
} else {
if (ngx_http_send_last(r) == NGX_ERROR) {
ngx_http_close_request(r, 0);
ngx_http_close_connection(r->connection);
return;
}
if (rc == NGX_AGAIN) {
ngx_http_set_write_handler(r);
return;
}
}
rev = r->connection->read;
@ -840,6 +860,8 @@ void ngx_http_finalize_request(ngx_http_request_t *r, int error)
ngx_http_close_request(r, 0);
ngx_http_close_connection(r->connection);
}
return;
}
@ -887,6 +909,8 @@ void ngx_http_set_write_handler(ngx_http_request_t *r)
ngx_http_close_request(r, 0);
ngx_http_close_connection(r->connection);
}
return;
}
@ -951,6 +975,8 @@ static void ngx_http_writer(ngx_event_t *wev)
ngx_http_close_request(r, 0);
ngx_http_close_connection(r->connection);
}
return;
}
@ -1046,6 +1072,8 @@ static void ngx_http_read_discarded_body_event(ngx_event_t *rev)
ngx_http_close_request(r, rc);
ngx_http_close_connection(c);
}
return;
}
@ -1385,6 +1413,17 @@ static void ngx_http_empty_handler(ngx_event_t *wev)
}
int ngx_http_send_last(ngx_http_request_t *r)
{
ngx_hunk_t *h;
ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR);
h->type = NGX_HUNK_LAST;
return ngx_http_output_filter(r, h);
}
void ngx_http_close_request(ngx_http_request_t *r, int error)
{
ngx_http_log_ctx_t *ctx;

View File

@ -199,15 +199,19 @@ int ngx_http_special_response_handler(ngx_http_request_t *r, int error)
}
rc = ngx_http_send_header(r);
if (rc == NGX_ERROR) {
return NGX_ERROR;
}
if (r->header_only) {
ngx_http_finalize_request(r, rc);
#if 0
if (rc == NGX_AGAIN) {
ngx_http_set_write_handler(r);
return NGX_AGAIN;
}
#endif
return NGX_OK;
}
@ -248,12 +252,16 @@ int ngx_http_special_response_handler(ngx_http_request_t *r, int error)
rc = ngx_http_output_filter(r, h);
ngx_http_finalize_request(r, rc);
#if 0
if (r->main == NULL) {
if (rc == NGX_AGAIN) {
ngx_http_set_write_handler(r);
return NGX_AGAIN;
}
}
#endif
return NGX_OK;

View File

@ -130,14 +130,16 @@ int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
last _ flush _ size);
#endif
/* avoid the output if there is no last hunk, no flush point and
size of the hunks is smaller then "buffer_output" */
/*
* avoid the output if there is no last hunk, no flush point and
* size of the hunks is smaller then "buffer_output"
*/
if (!last && flush == 0 && size < conf->buffer_output) {
return NGX_OK;
}
if (r->connection->write->delayed) {
if (!r->connection->write->ready || r->connection->write->delayed) {
return NGX_AGAIN;
}

View File

@ -93,26 +93,30 @@ int ngx_os_init(ngx_log_t *log)
#if (HAVE_FREEBSD_SENDFILE)
/* The determination of the sendfile() nbytes bug is complex enough.
There're two sendfile() syscalls: a new 393 has no bug while
an old 336 has the bug in some versions and has not in others.
Besides libc_r wrapper also emulates the bug in some versions.
There's no way to say exactly if a given FreeBSD version has bug.
Here is the algorithm that works at least for RELEASEs
and for syscalls only (not libc_r wrapper). */
/* detect the new sendfile() version available at the compile time
to allow an old binary to run correctly on an updated FreeBSD system. */
/*
* The determination of the sendfile() nbytes bug is complex enough.
* There're two sendfile() syscalls: a new 393 has no bug while
* an old 336 has the bug in some versions and has not in others.
* Besides libc_r wrapper also emulates the bug in some versions.
* There's no way to say exactly if a given FreeBSD version has the bug.
* Here is the algorithm that works at least for RELEASEs
* and for syscalls only (not libc_r wrapper).
*
* We detect the new sendfile() version available at the compile time
* to allow an old binary to run correctly on an updated FreeBSD system.
*/
#if (__FreeBSD__ == 4 && __FreeBSD_version >= 460102) \
|| __FreeBSD_version == 460002 || __FreeBSD_version >= 500039
/* a new syscall without the bug */
ngx_freebsd_sendfile_nbytes_bug = 0;
#else
/* an old syscall that can have the bug */
ngx_freebsd_sendfile_nbytes_bug = 1;
#endif

View File

@ -1,22 +1,23 @@
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_event.h>
#include <ngx_freebsd_init.h>
/*
sendfile() often sends 4K pages over ethernet in 3 packets: 2x1460 and 1176
or in 6 packets: 5x1460 and 892. Besides although sendfile() allows
to pass the header and the trailer it never sends the header or the trailer
with the part of the file in one packet. So we use TCP_NOPUSH (similar
to Linux's TCP_CORK) to postpone the sending - it not only sends the header
and the first part of the file in one packet but also sends 4K pages
in the full packets.
Until FreeBSD 4.5 the turning TCP_NOPUSH off does not not flush
the pending data that less than MSS and the data sent with 5 second delay.
So we use TCP_NOPUSH on FreeBSD prior to 4.5 only if the connection
is not needed not keepalive.
* sendfile() often sends 4K pages over ethernet in 3 packets: 2x1460 and 1176
* or in 6 packets: 5x1460 and 892. Besides although sendfile() allows
* to pass the header and the trailer it never sends the header or the trailer
* with the part of the file in one packet. So we use TCP_NOPUSH (similar
* to Linux's TCP_CORK) to postpone the sending - it not only sends the header
* and the first part of the file in one packet but also sends 4K pages
* in the full packets.
*
* Until FreeBSD 4.5 the turning TCP_NOPUSH off does not not flush
* the pending data that less than MSS and the data sent with 5 second delay.
* So we use TCP_NOPUSH on FreeBSD prior to 4.5 only if the connection
* is not needed to be keepalive.
*/
@ -47,12 +48,23 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
NGX_CHAIN_ERROR);
/* create the header iovec */
if (ngx_hunk_in_memory_only(ce->hunk)) {
#if 0
if (ngx_hunk_in_memory_only(ce->hunk) || ngx_hunk_special(ce->hunk)) {
#endif
prev = NULL;
iov = NULL;
/* create the iovec and coalesce the neighbouring chain entries */
while (ce && ngx_hunk_in_memory_only(ce->hunk)) {
for ( /* void */; ce; ce = ce->next) {
if (ngx_hunk_special(ce->hunk)) {
continue;
}
if (!ngx_hunk_in_memory_only(ce->hunk)) {
break;
}
if (prev == ce->hunk->pos) {
iov->iov_len += ce->hunk->last - ce->hunk->pos;
@ -67,24 +79,39 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
}
hsize += ce->hunk->last - ce->hunk->pos;
ce = ce->next;
}
#if 0
}
#endif
/* TODO: coalesce the neighbouring file hunks */
if (ce && (ce->hunk->type & NGX_HUNK_FILE)) {
file = ce->hunk;
ce = ce->next;
}
/* create the trailer iovec */
if (ce && ngx_hunk_in_memory_only(ce->hunk)) {
#if 0
if (ce
&& (ngx_hunk_in_memory_only(ce->hunk)
|| ngx_hunk_special(ce->hunk)))
{
#endif
prev = NULL;
iov = NULL;
/* create the iovec and coalesce the neighbouring chain entries */
while (ce && ngx_hunk_in_memory_only(ce->hunk)) {
for ( /* void */; ce; ce = ce->next) {
if (ngx_hunk_special(ce->hunk)) {
continue;
}
if (!ngx_hunk_in_memory_only(ce->hunk)) {
break;
}
if (prev == ce->hunk->pos) {
iov->iov_len += ce->hunk->last - ce->hunk->pos;
@ -97,10 +124,10 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
iov->iov_len = ce->hunk->last - ce->hunk->pos;
prev = ce->hunk->last;
}
ce = ce->next;
}
#if 0
}
#endif
tail = ce;
@ -155,19 +182,23 @@ ngx_log_debug(c->log, "NOPUSH");
#endif
} else {
if (hsize) {
rc = writev(c->fd, (struct iovec *) header.elts, header.nelts);
if (rc == -1) {
err = ngx_errno;
if (err == NGX_EAGAIN) {
ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EAGAIN");
ngx_log_error(NGX_LOG_INFO, c->log, err,
"writev() EAGAIN");
} else if (err == NGX_EINTR) {
eintr = 1;
ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EINTR");
ngx_log_error(NGX_LOG_INFO, c->log, err,
"writev() EINTR");
} else {
ngx_log_error(NGX_LOG_CRIT, c->log, err, "writev() failed");
ngx_log_error(NGX_LOG_CRIT, c->log, err,
"writev() failed");
return NGX_CHAIN_ERROR;
}
}
@ -177,6 +208,10 @@ ngx_log_debug(c->log, "NOPUSH");
#if (NGX_DEBUG_WRITE_CHAIN)
ngx_log_debug(c->log, "writev: %qd" _ sent);
#endif
} else {
sent = 0;
}
}
c->sent += sent;
@ -221,5 +256,9 @@ ngx_log_debug(c->log, "NOPUSH");
} while ((tail && tail == ce) || eintr);
if (ce) {
c->write->ready = 0;
}
return ce;
}