nginx-0.0.1-2003-02-11-10:14:40 import

This commit is contained in:
Igor Sysoev 2003-02-11 07:14:40 +00:00
parent 7300977320
commit 1e7ec9dcd2
16 changed files with 468 additions and 108 deletions

View File

@ -66,13 +66,21 @@ int ngx_kqueue_init(int max_connections, ngx_log_t *log)
ngx_event_actions.timer = ngx_event_add_timer; ngx_event_actions.timer = ngx_event_add_timer;
ngx_event_actions.process = ngx_kqueue_process_events; ngx_event_actions.process = ngx_kqueue_process_events;
#if (HAVE_AIO_EVENT)
ngx_event_flags = NGX_HAVE_AIO_EVENT;
#else
ngx_event_flags = NGX_HAVE_LEVEL_EVENT ngx_event_flags = NGX_HAVE_LEVEL_EVENT
|NGX_HAVE_ONESHOT_EVENT |NGX_HAVE_ONESHOT_EVENT
#if (HAVE_AIO_EVENT) #if (HAVE_CLEAR_EVENT)
|NGX_HAVE_AIO_EVENT; |NGX_HAVE_CLEAR_EVENT
#else
|NGX_HAVE_CLEAR_EVENT;
#endif #endif
|NGX_HAVE_KQUEUE_EVENT;
#endif
#endif #endif
return NGX_OK; return NGX_OK;

View File

@ -214,6 +214,8 @@ int ngx_poll_process_events(ngx_log_t *log)
if (event_list[i].revents & (POLLERR|POLLHUP|POLLNVAL)) { if (event_list[i].revents & (POLLERR|POLLHUP|POLLNVAL)) {
found = 1; found = 1;
/* need ot add to ready_index[nready++] = c->read or c->write; */
err = 0; err = 0;
if (event_list[i].revents & POLLNVAL) { if (event_list[i].revents & POLLNVAL) {
err = EBADF; err = EBADF;

View File

@ -0,0 +1,117 @@
int ngx_sigio_add_event(ngx_event_t *ev, int signal)
{
ngx_connection_t *c;
c = (ngx_connection_t *) ev->data;
if (fcntl(c->fd, F_SETFL, O_RDWR|O_NONBLOCK|O_ASYNC) == -1) {
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
"fcntl(O_RDWR|O_NONBLOCK|O_ASYNC) failed");
return NGX_ERROR;
}
if (fcntl(c->fd, F_SETSIG, signal) == -1) {
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
"fcntl(F_SETSIG) failed");
return NGX_ERROR;
}
if (fcntl(c->fd, F_SETOWN, pid) == -1) {
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
"fcntl(F_SETOWN) failed");
return NGX_ERROR;
}
#if (HAVE_ONESIGFD)
if (fcntl(c->fd, F_SETAUXFL, O_ONESIGFD) == -1) {
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
"fcntl(F_SETAUXFL) failed");
return NGX_ERROR;
}
#endif
return NGX_OK;
}
int ngx_sigio_process_events(ngx_log_t *log)
{
struct siginfo si;
for ( ;; ) {
if (timer) {
sig = sigtimedwait(&sigio_set, &si, &ts);
if (sig == -1) {
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
"sigtimedwait() failed");
continue;
}
}
} else {
sig = sigwaitinfo(&set, &si);
if (sig == -1) {
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
"sigwaitinfo() failed");
}
}
if (sig == rtsig) {
c = &ngx_connections[si.si_fd];
if (si.si_band & (POLLERR|POLLHUP|POLLNVAL)) {
ev = ???;
if (ev->active) {
ev->ready = 1;
if (ev->event_handler(ev) == NGX_ERROR) {
ev->close_handler(ev);
}
}
}
if (si.si_band & (POLLIN)) {
ev = c->read;
if (ev->active) {
ev->ready = 1;
if (ev->event_handler(ev) == NGX_ERROR) {
ev->close_handler(ev);
}
}
}
if (si.si_band & (POLLOUT)) {
ev = c->write;
if (ev->active) {
ev->ready = 1;
if (ev->event_handler(ev) == NGX_ERROR) {
ev->close_handler(ev);
}
}
}
} else if (sig == SIGIO) {
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
"Signal queue overflowed: "
"SIGIO, fd:%d, band:%d", si.si_fd, si.si_band);
/* flush queue: method #1 (dphttpd) */
ts.tv_sec = 0;
ts.tv_nsec = 0;
while (sigtimedwait(&sigio_set, &si, &ts) > 0);
/* flush queue: method #2 (dkftpbench) */
signal(m_signum, SIG_IGN);
signal(m_signum, SIG_DFL);
/* do poll */
} else {
}
}
}

View File

@ -36,31 +36,7 @@ ngx_event_t *ngx_read_events, *ngx_write_events;
#if !(USE_KQUEUE) #if !(USE_KQUEUE)
#if (HAVE_KQUEUE) ngx_event_type_e ngx_event_type;
#if 0
ngx_event_type_e ngx_event_type = NGX_SELECT_EVENT;
#elif 0
ngx_event_type_e ngx_event_type = NGX_POLL_EVENT;
#else
ngx_event_type_e ngx_event_type = NGX_KQUEUE_EVENT;
#endif
#elif (HAVE_DEVPOLL)
#if 0
ngx_event_type_e ngx_event_type = NGX_SELECT_EVENT;
#elif 0
ngx_event_type_e ngx_event_type = NGX_POLL_EVENT;
#else
ngx_event_type_e ngx_event_type = NGX_DEVPOLL_EVENT;
#endif
#else
ngx_event_type_e ngx_event_type = NGX_SELECT_EVENT;
#endif
int ngx_event_flags; int ngx_event_flags;
@ -97,8 +73,17 @@ void ngx_pre_thread(ngx_array_t *ls, ngx_pool_t *pool, ngx_log_t *log)
/* STUB */ /* STUB */
int max_connections = 512; int max_connections = 512;
#if (HAVE_IOCP) #if 0
ngx_event_type = NGX_IOCP_EVENT; ngx_event_type = NGX_POLL_EVENT_N;
#endif
#if 1
ngx_event_type = NGX_KQUEUE_EVENT_N;
#endif
#if 0
ngx_event_type = NGX_DEVPOLL_EVENT_N;
#endif
#if 0
ngx_event_type = NGX_IOCP_EVENT_N;
#endif #endif
if (ngx_init_events(max_connections, log) == NGX_ERROR) { if (ngx_init_events(max_connections, log) == NGX_ERROR) {

View File

@ -106,20 +106,20 @@ struct ngx_event_s {
}; };
typedef enum { typedef enum {
NGX_SELECT_EVENT = 0, NGX_SELECT_EVENT_N = 0,
#if (HAVE_POLL) #if (HAVE_POLL)
NGX_POLL_EVENT, NGX_POLL_EVENT_N,
#endif #endif
#if (HAVE_DEVPOLL) #if (HAVE_DEVPOLL)
NGX_DEVPOLL_EVENT, NGX_DEVPOLL_EVENT_N,
#endif #endif
#if (HAVE_KQUEUE) #if (HAVE_KQUEUE)
NGX_KQUEUE_EVENT, NGX_KQUEUE_EVENT_N,
#endif #endif
#if (HAVE_IOCP) #if (HAVE_IOCP)
NGX_IOCP_EVENT, NGX_IOCP_EVENT_N,
#endif #endif
NGX_DUMMY_EVENT /* avoid comma at end of enumerator list */ NGX_DUMMY_EVENT_N /* avoid comma at end of enumerator list */
} ngx_event_type_e ; } ngx_event_type_e ;
typedef struct { typedef struct {
@ -145,15 +145,21 @@ typedef struct {
/* Event filter notifies only changes and initial level - kqueue */ /* Event filter notifies only changes and initial level - kqueue */
#define NGX_HAVE_CLEAR_EVENT 4 #define NGX_HAVE_CLEAR_EVENT 4
/* Event filter has kqueue features - eof flag, errno, available data, etc */
#define NGX_HAVE_KQUEUE_EVENT 8
/* Event filter notifies only changes (edgesi) but not initial level - epoll */ /* Event filter notifies only changes (edgesi) but not initial level - epoll */
#define NGX_HAVE_EDGE_EVENT 8 #define NGX_HAVE_EDGE_EVENT 16
/* No need to add or delete event filters - rt signals */
#define NGX_HAVE_SIGIO_EVENT 32
/* No need to add or delete event filters - overlapped, aio_read, aioread */ /* No need to add or delete event filters - overlapped, aio_read, aioread */
#define NGX_HAVE_AIO_EVENT 16 #define NGX_HAVE_AIO_EVENT 64
/* Need to add socket or halde only once - i/o completion port. /* Need to add socket or halde only once - i/o completion port.
It also requires to set HAVE_AIO_EVENT and NGX_HAVE_AIO_EVENT */ It also requires to set HAVE_AIO_EVENT and NGX_HAVE_AIO_EVENT */
#define NGX_HAVE_IOCP_EVENT 32 #define NGX_HAVE_IOCP_EVENT 128
/* Event filter is deleted before closing file. Has no meaning /* Event filter is deleted before closing file. Has no meaning
for select, poll, epoll. for select, poll, epoll.

View File

@ -156,7 +156,7 @@ int ngx_event_accept(ngx_event_t *ev)
#elif (HAVE_KQUEUE) #elif (HAVE_KQUEUE)
if (ngx_event_type == NGX_KQUEUE_EVENT) { if (ngx_event_type == NGX_HAVE_KQUEUE_EVENT) {
ev->available--; ev->available--;
} }

View File

@ -29,7 +29,7 @@ int ngx_event_acceptex(ngx_event_t *ev)
return NGX_OK; return NGX_OK;
} }
GetAcceptExSockaddrs(c->data, 0, getacceptexsockaddrs(c->data, 0,
c->socklen + 16, c->socklen + 16, c->socklen + 16, c->socklen + 16,
&c->local_sockaddr, &c->local_socklen, &c->local_sockaddr, &c->local_socklen,
&c->sockaddr, &c->socklen); &c->sockaddr, &c->socklen);
@ -130,7 +130,7 @@ int ngx_event_post_acceptex(ngx_listen_t *ls, int n)
return NGX_ERROR; return NGX_ERROR;
} }
if (AcceptEx(ls->fd, s, c->data, 0, if (acceptex(ls->fd, s, c->data, 0,
c->socklen + 16, c->socklen + 16, c->socklen + 16, c->socklen + 16,
&rcvd, (LPOVERLAPPED) &rev->ovlp) == 0) { &rcvd, (LPOVERLAPPED) &rev->ovlp) == 0) {

View File

@ -36,7 +36,7 @@ ssize_t ngx_event_recv_core(ngx_connection_t *c, char *buf, size_t size)
#elif (HAVE_KQUEUE) #elif (HAVE_KQUEUE)
if (ngx_event_type == NGX_KQUEUE_EVENT) { if (ngx_event_type == NGX_HAVE_KQUEUE_EVENT) {
if (c->read->eof && c->read->available == 0) { if (c->read->eof && c->read->available == 0) {
if (c->read->error) { if (c->read->error) {
ngx_log_error(NGX_LOG_ERR, c->log, c->read->error, ngx_log_error(NGX_LOG_ERR, c->log, c->read->error,
@ -70,7 +70,7 @@ ssize_t ngx_event_recv_core(ngx_connection_t *c, char *buf, size_t size)
#elif (HAVE_KQUEUE) #elif (HAVE_KQUEUE)
if (ngx_event_type == NGX_KQUEUE_EVENT) { if (ngx_event_type == NGX_HAVE_KQUEUE_EVENT) {
c->read->available -= n; c->read->available -= n;
} }

View File

@ -437,7 +437,7 @@ static int ngx_http_proxy_read_response_body(ngx_event_t *ev)
#elif (HAVE_KQUEUE) #elif (HAVE_KQUEUE)
if (ngx_event_type == NGX_KQUEUE_EVENT) { if (ngx_event_type == NGX_HAVE_KQUEUE_EVENT) {
/* do not allocate new block if there is EOF */ /* do not allocate new block if there is EOF */
if (ev->eof && ev->available == 0) { if (ev->eof && ev->available == 0) {
left = 1; left = 1;

View File

@ -163,6 +163,9 @@ struct ngx_http_request_s {
unsigned unusual_uri:1; /* URI is not started with '/' - "GET http://" */ unsigned unusual_uri:1; /* URI is not started with '/' - "GET http://" */
unsigned complex_uri:1; /* URI with "/." or with "//" (WIN32) */ unsigned complex_uri:1; /* URI with "/." or with "//" (WIN32) */
unsigned path_not_found:1; unsigned path_not_found:1;
#ifdef NGX_EVENT
unsigned write_level_event:1;
#endif
int state; int state;
char *uri_start; char *uri_start;

View File

@ -101,10 +101,10 @@ int ngx_http_handler(ngx_http_request_t *r)
r->connection->unexpected_eof = 0; r->connection->unexpected_eof = 0;
r->lingering_close = 0; r->lingering_close = 1;
r->keepalive = 0; r->keepalive = 1;
#if 0 #if 1
r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY; r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY;
#endif #endif

View File

@ -30,6 +30,7 @@ static int ngx_http_event_request_handler(ngx_http_request_t *r);
static int ngx_http_writer(ngx_event_t *ev); static int ngx_http_writer(ngx_event_t *ev);
static int ngx_http_block_read(ngx_event_t *ev); static int ngx_http_block_read(ngx_event_t *ev);
static int ngx_http_read_discarded_body(ngx_event_t *ev); static int ngx_http_read_discarded_body(ngx_event_t *ev);
static int ngx_http_set_keepalive(ngx_http_request_t *r);
static int ngx_http_keepalive_handler(ngx_event_t *ev); static int ngx_http_keepalive_handler(ngx_event_t *ev);
static int ngx_http_set_lingering_close(ngx_http_request_t *r); static int ngx_http_set_lingering_close(ngx_http_request_t *r);
static int ngx_http_lingering_close_handler(ngx_event_t *ev); static int ngx_http_lingering_close_handler(ngx_event_t *ev);
@ -112,10 +113,11 @@ int ngx_http_init_connection(ngx_connection_t *c)
#endif #endif
/* THINK: should ngx_edge_add_event() be moved to accept part ? */
#if (HAVE_EDGE_EVENT) /* epoll */ #if (HAVE_EDGE_EVENT) /* epoll */
if (ngx_event_flags & NGX_HAVE_EDGE_EVENT) { if (ngx_event_flags & NGX_HAVE_EDGE_EVENT) {
if (ngx_add_event(ev, NGX_READ_EVENT, NGX_EDGE_EVENT) == NGX_ERROR) { if (ngx_edge_add_event(ev) == NGX_ERROR) {
return NGX_ERROR; return NGX_ERROR;
} }
return ngx_http_init_request(ev); return ngx_http_init_request(ev);
@ -129,7 +131,7 @@ int ngx_http_init_connection(ngx_connection_t *c)
return ngx_http_init_request(ev); return ngx_http_init_request(ev);
} }
#endif /* HAVE_AIO_EVENT */ #endif
/* select, poll, /dev/poll */ /* select, poll, /dev/poll */
@ -498,9 +500,9 @@ static int ngx_http_event_request_handler(ngx_http_request_t *r)
#else #else
#if (HAVE_AIO_EVENT) /* aio, iocp */ #if (HAVE_AIO_EVENT) || (HAVE_EDGE_EVENT) /* aio, iocp, epoll */
if (ngx_event_flags & NGX_HAVE_AIO_EVENT) { if (ngx_event_flags & (NGX_HAVE_AIO_EVENT|NGX_HAVE_EDGE_EVENT)) {
return rc; return rc;
} }
@ -512,30 +514,14 @@ static int ngx_http_event_request_handler(ngx_http_request_t *r)
event = NGX_CLEAR_EVENT; event = NGX_CLEAR_EVENT;
} else { } else {
event = NGX_ONESHOT_EVENT;
}
#elif (HAVE_EDGE_EVENT) /* epoll */
if (ngx_event_flags & NGX_HAVE_EDGE_EVENT) {
event = NGX_EDGE_EVENT;
} else {
event = NGX_ONESHOT_EVENT;
}
#elif (HAVE_DEVPOLL_EVENT) /* /dev/poll */
if (ngx_event_flags & NGX_HAVE_LEVEL_EVENT) {
event = NGX_LEVEL_EVENT; event = NGX_LEVEL_EVENT;
r->write_level_event = 1;
} else {
event = NGX_ONESHOT_EVENT;
} }
#else /* select, poll */ #else /* select, poll, /dev/poll */
event = NGX_ONESHOT_EVENT; event = NGX_LEVEL_EVENT;
r->write_level_event = 1;
#endif #endif
@ -571,13 +557,7 @@ static int ngx_http_event_request_handler(ngx_http_request_t *r)
/* keepalive */ /* keepalive */
r->connection->buffer->pos.mem = r->connection->buffer->last.mem return ngx_http_set_keepalive(r);
= r->connection->buffer->start;
rev->event_handler = ngx_http_keepalive_handler;
ngx_http_close_request(r);
return NGX_OK;
} }
@ -617,14 +597,6 @@ static int ngx_http_writer(ngx_event_t *ev)
ngx_add_timer(ev, timeout); ngx_add_timer(ev, timeout);
} }
/* TODO: /dev/poll, epoll, aio_write */
if (ev->oneshot)
if (ngx_add_event(ev, NGX_WRITE_EVENT, NGX_ONESHOT_EVENT)
== NGX_ERROR) {
return ngx_http_close_request(r);
}
return rc; return rc;
} }
@ -646,15 +618,11 @@ static int ngx_http_writer(ngx_event_t *ev)
/* keepalive */ /* keepalive */
c->buffer->pos.mem = c->buffer->last.mem = c->buffer->start; return ngx_http_set_keepalive(r);
c->read->event_handler = ngx_http_keepalive_handler;
ngx_http_close_request(r);
return NGX_OK;
} }
/* TODO */
static int ngx_http_block_read(ngx_event_t *ev) static int ngx_http_block_read(ngx_event_t *ev)
{ {
ngx_log_debug(ev->log, "http read blocked"); ngx_log_debug(ev->log, "http read blocked");
@ -693,6 +661,7 @@ static int ngx_http_block_read(ngx_event_t *ev)
} }
/* TODO */
int ngx_http_discard_body(ngx_http_request_t *r) int ngx_http_discard_body(ngx_http_request_t *r)
{ {
ngx_event_t *ev; ngx_event_t *ev;
@ -716,6 +685,7 @@ int ngx_http_discard_body(ngx_http_request_t *r)
} }
/* TODO */
static int ngx_http_read_discarded_body(ngx_event_t *ev) static int ngx_http_read_discarded_body(ngx_event_t *ev)
{ {
size_t size; size_t size;
@ -757,6 +727,34 @@ static int ngx_http_read_discarded_body(ngx_event_t *ev)
} }
/* TODO: if c->read->blocked */
static int ngx_http_set_keepalive(ngx_http_request_t *r)
{
ngx_connection_t *c;
c = (ngx_connection_t *) r->connection;
c->buffer->pos.mem = c->buffer->last.mem = c->buffer->start;
c->read->event_handler = ngx_http_keepalive_handler;
if (r->write_level_event) {
if (ngx_del_event(c->write, NGX_WRITE_EVENT, 0) == NGX_ERROR) {
return NGX_ERROR;
}
}
ngx_http_close_request(r);
#if (HAVE_AIO_EVENT) /* aio, iocp */
if (ngx_event_flags & NGX_HAVE_AIO_EVENT) {
return ngx_http_keepalive_handler(c->read);
}
#endif
return NGX_OK;
}
static int ngx_http_keepalive_handler(ngx_event_t *ev) static int ngx_http_keepalive_handler(ngx_event_t *ev)
{ {
ssize_t n; ssize_t n;
@ -796,8 +794,10 @@ static int ngx_http_keepalive_handler(ngx_event_t *ev)
static int ngx_http_set_lingering_close(ngx_http_request_t *r) static int ngx_http_set_lingering_close(ngx_http_request_t *r)
{ {
ngx_event_t *ev; ngx_event_t *ev;
ngx_connection_t *c;
ngx_http_core_loc_conf_t *lcf; ngx_http_core_loc_conf_t *lcf;
c = r->connection;
ev = r->connection->read; ev = r->connection->read;
lcf = (ngx_http_core_loc_conf_t *) lcf = (ngx_http_core_loc_conf_t *)
@ -832,8 +832,22 @@ static int ngx_http_set_lingering_close(ngx_http_request_t *r)
return ngx_http_close_request(r); return ngx_http_close_request(r);
} }
#if (HAVE_AIO_EVENT) /* aio, iocp */
if (ngx_event_flags & NGX_HAVE_AIO_EVENT) {
return ngx_http_lingering_close_handler(ev);
}
#endif
#if (HAVE_CLEAR_EVENT) || (HAVE_EDGE_EVENT) /* kqueue, epoll */
if (ngx_event_flags & (NGX_HAVE_CLEAR_EVENT|NGX_HAVE_EDGE_EVENT)) {
return NGX_OK; return NGX_OK;
} }
#endif
/* select, poll, /dev/poll */
return ngx_del_event(c->write, NGX_WRITE_EVENT, 0);
}
static int ngx_http_lingering_close_handler(ngx_event_t *ev) static int ngx_http_lingering_close_handler(ngx_event_t *ev)

View File

@ -57,6 +57,224 @@ ngx_module_t ngx_http_output_filter_module = {
}; };
#if 1
#define next_filter ngx_http_output_filter_module_ctx.next_output_body_filter
#define need_to_copy(r, hunk) \
(((r->filter & NGX_HTTP_FILTER_NEED_IN_MEMORY) \
&& (hunk->type & NGX_HUNK_FILE)) \
|| ((r->filter & NGX_HTTP_FILTER_NEED_TEMP) \
&& (hunk->type & (NGX_HUNK_MEMORY|NGX_HUNK_MMAP))))
int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
{
int rc;
size_t size;
ngx_chain_t *ce, *pe;
ngx_http_output_filter_ctx_t *ctx;
ngx_http_output_filter_conf_t *conf;
ctx = (ngx_http_output_filter_ctx_t *)
ngx_http_get_module_ctx(r->main ? r->main : r,
ngx_http_output_filter_module);
if (ctx == NULL) {
ngx_http_create_ctx(r, ctx, ngx_http_output_filter_module,
sizeof(ngx_http_output_filter_ctx_t));
}
/* the incoming chain ctx->in is empty */
if (ctx->in == NULL) {
if (hunk == NULL) {
return next_filter(r, NULL);
}
/* we do not need to copy the incoming hunk to our hunk */
if (!need_to_copy(r, hunk)) {
ctx->out.hunk = hunk;
ctx->out.next = NULL;
return next_filter(r, &ctx->out);
}
/* we need to copy the incoming hunk to our hunk */
/* allocate ctx->hunk if it's needed */
if (ctx->hunk == NULL) {
conf = (ngx_http_output_filter_conf_t *)
ngx_http_get_module_loc_conf(r->main ? r->main : r,
ngx_http_output_filter_module);
if (hunk->type & NGX_HUNK_LAST) {
size = hunk->last.mem - hunk->pos.mem;
if (size > conf->hunk_size) {
size = conf->hunk_size;
}
} else {
size = conf->hunk_size;
}
ngx_test_null(ctx->hunk,
ngx_create_temp_hunk(r->pool, size, 50, 50),
NGX_ERROR);
ctx->hunk->type |= NGX_HUNK_RECYCLED;
}
/* copy the incoming hunk or its part to our hunk
and pass it to the next filter */
do {
rc = ngx_http_output_filter_copy_hunk(ctx->hunk, hunk);
if (rc == NGX_ERROR) {
return rc;
}
#if (NGX_FILE_AIO_READ)
if (rc == NGX_AGAIN) {
/* add the incoming hunk to the incoming chain */
ngx_add_hunk_to_chain(ctx->in, hunk, r->pool, NGX_ERROR);
return rc;
}
#endif
ctx->out.hunk = ctx->hunk;
ctx->out.next = NULL;
rc = next_filter(r, &ctx->out);
if (rc == NGX_ERROR) {
return rc;
}
if (rc == NGX_AGAIN) {
/* add the incoming hunk to the incoming chain */
ngx_add_hunk_to_chain(ctx->in, hunk, r->pool, NGX_ERROR);
return rc;
}
/* NGX_OK */
/* set our hunk free */
ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
/* repeat until we will have copied the whole incoming hunk */
} while (hunk->pos.mem < hunk->last.mem);
return NGX_OK;
}
/* the incoming chain ctx->in is not empty */
/* add the incoming hunk to the incoming chain */
if (hunk) {
for (ce = ctx->in; ce->next; ce = ce->next) {
/* void */ ;
}
ngx_add_hunk_to_chain(ce->next, hunk, r->pool, NGX_ERROR);
}
/* our hunk is still busy */
if (ctx->hunk->pos.mem < ctx->hunk->last.mem) {
rc = next_filter(r, NULL);
if (rc == NGX_ERROR || rc == NGX_AGAIN) {
return rc;
}
/* NGX_OK */
ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
}
#if (NGX_SUPPRESS_WARN)
pe = NULL;
#endif
/* process the incoming chain ctx->in */
do {
/* find the hunks that do not need to be copied ... */
for (ce = ctx->in; ce; ce = ce->next) {
if (need_to_copy(r, ce->hunk)) {
break;
}
pe = ce;
}
/* ... and pass them to the next filter */
if (ctx->in != ce) {
ctx->out.hunk = ctx->in->hunk;
ctx->out.next = ctx->in->next;
ctx->in = ce;
pe->next = NULL;
rc = next_filter(r, &ctx->out);
if (rc == NGX_ERROR || rc == NGX_AGAIN) {
return rc;
}
/* NGX_OK */
if (ctx->in == NULL) {
return rc;
}
}
/* copy the first hunk or its part from the incoming chain ctx->in
to our hunk and pass it to the next filter */
do {
rc = ngx_http_output_filter_copy_hunk(ctx->hunk, ctx->in->hunk);
if (rc == NGX_ERROR) {
return rc;
}
#if (NGX_FILE_AIO_READ)
if (rc == NGX_AGAIN) {
return rc;
}
#endif
ctx->out.hunk = ctx->hunk;
ctx->out.next = NULL;
rc = next_filter(r, &ctx->out);
if (rc == NGX_ERROR || rc == NGX_AGAIN) {
return rc;
}
/* NGX_OK */
/* set our hunk free */
ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
/* repeat until we will have copied the whole first hunk from
the incoming chain ctx->in */
} while (ctx->in->hunk->pos.mem < ctx->in->hunk->last.mem);
/* delete the completed hunk from the incoming chain */
ctx->in = ctx->in->next;
/* repeat until we will have processed the whole incoming chain ctx->in */
} while (ctx->in);
return NGX_OK;
}
#else
int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk) int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
{ {
int rc, once; int rc, once;
@ -106,6 +324,7 @@ int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
} else { } else {
ctx->out.hunk = ctx->hunk; ctx->out.hunk = ctx->hunk;
/* XXX: should we check hunk type before copy it ? */
rc = ngx_http_output_filter_copy_hunk(ctx->hunk, ctx->in->hunk); rc = ngx_http_output_filter_copy_hunk(ctx->hunk, ctx->in->hunk);
#if (NGX_FILE_AIO_READ) #if (NGX_FILE_AIO_READ)
if (rc == NGX_AGAIN) { if (rc == NGX_AGAIN) {
@ -116,6 +335,8 @@ int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
return rc; return rc;
} }
/* NGX_OK */
/* whole hunk is copied so we send to next filter chain part /* whole hunk is copied so we send to next filter chain part
up to next hunk that need to be copied */ up to next hunk that need to be copied */
if (ctx->in->hunk->pos.mem == ctx->in->hunk->last.mem) { if (ctx->in->hunk->pos.mem == ctx->in->hunk->last.mem) {
@ -242,9 +463,11 @@ int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
} }
} }
if (rc == NGX_OK && ctx->hunk) /* set free our hunk if operation has completed */
if (rc == NGX_OK && ctx->hunk) {
ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start; ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
} }
}
#if (NGX_SUPPRESS_WARN) #if (NGX_SUPPRESS_WARN)
if (rc == NGX_ALERT) { if (rc == NGX_ALERT) {
@ -259,7 +482,7 @@ int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
} }
if (rc == NGX_OK) { if (rc == NGX_OK) {
if (ctx->hunk) { if (ctx->hunk) { /* XXX: double upper code ? */
ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start; ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
} }
#if (NGX_LEVEL_EVENT) #if (NGX_LEVEL_EVENT)
@ -270,6 +493,8 @@ int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
return rc; return rc;
} }
#endif
static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src) static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src)
{ {

View File

@ -21,7 +21,6 @@ typedef struct {
ngx_hunk_t *hunk; ngx_hunk_t *hunk;
ngx_chain_t *in; ngx_chain_t *in;
ngx_chain_t out; ngx_chain_t out;
unsigned last;
} ngx_http_output_filter_ctx_t; } ngx_http_output_filter_ctx_t;

View File

@ -83,11 +83,12 @@ int ngx_sendfile(ngx_connection_t *c,
ptfb = NULL; ptfb = NULL;
} }
#if 0 #if 1
flags = TF_DISCONNECT|TF_REUSE_SOCKET; flags = TF_DISCONNECT|TF_REUSE_SOCKET;
#endif tfrc = transmitfile(c->fd, NULL, 0, 0, &olp, NULL, flags);
#else
tfrc = TransmitFile(c->fd, fd, nbytes, 0, &olp, ptfb, flags); tfrc = TransmitFile(c->fd, fd, nbytes, 0, &olp, ptfb, flags);
#endif
#if 0 #if 0
#if 1 #if 1

View File

@ -8,9 +8,9 @@
/* These pointers should be per protocol ? */ /* These pointers should be per protocol ? */
LPFN_ACCEPTEX AcceptEx; LPFN_ACCEPTEX acceptex;
LPFN_GETACCEPTEXSOCKADDRS GetAcceptExSockaddrs; LPFN_GETACCEPTEXSOCKADDRS getacceptexsockaddrs;
LPFN_TRANSMITFILE TransmitFile; LPFN_TRANSMITFILE transmitfile;
static GUID ae_guid = WSAID_ACCEPTEX; static GUID ae_guid = WSAID_ACCEPTEX;
static GUID as_guid = WSAID_GETACCEPTEXSOCKADDRS; static GUID as_guid = WSAID_GETACCEPTEXSOCKADDRS;
@ -37,7 +37,7 @@ int ngx_init_sockets(ngx_log_t *log)
} }
if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &ae_guid, sizeof(GUID), if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &ae_guid, sizeof(GUID),
&AcceptEx, sizeof(LPFN_ACCEPTEX), &bytes, NULL, NULL) == -1) { &acceptex, sizeof(LPFN_ACCEPTEX), &bytes, NULL, NULL) == -1) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
"WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, " "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
@ -46,7 +46,7 @@ int ngx_init_sockets(ngx_log_t *log)
} }
if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &as_guid, sizeof(GUID), if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &as_guid, sizeof(GUID),
&GetAcceptExSockaddrs, sizeof(LPFN_GETACCEPTEXSOCKADDRS), &getacceptexsockaddrs, sizeof(LPFN_GETACCEPTEXSOCKADDRS),
&bytes, NULL, NULL) == -1) { &bytes, NULL, NULL) == -1) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
@ -56,7 +56,7 @@ int ngx_init_sockets(ngx_log_t *log)
} }
if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &tf_guid, sizeof(GUID), if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &tf_guid, sizeof(GUID),
&TransmitFile, sizeof(LPFN_TRANSMITFILE), &bytes, &transmitfile, sizeof(LPFN_TRANSMITFILE), &bytes,
NULL, NULL) == -1) { NULL, NULL) == -1) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
"WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, " "WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "