mirror of
https://github.com/nginx/nginx.git
synced 2024-11-24 04:49:01 +08:00
nginx-0.0.7-2004-06-20-23:54:15 import
This commit is contained in:
parent
f7290501f2
commit
73a73b5a60
6
auto/types/maxvalue
Normal file
6
auto/types/maxvalue
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
cat << END >> $NGX_AUTO_CONFIG_H
|
||||
|
||||
#ifndef $ngx_type_max_value
|
||||
#define $ngx_type_max_value $ngx_max_size
|
||||
#endif
|
@ -46,6 +46,7 @@ CC_WARN=$CC_STRONG
|
||||
ngx_fmt_collect=no
|
||||
|
||||
ngx_fmt_name=OFF_T_FMT; ngx_type="off_t"; . auto/types/sizeof
|
||||
ngx_type_max_value=OFF_T_MAX_VALUE; . auto/types/maxvalue
|
||||
eval ngx_formats=\${ngx_${ngx_bytes}_fmt}; . auto/fmt/fmt
|
||||
|
||||
ngx_fmt_name=TIME_T_FMT; ngx_type="time_t"; . auto/types/sizeof
|
||||
|
@ -91,8 +91,6 @@ struct ngx_event_s {
|
||||
unsigned short timedout:1;
|
||||
unsigned short timer_set:1;
|
||||
|
||||
unsigned short delayed:1;
|
||||
|
||||
unsigned short read_discarded:1;
|
||||
|
||||
unsigned short unexpected_eof:1;
|
||||
@ -499,7 +497,7 @@ ngx_inline static int ngx_handle_read_event(ngx_event_t *rev, u_int flags)
|
||||
}
|
||||
}
|
||||
|
||||
/* aio, iocp, epoll, rt signals */
|
||||
/* aio, iocp, epoll, rtsig */
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
@ -570,7 +568,7 @@ ngx_inline static int ngx_handle_write_event(ngx_event_t *wev, u_int flags)
|
||||
}
|
||||
}
|
||||
|
||||
/* aio, iocp, epoll, rt signals */
|
||||
/* aio, iocp, epoll, rtsig */
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
@ -91,15 +91,7 @@ void ngx_event_expire_timers(ngx_msec_t timer)
|
||||
|
||||
ngx_del_timer(ev);
|
||||
|
||||
if (ev->delayed) {
|
||||
ev->delayed = 0;
|
||||
if (ev->ready == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
} else {
|
||||
ev->timedout = 1;
|
||||
}
|
||||
ev->timedout = 1;
|
||||
|
||||
if (ngx_threaded) {
|
||||
if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
|
||||
|
@ -85,7 +85,7 @@ ngx_inline static void ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer)
|
||||
* for the fast connections.
|
||||
*/
|
||||
|
||||
if (key - ev->rbtree_key < 100 / NGX_TIMER_RESOLUTION) {
|
||||
if (abs(key - ev->rbtree_key) < 100 / NGX_TIMER_RESOLUTION) {
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
|
||||
"event timer: %d, old: %d, new: %d",
|
||||
ngx_event_ident(ev->data), ev->rbtree_key, key);
|
||||
|
@ -1050,13 +1050,15 @@ static void ngx_http_set_write_handler(ngx_http_request_t *r)
|
||||
wev = r->connection->write;
|
||||
wev->event_handler = ngx_http_writer;
|
||||
|
||||
if (wev->delayed && wev->ready) {
|
||||
if (wev->ready && r->delayed) {
|
||||
return;
|
||||
}
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r,
|
||||
ngx_http_core_module);
|
||||
ngx_add_timer(wev, clcf->send_timeout);
|
||||
if (!r->delayed) {
|
||||
ngx_add_timer(wev, clcf->send_timeout);
|
||||
}
|
||||
|
||||
wev->available = clcf->send_lowat;
|
||||
if (ngx_handle_write_event(wev, NGX_LOWAT_EVENT) == NGX_ERROR) {
|
||||
@ -1080,15 +1082,36 @@ void ngx_http_writer(ngx_event_t *wev)
|
||||
c = wev->data;
|
||||
r = c->data;
|
||||
|
||||
#if 0 /* TODO: THINK */
|
||||
if (wev->delayed) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (wev->timedout) {
|
||||
ngx_http_client_error(r, 0, NGX_HTTP_REQUEST_TIME_OUT);
|
||||
return;
|
||||
if (!r->delayed) {
|
||||
ngx_http_client_error(r, 0, NGX_HTTP_REQUEST_TIME_OUT);
|
||||
return;
|
||||
}
|
||||
|
||||
wev->timedout = 0;
|
||||
r->delayed = 0;
|
||||
|
||||
if (!wev->ready) {
|
||||
clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r,
|
||||
ngx_http_core_module);
|
||||
ngx_add_timer(wev, clcf->send_timeout);
|
||||
|
||||
wev->available = clcf->send_lowat;
|
||||
|
||||
if (ngx_handle_write_event(wev, NGX_LOWAT_EVENT) == NGX_ERROR) {
|
||||
ngx_http_close_request(r, 0);
|
||||
ngx_http_close_connection(r->connection);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (r->delayed) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0,
|
||||
"http writer delayed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
rc = ngx_http_output_filter(r, NULL);
|
||||
@ -1097,13 +1120,15 @@ void ngx_http_writer(ngx_event_t *wev)
|
||||
"http writer output filter: %d", rc);
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
if (!wev->ready) {
|
||||
clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r,
|
||||
ngx_http_core_module);
|
||||
clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r,
|
||||
ngx_http_core_module);
|
||||
if (!wev->ready && !r->delayed) {
|
||||
ngx_add_timer(wev, clcf->send_timeout);
|
||||
}
|
||||
|
||||
if (ngx_handle_level_write_event(wev) == NGX_ERROR) {
|
||||
wev->available = clcf->send_lowat;
|
||||
|
||||
if (ngx_handle_write_event(wev, NGX_LOWAT_EVENT) == NGX_ERROR) {
|
||||
ngx_http_close_request(r, 0);
|
||||
ngx_http_close_connection(r->connection);
|
||||
}
|
||||
|
@ -284,6 +284,7 @@ struct ngx_http_request_s {
|
||||
/* can we use sendfile ? */
|
||||
unsigned sendfile:1;
|
||||
|
||||
unsigned delayed:1;
|
||||
unsigned chunked:1;
|
||||
unsigned header_only:1;
|
||||
unsigned keepalive:1;
|
||||
|
@ -69,7 +69,7 @@ ngx_module_t ngx_http_write_filter_module = {
|
||||
ngx_int_t ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
{
|
||||
int last;
|
||||
off_t size, flush;
|
||||
off_t size, flush, sent;
|
||||
ngx_chain_t *cl, *ln, **ll, *chain;
|
||||
ngx_http_write_filter_ctx_t *ctx;
|
||||
ngx_http_write_filter_conf_t *conf;
|
||||
@ -138,7 +138,7 @@ ngx_int_t ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (r->connection->write->delayed) {
|
||||
if (r->delayed) {
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
@ -150,11 +150,19 @@ ngx_int_t ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
sent = r->connection->sent;
|
||||
|
||||
chain = ngx_write_chain(r->connection, ctx->out);
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http write filter %X", chain);
|
||||
|
||||
#if 1
|
||||
sent = r->connection->sent - sent;
|
||||
r->delayed = 1;
|
||||
ngx_add_timer(r->connection->write, sent * 1000 / (4 * 1024));
|
||||
#endif
|
||||
|
||||
if (chain == NGX_CHAIN_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
@ -35,6 +35,22 @@
|
||||
#include <sys/sysctl.h>
|
||||
#include <netinet/tcp.h> /* TCP_NOPUSH */
|
||||
|
||||
|
||||
#if __FreeBSD_version < 400017
|
||||
|
||||
#include <sys/param.h> /* ALIGN() */
|
||||
|
||||
/* FreeBSD 3.x has no CMSG_SPACE() at all and has the broken CMSG_DATA() */
|
||||
|
||||
#undef CMSG_SPACE
|
||||
#define CMSG_SPACE(l) (ALIGN(sizeof(struct cmsghdr)) + ALIGN(l))
|
||||
|
||||
#undef CMSG_DATA
|
||||
#define CMSG_DATA(cmsg) ((u_char *)(cmsg) + ALIGN(sizeof(struct cmsghdr)))
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#include <ngx_auto_config.h>
|
||||
|
||||
|
||||
|
@ -121,15 +121,18 @@ int ngx_os_init(ngx_log_t *log)
|
||||
#if (HAVE_SENDFILE)
|
||||
|
||||
/*
|
||||
* The determination of the sendfile() nbytes bug is complex enough.
|
||||
* The determination of the sendfile() "nbytes bug" is complex enough.
|
||||
* There are 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
|
||||
* We use the algorithm that is correct at least for RELEASEs
|
||||
* and for syscalls only (not libc_r wrapper).
|
||||
*
|
||||
* We detect the new sendfile() version available at the compile time
|
||||
* 4.6.1-RELEASE and below have the bug
|
||||
* 4.6.2-RELEASE and above have the new syscall
|
||||
*
|
||||
* We detect the new sendfile() syscall available at the compile time
|
||||
* to allow an old binary to run correctly on an updated FreeBSD system.
|
||||
*/
|
||||
|
||||
@ -142,7 +145,7 @@ int ngx_os_init(ngx_log_t *log)
|
||||
|
||||
#else
|
||||
|
||||
/* an old syscall that can have the bug */
|
||||
/* an old syscall that may have the bug */
|
||||
|
||||
ngx_freebsd_sendfile_nbytes_bug = 1;
|
||||
|
||||
|
@ -11,9 +11,9 @@
|
||||
|
||||
/*
|
||||
* Although FreeBSD sendfile() allows to pass a header and a trailer
|
||||
* it never sends a header with a part of the file in one packet until
|
||||
* it can not send a header with a part of the file in one packet until
|
||||
* FreeBSD 5.2-STABLE. Besides over the fast ethernet connection sendfile()
|
||||
* can send the partially filled packets, i.e. the 8 file pages can be sent
|
||||
* may send the partially filled packets, i.e. the 8 file pages may be sent
|
||||
* as the 11 full 1460-bytes packets, then one incomplete 324-bytes packet,
|
||||
* and then again the 11 full 1460-bytes packets.
|
||||
*
|
||||
@ -22,7 +22,7 @@
|
||||
* of the file in one packet but also sends file pages in the full packets.
|
||||
*
|
||||
* But until FreeBSD 4.5 the turning TCP_NOPUSH off does not flush a pending
|
||||
* data that less than MSS so that data can be sent with 5 second delay.
|
||||
* data that less than MSS so that data may be sent with 5 second delay.
|
||||
* So we do not use TCP_NOPUSH on FreeBSD prior to 4.5 although it can be used
|
||||
* for non-keepalive HTTP connections.
|
||||
*/
|
||||
@ -32,10 +32,10 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
|
||||
{
|
||||
int rc;
|
||||
u_char *prev;
|
||||
off_t sent, fprev;
|
||||
off_t sent, fprev, send, limit;
|
||||
size_t hsize, fsize;
|
||||
ssize_t size;
|
||||
ngx_int_t eintr, eagain;
|
||||
ngx_uint_t eintr, eagain, ready;
|
||||
struct iovec *iov;
|
||||
struct sf_hdtr hdtr;
|
||||
ngx_err_t err;
|
||||
@ -62,12 +62,20 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
|
||||
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
limit = 4096;
|
||||
#else
|
||||
limit = OFF_T_MAX_VALUE;
|
||||
#endif
|
||||
|
||||
do {
|
||||
file = NULL;
|
||||
fsize = 0;
|
||||
hsize = 0;
|
||||
send = 0;
|
||||
eintr = 0;
|
||||
eagain = 0;
|
||||
ready = 0;
|
||||
|
||||
ngx_init_array(header, c->pool, 10, sizeof(struct iovec),
|
||||
NGX_CHAIN_ERROR);
|
||||
@ -88,40 +96,50 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
|
||||
break;
|
||||
}
|
||||
|
||||
size = cl->buf->last - cl->buf->pos;
|
||||
|
||||
if (send + size > limit) {
|
||||
size = limit - send;
|
||||
}
|
||||
|
||||
if (prev == cl->buf->pos) {
|
||||
iov->iov_len += cl->buf->last - cl->buf->pos;
|
||||
iov->iov_len += size;
|
||||
|
||||
} else {
|
||||
ngx_test_null(iov, ngx_push_array(&header), NGX_CHAIN_ERROR);
|
||||
iov->iov_base = (void *) cl->buf->pos;
|
||||
iov->iov_len = cl->buf->last - cl->buf->pos;
|
||||
iov->iov_len = size;
|
||||
}
|
||||
|
||||
prev = cl->buf->last;
|
||||
hsize += cl->buf->last - cl->buf->pos;
|
||||
prev = cl->buf->pos + size;
|
||||
hsize += size;
|
||||
send += size;
|
||||
}
|
||||
|
||||
/* get the file buf */
|
||||
|
||||
if (cl && cl->buf->in_file) {
|
||||
file = cl->buf;
|
||||
fsize = (size_t) (file->file_last - file->file_pos);
|
||||
fprev = file->file_last;
|
||||
cl = cl->next;
|
||||
fsize = 0;
|
||||
|
||||
/* coalesce the neighbouring file bufs */
|
||||
|
||||
while (cl && cl->buf->in_file) {
|
||||
if (file->file->fd != cl->buf->file->fd
|
||||
|| fprev != cl->buf->file_pos)
|
||||
{
|
||||
break;
|
||||
do {
|
||||
size = (size_t) (cl->buf->file_last - cl->buf->file_pos);
|
||||
|
||||
if (send + size > limit) {
|
||||
size = limit - send;
|
||||
}
|
||||
|
||||
fsize += (size_t) (cl->buf->file_last - cl->buf->file_pos);
|
||||
fprev = cl->buf->file_last;
|
||||
fsize += size;
|
||||
send += size;
|
||||
fprev = cl->buf->file_pos + size;
|
||||
cl = cl->next;
|
||||
}
|
||||
|
||||
} while (cl
|
||||
&& cl->buf->in_file
|
||||
&& file->file->fd == cl->buf->file->fd
|
||||
&& fprev == cl->buf->file_pos);
|
||||
}
|
||||
|
||||
if (file) {
|
||||
@ -139,17 +157,24 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
|
||||
break;
|
||||
}
|
||||
|
||||
size = cl->buf->last - cl->buf->pos;
|
||||
|
||||
if (send + size > limit) {
|
||||
size = limit - send;
|
||||
}
|
||||
|
||||
if (prev == cl->buf->pos) {
|
||||
iov->iov_len += cl->buf->last - cl->buf->pos;
|
||||
iov->iov_len += size;
|
||||
|
||||
} else {
|
||||
ngx_test_null(iov, ngx_push_array(&trailer),
|
||||
NGX_CHAIN_ERROR);
|
||||
iov->iov_base = (void *) cl->buf->pos;
|
||||
iov->iov_len = cl->buf->last - cl->buf->pos;
|
||||
iov->iov_len = size;
|
||||
}
|
||||
|
||||
prev = cl->buf->last;
|
||||
prev = cl->buf->pos + size;
|
||||
send += size;
|
||||
}
|
||||
}
|
||||
|
||||
@ -261,6 +286,10 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
|
||||
sent = rc > 0 ? rc : 0;
|
||||
}
|
||||
|
||||
if (send == sent) {
|
||||
ready = 1;
|
||||
}
|
||||
|
||||
c->sent += sent;
|
||||
|
||||
for (cl = in; cl; cl = cl->next) {
|
||||
@ -300,6 +329,10 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ready) {
|
||||
return cl;
|
||||
}
|
||||
|
||||
in = cl;
|
||||
|
||||
if (eagain) {
|
||||
|
@ -763,26 +763,30 @@ int ngx_worker_thread_cycle(void *data)
|
||||
ngx_int_t ngx_write_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size,
|
||||
ngx_log_t *log)
|
||||
{
|
||||
ssize_t n;
|
||||
ngx_err_t err;
|
||||
struct iovec iov[1];
|
||||
struct msghdr msg;
|
||||
struct cmsghdr cm;
|
||||
ssize_t n;
|
||||
ngx_err_t err;
|
||||
struct iovec iov[1];
|
||||
struct msghdr msg;
|
||||
|
||||
#if (HAVE_MSGHDR_MSG_CONTROL)
|
||||
|
||||
union {
|
||||
struct cmsghdr cm;
|
||||
char space[CMSG_SPACE(sizeof(int))];
|
||||
} cmsg;
|
||||
|
||||
if (ch->fd == -1) {
|
||||
msg.msg_control = NULL;
|
||||
msg.msg_controllen = 0;
|
||||
|
||||
} else {
|
||||
msg.msg_control = (caddr_t) &cm;
|
||||
msg.msg_controllen = sizeof(struct cmsghdr) + sizeof(int);
|
||||
msg.msg_control = (caddr_t) &cmsg;
|
||||
msg.msg_controllen = sizeof(cmsg);
|
||||
|
||||
cm.cmsg_len = sizeof(struct cmsghdr) + sizeof(int);
|
||||
cm.cmsg_level = SOL_SOCKET;
|
||||
cm.cmsg_type = SCM_RIGHTS;
|
||||
*((int *) ((char *) &cm + sizeof(struct cmsghdr))) = ch->fd;
|
||||
cmsg.cm.cmsg_len = sizeof(cmsg);
|
||||
cmsg.cm.cmsg_level = SOL_SOCKET;
|
||||
cmsg.cm.cmsg_type = SCM_RIGHTS;
|
||||
*(int *) CMSG_DATA(&cmsg) = ch->fd;
|
||||
}
|
||||
|
||||
#else
|
||||
@ -825,12 +829,19 @@ ngx_int_t ngx_write_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size,
|
||||
ngx_int_t ngx_read_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size,
|
||||
ngx_log_t *log)
|
||||
{
|
||||
int fd;
|
||||
ssize_t n;
|
||||
ngx_err_t err;
|
||||
struct iovec iov[1];
|
||||
struct msghdr msg;
|
||||
struct cmsghdr cm;
|
||||
ssize_t n;
|
||||
ngx_err_t err;
|
||||
struct iovec iov[1];
|
||||
struct msghdr msg;
|
||||
|
||||
#if (HAVE_MSGHDR_MSG_CONTROL)
|
||||
union {
|
||||
struct cmsghdr cm;
|
||||
char space[CMSG_SPACE(sizeof(int))];
|
||||
} cmsg;
|
||||
#else
|
||||
int fd;
|
||||
#endif
|
||||
|
||||
iov[0].iov_base = (char *) ch;
|
||||
iov[0].iov_len = size;
|
||||
@ -841,8 +852,8 @@ ngx_int_t ngx_read_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size,
|
||||
msg.msg_iovlen = 1;
|
||||
|
||||
#if (HAVE_MSGHDR_MSG_CONTROL)
|
||||
msg.msg_control = (caddr_t) &cm;
|
||||
msg.msg_controllen = sizeof(struct cmsghdr) + sizeof(int);
|
||||
msg.msg_control = (caddr_t) &cmsg;
|
||||
msg.msg_controllen = sizeof(cmsg);
|
||||
#else
|
||||
msg.msg_accrights = (caddr_t) &fd;
|
||||
msg.msg_accrightslen = sizeof(int);
|
||||
@ -870,20 +881,22 @@ ngx_int_t ngx_read_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size,
|
||||
|
||||
if (ch->command == NGX_CMD_OPEN_CHANNEL) {
|
||||
|
||||
if (cm.cmsg_len < sizeof(struct cmsghdr) + sizeof(int)) {
|
||||
if (cmsg.cm.cmsg_len < sizeof(cmsg)) {
|
||||
ngx_log_error(NGX_LOG_ALERT, log, 0,
|
||||
"recvmsg() returned too small ancillary data");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (cm.cmsg_level != SOL_SOCKET || cm.cmsg_type != SCM_RIGHTS) {
|
||||
if (cmsg.cm.cmsg_level != SOL_SOCKET || cmsg.cm.cmsg_type != SCM_RIGHTS)
|
||||
{
|
||||
ngx_log_error(NGX_LOG_ALERT, log, 0,
|
||||
"recvmsg() returned invalid ancillary data "
|
||||
"level %d or type %d", cm.cmsg_level, cm.cmsg_type);
|
||||
"level %d or type %d",
|
||||
cmsg.cm.cmsg_level, cmsg.cm.cmsg_type);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ch->fd = *((int *) ((char *) &cm + sizeof(struct cmsghdr)));
|
||||
ch->fd = *(int *) CMSG_DATA(&cmsg);
|
||||
}
|
||||
|
||||
if (msg.msg_flags & (MSG_TRUNC|MSG_CTRUNC)) {
|
||||
|
Loading…
Reference in New Issue
Block a user