mirror of
https://github.com/nginx/nginx.git
synced 2024-12-20 06:03:31 -06:00
nginx-0.0.1-2003-02-11-10:14:40 import
This commit is contained in:
parent
7300977320
commit
1e7ec9dcd2
@ -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.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_HAVE_ONESHOT_EVENT
|
||||
#if (HAVE_AIO_EVENT)
|
||||
|NGX_HAVE_AIO_EVENT;
|
||||
#else
|
||||
|NGX_HAVE_CLEAR_EVENT;
|
||||
#if (HAVE_CLEAR_EVENT)
|
||||
|NGX_HAVE_CLEAR_EVENT
|
||||
#endif
|
||||
|NGX_HAVE_KQUEUE_EVENT;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
return NGX_OK;
|
||||
|
@ -214,6 +214,8 @@ int ngx_poll_process_events(ngx_log_t *log)
|
||||
if (event_list[i].revents & (POLLERR|POLLHUP|POLLNVAL)) {
|
||||
found = 1;
|
||||
|
||||
/* need ot add to ready_index[nready++] = c->read or c->write; */
|
||||
|
||||
err = 0;
|
||||
if (event_list[i].revents & POLLNVAL) {
|
||||
err = EBADF;
|
||||
|
117
src/event/modules/ngx_sigio_module.c
Normal file
117
src/event/modules/ngx_sigio_module.c
Normal 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 {
|
||||
}
|
||||
}
|
||||
}
|
@ -36,33 +36,9 @@ ngx_event_t *ngx_read_events, *ngx_write_events;
|
||||
|
||||
#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;
|
||||
|
||||
ngx_event_actions_t ngx_event_actions;
|
||||
|
||||
@ -97,8 +73,17 @@ void ngx_pre_thread(ngx_array_t *ls, ngx_pool_t *pool, ngx_log_t *log)
|
||||
/* STUB */
|
||||
int max_connections = 512;
|
||||
|
||||
#if (HAVE_IOCP)
|
||||
ngx_event_type = NGX_IOCP_EVENT;
|
||||
#if 0
|
||||
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
|
||||
|
||||
if (ngx_init_events(max_connections, log) == NGX_ERROR) {
|
||||
|
@ -106,20 +106,20 @@ struct ngx_event_s {
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
NGX_SELECT_EVENT = 0,
|
||||
NGX_SELECT_EVENT_N = 0,
|
||||
#if (HAVE_POLL)
|
||||
NGX_POLL_EVENT,
|
||||
NGX_POLL_EVENT_N,
|
||||
#endif
|
||||
#if (HAVE_DEVPOLL)
|
||||
NGX_DEVPOLL_EVENT,
|
||||
NGX_DEVPOLL_EVENT_N,
|
||||
#endif
|
||||
#if (HAVE_KQUEUE)
|
||||
NGX_KQUEUE_EVENT,
|
||||
NGX_KQUEUE_EVENT_N,
|
||||
#endif
|
||||
#if (HAVE_IOCP)
|
||||
NGX_IOCP_EVENT,
|
||||
NGX_IOCP_EVENT_N,
|
||||
#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 ;
|
||||
|
||||
typedef struct {
|
||||
@ -145,15 +145,21 @@ typedef struct {
|
||||
/* Event filter notifies only changes and initial level - kqueue */
|
||||
#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 */
|
||||
#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 */
|
||||
#define NGX_HAVE_AIO_EVENT 16
|
||||
#define NGX_HAVE_AIO_EVENT 64
|
||||
|
||||
/* 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 */
|
||||
#define NGX_HAVE_IOCP_EVENT 32
|
||||
#define NGX_HAVE_IOCP_EVENT 128
|
||||
|
||||
/* Event filter is deleted before closing file. Has no meaning
|
||||
for select, poll, epoll.
|
||||
|
@ -156,7 +156,7 @@ int ngx_event_accept(ngx_event_t *ev)
|
||||
|
||||
#elif (HAVE_KQUEUE)
|
||||
|
||||
if (ngx_event_type == NGX_KQUEUE_EVENT) {
|
||||
if (ngx_event_type == NGX_HAVE_KQUEUE_EVENT) {
|
||||
ev->available--;
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ int ngx_event_acceptex(ngx_event_t *ev)
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
GetAcceptExSockaddrs(c->data, 0,
|
||||
getacceptexsockaddrs(c->data, 0,
|
||||
c->socklen + 16, c->socklen + 16,
|
||||
&c->local_sockaddr, &c->local_socklen,
|
||||
&c->sockaddr, &c->socklen);
|
||||
@ -130,7 +130,7 @@ int ngx_event_post_acceptex(ngx_listen_t *ls, int n)
|
||||
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,
|
||||
&rcvd, (LPOVERLAPPED) &rev->ovlp) == 0) {
|
||||
|
||||
|
@ -36,7 +36,7 @@ ssize_t ngx_event_recv_core(ngx_connection_t *c, char *buf, size_t size)
|
||||
|
||||
#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->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)
|
||||
|
||||
if (ngx_event_type == NGX_KQUEUE_EVENT) {
|
||||
if (ngx_event_type == NGX_HAVE_KQUEUE_EVENT) {
|
||||
c->read->available -= n;
|
||||
}
|
||||
|
||||
|
@ -437,7 +437,7 @@ static int ngx_http_proxy_read_response_body(ngx_event_t *ev)
|
||||
|
||||
#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 */
|
||||
if (ev->eof && ev->available == 0) {
|
||||
left = 1;
|
||||
|
@ -163,6 +163,9 @@ struct ngx_http_request_s {
|
||||
unsigned unusual_uri:1; /* URI is not started with '/' - "GET http://" */
|
||||
unsigned complex_uri:1; /* URI with "/." or with "//" (WIN32) */
|
||||
unsigned path_not_found:1;
|
||||
#ifdef NGX_EVENT
|
||||
unsigned write_level_event:1;
|
||||
#endif
|
||||
|
||||
int state;
|
||||
char *uri_start;
|
||||
|
@ -101,10 +101,10 @@ int ngx_http_handler(ngx_http_request_t *r)
|
||||
|
||||
r->connection->unexpected_eof = 0;
|
||||
|
||||
r->lingering_close = 0;
|
||||
r->keepalive = 0;
|
||||
r->lingering_close = 1;
|
||||
r->keepalive = 1;
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY;
|
||||
#endif
|
||||
|
||||
|
@ -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_block_read(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_set_lingering_close(ngx_http_request_t *r);
|
||||
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
|
||||
|
||||
/* THINK: should ngx_edge_add_event() be moved to accept part ? */
|
||||
#if (HAVE_EDGE_EVENT) /* epoll */
|
||||
|
||||
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_http_init_request(ev);
|
||||
@ -129,7 +131,7 @@ int ngx_http_init_connection(ngx_connection_t *c)
|
||||
return ngx_http_init_request(ev);
|
||||
}
|
||||
|
||||
#endif /* HAVE_AIO_EVENT */
|
||||
#endif
|
||||
|
||||
/* select, poll, /dev/poll */
|
||||
|
||||
@ -498,9 +500,9 @@ static int ngx_http_event_request_handler(ngx_http_request_t *r)
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
@ -512,30 +514,14 @@ static int ngx_http_event_request_handler(ngx_http_request_t *r)
|
||||
event = NGX_CLEAR_EVENT;
|
||||
|
||||
} 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;
|
||||
|
||||
} else {
|
||||
event = NGX_ONESHOT_EVENT;
|
||||
r->write_level_event = 1;
|
||||
}
|
||||
|
||||
#else /* select, poll */
|
||||
#else /* select, poll, /dev/poll */
|
||||
|
||||
event = NGX_ONESHOT_EVENT;
|
||||
event = NGX_LEVEL_EVENT;
|
||||
r->write_level_event = 1;
|
||||
|
||||
#endif
|
||||
|
||||
@ -571,13 +557,7 @@ static int ngx_http_event_request_handler(ngx_http_request_t *r)
|
||||
|
||||
/* keepalive */
|
||||
|
||||
r->connection->buffer->pos.mem = r->connection->buffer->last.mem
|
||||
= r->connection->buffer->start;
|
||||
rev->event_handler = ngx_http_keepalive_handler;
|
||||
|
||||
ngx_http_close_request(r);
|
||||
|
||||
return NGX_OK;
|
||||
return ngx_http_set_keepalive(r);
|
||||
}
|
||||
|
||||
|
||||
@ -617,14 +597,6 @@ static int ngx_http_writer(ngx_event_t *ev)
|
||||
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;
|
||||
}
|
||||
|
||||
@ -646,15 +618,11 @@ static int ngx_http_writer(ngx_event_t *ev)
|
||||
|
||||
/* keepalive */
|
||||
|
||||
c->buffer->pos.mem = c->buffer->last.mem = c->buffer->start;
|
||||
c->read->event_handler = ngx_http_keepalive_handler;
|
||||
|
||||
ngx_http_close_request(r);
|
||||
|
||||
return NGX_OK;
|
||||
return ngx_http_set_keepalive(r);
|
||||
}
|
||||
|
||||
|
||||
/* TODO */
|
||||
static int ngx_http_block_read(ngx_event_t *ev)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
ngx_event_t *ev;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_core_loc_conf_t *lcf;
|
||||
|
||||
c = r->connection;
|
||||
ev = r->connection->read;
|
||||
|
||||
lcf = (ngx_http_core_loc_conf_t *)
|
||||
@ -832,7 +832,21 @@ static int ngx_http_set_lingering_close(ngx_http_request_t *r)
|
||||
return ngx_http_close_request(r);
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
#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;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* select, poll, /dev/poll */
|
||||
|
||||
return ngx_del_event(c->write, NGX_WRITE_EVENT, 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 rc, once;
|
||||
@ -106,6 +324,7 @@ int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
|
||||
} else {
|
||||
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);
|
||||
#if (NGX_FILE_AIO_READ)
|
||||
if (rc == NGX_AGAIN) {
|
||||
@ -116,6 +335,8 @@ int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* NGX_OK */
|
||||
|
||||
/* whole hunk is copied so we send to next filter chain part
|
||||
up to next hunk that need to be copied */
|
||||
if (ctx->in->hunk->pos.mem == ctx->in->hunk->last.mem) {
|
||||
@ -242,8 +463,10 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
#if (NGX_SUPPRESS_WARN)
|
||||
@ -259,7 +482,7 @@ int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
#if (NGX_LEVEL_EVENT)
|
||||
@ -270,6 +493,8 @@ int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src)
|
||||
{
|
||||
|
@ -21,7 +21,6 @@ typedef struct {
|
||||
ngx_hunk_t *hunk;
|
||||
ngx_chain_t *in;
|
||||
ngx_chain_t out;
|
||||
unsigned last;
|
||||
} ngx_http_output_filter_ctx_t;
|
||||
|
||||
|
||||
|
@ -83,11 +83,12 @@ int ngx_sendfile(ngx_connection_t *c,
|
||||
ptfb = NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
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);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
|
@ -8,9 +8,9 @@
|
||||
|
||||
|
||||
/* These pointers should be per protocol ? */
|
||||
LPFN_ACCEPTEX AcceptEx;
|
||||
LPFN_GETACCEPTEXSOCKADDRS GetAcceptExSockaddrs;
|
||||
LPFN_TRANSMITFILE TransmitFile;
|
||||
LPFN_ACCEPTEX acceptex;
|
||||
LPFN_GETACCEPTEXSOCKADDRS getacceptexsockaddrs;
|
||||
LPFN_TRANSMITFILE transmitfile;
|
||||
|
||||
static GUID ae_guid = WSAID_ACCEPTEX;
|
||||
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),
|
||||
&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,
|
||||
"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),
|
||||
&GetAcceptExSockaddrs, sizeof(LPFN_GETACCEPTEXSOCKADDRS),
|
||||
&getacceptexsockaddrs, sizeof(LPFN_GETACCEPTEXSOCKADDRS),
|
||||
&bytes, NULL, NULL) == -1) {
|
||||
|
||||
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),
|
||||
&TransmitFile, sizeof(LPFN_TRANSMITFILE), &bytes,
|
||||
&transmitfile, sizeof(LPFN_TRANSMITFILE), &bytes,
|
||||
NULL, NULL) == -1) {
|
||||
ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
|
||||
"WSAIoctl(SIO_GET_EXTENSION_FUNCTION_POINTER, "
|
||||
|
Loading…
Reference in New Issue
Block a user