nginx-0.0.7-2004-06-20-23:54:15 import

This commit is contained in:
Igor Sysoev 2004-06-20 19:54:15 +00:00
parent f7290501f2
commit 73a73b5a60
12 changed files with 176 additions and 80 deletions

6
auto/types/maxvalue Normal file
View 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

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}
if (ngx_threaded) {
if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {

View File

@ -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);

View File

@ -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);
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,30 +1082,53 @@ 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) {
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);
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
"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);
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);
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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>

View File

@ -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;

View File

@ -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) {

View File

@ -767,22 +767,26 @@ ngx_int_t ngx_write_channel(ngx_socket_t s, ngx_channel_t *ch, size_t size,
ngx_err_t err;
struct iovec iov[1];
struct msghdr msg;
struct cmsghdr cm;
#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;
#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)) {