Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nginx/nginx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2003-06-11 19:28:34 +0400
committerIgor Sysoev <igor@sysoev.ru>2003-06-11 19:28:34 +0400
commit239baac646073cab7bbaf537ba2d6ca844f2c992 (patch)
treec7c3f61213697a68dc95898d27a730c08abce049
parente4a2526e5ccd4f3f5f160656c1a7b6f865ac44c8 (diff)
nginx-0.0.1-2003-06-11-19:28:34 import
-rw-r--r--src/core/nginx.c30
-rw-r--r--src/core/ngx_conf_file.h4
-rw-r--r--src/core/ngx_connection.h78
-rw-r--r--src/core/ngx_log.c2
-rw-r--r--src/core/ngx_modules.c10
-rw-r--r--src/event/modules/ngx_iocp_module.c53
-rw-r--r--src/event/modules/ngx_iocp_module.h12
-rw-r--r--src/event/modules/ngx_select_module.c4
-rw-r--r--src/event/ngx_event.c93
-rw-r--r--src/event/ngx_event.h43
-rw-r--r--src/event/ngx_event_accept.c53
-rw-r--r--src/event/ngx_event_acceptex.c114
-rw-r--r--src/event/ngx_event_timer.c8
-rw-r--r--src/event/ngx_event_timer.h8
-rw-r--r--src/http/modules/ngx_http_chunked_filter.c2
-rw-r--r--src/http/modules/ngx_http_index_handler.c2
-rw-r--r--src/http/modules/ngx_http_range_filter.c10
-rw-r--r--src/http/ngx_http.c30
-rw-r--r--src/http/ngx_http_core_module.c30
-rw-r--r--src/http/ngx_http_core_module.h5
-rw-r--r--src/http/ngx_http_event.c69
-rw-r--r--src/http/ngx_http_output_filter.c2
-rw-r--r--src/http/ngx_http_special_response.c73
-rw-r--r--src/http/ngx_http_write_filter.c7
-rw-r--r--src/os/unix/ngx_aio_read.c1
-rw-r--r--src/os/unix/ngx_aio_write.c3
-rw-r--r--src/os/unix/ngx_freebsd_config.h19
-rw-r--r--src/os/unix/ngx_freebsd_sendfile_chain.c5
-rw-r--r--src/os/unix/ngx_linux_config.h13
-rw-r--r--src/os/unix/ngx_readv_chain.c1
-rw-r--r--src/os/unix/ngx_recv.c1
-rw-r--r--src/os/unix/ngx_socket.c3
-rw-r--r--src/os/unix/ngx_solaris_config.h3
-rw-r--r--src/os/unix/ngx_writev_chain.c13
-rw-r--r--src/os/win32/ngx_errno.c44
-rw-r--r--src/os/win32/ngx_os_init.h2
-rw-r--r--src/os/win32/ngx_socket.h8
-rw-r--r--src/os/win32/ngx_types.h1
-rw-r--r--src/os/win32/ngx_win32_init.c (renamed from src/os/win32/ngx_init.c)53
-rw-r--r--src/os/win32/ngx_wsarecv.c90
-rw-r--r--src/os/win32/ngx_wsasend_chain.c181
41 files changed, 881 insertions, 302 deletions
diff --git a/src/core/nginx.c b/src/core/nginx.c
index 295e2a946..4f3be980c 100644
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -2,9 +2,7 @@
#include <ngx_config.h>
#include <ngx_core.h>
-
-#include <ngx_listen.h>
-
+#include <ngx_event.h>
#include <nginx.h>
@@ -61,7 +59,7 @@ int main(int argc, char *const *argv)
{
ngx_init_array(ngx_listening_sockets,
- ngx_pool, 10, sizeof(ngx_listen_t),
+ ngx_pool, 10, sizeof(ngx_listening_t),
1);
ngx_memzero(&conf, sizeof(ngx_conf_t));
@@ -126,10 +124,10 @@ int main(int argc, char *const *argv)
static int ngx_open_listening_sockets(ngx_log_t *log)
{
- int times, failed, reuseaddr, i;
- ngx_err_t err;
- ngx_socket_t s;
- ngx_listen_t *ls;
+ int times, failed, reuseaddr, i;
+ ngx_err_t err;
+ ngx_socket_t s;
+ ngx_listening_t *ls;
reuseaddr = 1;
@@ -137,7 +135,8 @@ static int ngx_open_listening_sockets(ngx_log_t *log)
failed = 0;
/* for each listening socket */
- ls = (ngx_listen_t *) ngx_listening_sockets.elts;
+
+ ls = ngx_listening_sockets.elts;
for (i = 0; i < ngx_listening_sockets.nelts; i++) {
if (ls[i].bound)
@@ -161,6 +160,19 @@ static int ngx_open_listening_sockets(ngx_log_t *log)
return NGX_ERROR;
}
+#if (WIN32)
+ /*
+ * Winsock assignes a socket number divisible by 4
+ * so to find a connection we divide a socket number by 4.
+ */
+
+ if (s % 4) {
+ ngx_log_error(NGX_LOG_EMERG, ls->log, 0,
+ ngx_socket_n " created socket %d", s);
+ return NGX_ERROR;
+ }
+#endif
+
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
(const void *) &reuseaddr, sizeof(int)) == -1) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
diff --git a/src/core/ngx_conf_file.h b/src/core/ngx_conf_file.h
index b517ff0f9..046ee2c75 100644
--- a/src/core/ngx_conf_file.h
+++ b/src/core/ngx_conf_file.h
@@ -123,8 +123,8 @@ struct ngx_conf_s {
}
#define ngx_conf_merge_size_value(conf, prev, default) \
- if (conf == (size_t) NGX_CONF_UNSET) { \
- conf = (prev == (size_t) NGX_CONF_UNSET) ? default : prev; \
+ if (conf == (ssize_t) NGX_CONF_UNSET) { \
+ conf = (prev == (ssize_t) NGX_CONF_UNSET) ? default : prev; \
}
#define ngx_conf_merge_str_value(conf, prev, default) \
diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h
index 81b5987ca..1bd97f2bb 100644
--- a/src/core/ngx_connection.h
+++ b/src/core/ngx_connection.h
@@ -1,45 +1,98 @@
#ifndef _NGX_CONNECTION_H_INCLUDED_
#define _NGX_CONNECTION_H_INCLUDED_
+
#include <ngx_config.h>
#include <ngx_core.h>
-#include <ngx_event.h>
-struct ngx_connection_s {
- ngx_socket_t fd;
- void *data;
+typedef struct {
+ ngx_socket_t fd;
+
+ struct sockaddr *sockaddr;
+ socklen_t socklen; /* size of sockaddr */
+ int addr; /* offset to address in sockaddr */
+ int addr_text_max_len;
+ ngx_str_t addr_text;
+
+ int family;
+ int type;
+ int protocol;
+ int flags; /* Winsock2 flags */
+
+ void (*handler)(ngx_connection_t *c); /* handler of accepted
+ connection */
+ void *ctx; /* ngx_http_conf_ctx_t, for example */
+ void *servers; /* array of ngx_http_in_addr_t, for example */
+
+ ngx_log_t *log;
+ int backlog;
+
+ int pool_size;
+ int post_accept_buffer_size; /* should be here because
+ of the AcceptEx() preread */
+ time_t post_accept_timeout; /* should be here because
+ of the deferred accept */
+
+ unsigned bound:1; /* already bound */
+ unsigned inherited:1; /* inherited from previous process */
+ unsigned nonblocking_accept:1;
+ unsigned nonblocking:1;
+#if 0
+ unsigned overlapped:1; /* Winsock2 overlapped */
+#endif
+ unsigned shared:1; /* shared between threads or processes */
+#if (HAVE_DEFERRED_ACCEPT)
+ unsigned deferred_accept:1;
+#endif
+} ngx_listening_t;
-#ifdef NGX_EVENT
+
+struct ngx_connection_s {
+ void *data;
ngx_event_t *read;
ngx_event_t *write;
-#endif
+
+ ngx_socket_t fd;
+
+ ngx_listening_t *listening;
off_t sent;
+#if 0
void (*handler)(ngx_connection_t *c);
+#endif
void *ctx;
void *servers;
+
ngx_log_t *log;
ngx_pool_t *pool;
+#if 0
int pool_size;
int family;
+#endif
+
struct sockaddr *sockaddr;
socklen_t socklen;
+ ngx_str_t addr_text;
+
#if (HAVE_IOCP)
struct sockaddr *local_sockaddr;
socklen_t local_socklen;
- void *listening;
#endif
+
+#if 0
int addr;
int addr_text_max_len;
- ngx_str_t addr_text;
+#endif
ngx_hunk_t *buffer;
+#if 0
unsigned int post_accept_timeout;
+#endif
int number;
@@ -47,9 +100,15 @@ struct ngx_connection_s {
unsigned unexpected_eof:1;
unsigned tcp_nopush:1;
unsigned tcp_nopush_enabled:1;
+#if (HAVE_IOCP)
+ unsigned accept_context_updated:1;
+#endif
};
+
+
+
#if 0
cached file
int fd; -2 unused, -1 closed (but read or mmaped), >=0 open
@@ -84,8 +143,9 @@ typedef struct {
#endif
-extern ngx_os_io_t ngx_io;
+extern ngx_array_t ngx_listening_sockets;
+extern ngx_os_io_t ngx_io;
extern ngx_chain_t *(*ngx_write_chain_proc)
diff --git a/src/core/ngx_log.c b/src/core/ngx_log.c
index 55807ef7c..3da25f0a5 100644
--- a/src/core/ngx_log.c
+++ b/src/core/ngx_log.c
@@ -77,7 +77,7 @@ void ngx_log_error_core(int level, ngx_log_t *log, ngx_err_t err,
/* pid#tid */
len += ngx_snprintf(errstr + len, sizeof(errstr) - len - 1,
- "%d#%d: ", ngx_getpid(), 0);
+ PID_FMT "#%d: ", ngx_getpid(), 0);
#if (HAVE_VARIADIC_MACROS)
va_start(args, fmt);
diff --git a/src/core/ngx_modules.c b/src/core/ngx_modules.c
index 4780570bc..0dbcde64d 100644
--- a/src/core/ngx_modules.c
+++ b/src/core/ngx_modules.c
@@ -17,11 +17,10 @@ extern ngx_module_t ngx_kqueue_module;
#if (HAVE_DEVPOLL)
extern ngx_module_t ngx_devpoll_module;
#endif
-#if (HAVE_AIO)
-extern ngx_module_t ngx_aio_module;
-#endif
#if (HAVE_IOCP)
extern ngx_module_t ngx_iocp_module;
+#elif (HAVE_AIO)
+extern ngx_module_t ngx_aio_module;
#endif
@@ -64,11 +63,10 @@ ngx_module_t *ngx_modules[] = {
#if (HAVE_DEVPOLL)
&ngx_devpoll_module,
#endif
-#if (HAVE_AIO)
- &ngx_aio_module,
-#endif
#if (HAVE_IOCP)
&ngx_iocp_module,
+#elif (HAVE_AIO)
+ &ngx_aio_module,
#endif
/* http */
diff --git a/src/event/modules/ngx_iocp_module.c b/src/event/modules/ngx_iocp_module.c
index 44c155e73..004a3da38 100644
--- a/src/event/modules/ngx_iocp_module.c
+++ b/src/event/modules/ngx_iocp_module.c
@@ -7,16 +7,13 @@
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_event.h>
-
-
-typedef struct {
- int threads;
-} ngx_iocp_conf_t;
+#include <ngx_iocp_module.h>
static int ngx_iocp_init(ngx_log_t *log);
static void ngx_iocp_done(ngx_log_t *log);
static int ngx_iocp_add_event(ngx_event_t *ev, int event, u_int key);
+static int ngx_iocp_del_connection(ngx_connection_t *c);
static int ngx_iocp_process_events(ngx_log_t *log);
static void *ngx_iocp_create_conf(ngx_pool_t *pool);
static char *ngx_iocp_init_conf(ngx_pool_t *pool, void *conf);
@@ -33,6 +30,20 @@ static ngx_command_t ngx_iocp_commands[] = {
offsetof(ngx_iocp_conf_t, threads),
NULL},
+ {ngx_string("acceptex"),
+ NGX_EVENT_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_num_slot,
+ 0,
+ offsetof(ngx_iocp_conf_t, acceptex),
+ NULL},
+
+ {ngx_string("acceptex_read"),
+ NGX_EVENT_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_flag_slot,
+ 0,
+ offsetof(ngx_iocp_conf_t, acceptex_read),
+ NULL},
+
ngx_null_command
};
@@ -48,7 +59,7 @@ ngx_event_module_t ngx_iocp_module_ctx = {
NULL, /* enable an event */
NULL, /* disable an event */
NULL, /* add an connection */
- NULL, /* delete an connection */
+ ngx_iocp_del_connection, /* delete an connection */
ngx_iocp_process_events, /* process the events */
ngx_iocp_init, /* init the events */
ngx_iocp_done /* done the events */
@@ -111,10 +122,13 @@ static int ngx_iocp_add_event(ngx_event_t *ev, int event, u_int key)
c = (ngx_connection_t *) ev->data;
- ngx_log_debug(ev->log, "iocp add: %d, %08x:%08x" _ c->fd _ key _ &ev->ovlp);
+ c->read->active = 1;
+ c->write->active = 1;
+
+ ngx_log_debug(ev->log, "iocp add: %d, %d:%08x" _ c->fd _ key _ &ev->ovlp);
if (CreateIoCompletionPort((HANDLE) c->fd, iocp, key, 0) == NULL) {
- ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno,
+ ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
"CreateIoCompletionPort() failed");
return NGX_ERROR;
}
@@ -123,6 +137,17 @@ static int ngx_iocp_add_event(ngx_event_t *ev, int event, u_int key)
}
+static int ngx_iocp_del_connection(ngx_connection_t *c)
+{
+ if (CancelIo((HANDLE) c->fd) == 0) {
+ ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, "CancelIo() failed");
+ return NGX_ERROR;
+ }
+
+ return NGX_OK;
+}
+
+
static int ngx_iocp_process_events(ngx_log_t *log)
{
int rc;
@@ -148,7 +173,7 @@ static int ngx_iocp_process_events(ngx_log_t *log)
rc = GetQueuedCompletionStatus(iocp, &bytes, (LPDWORD) &key,
(LPOVERLAPPED *) &ovlp, timer);
- ngx_log_debug(log, "iocp: %d, %d:%08x:%08x" _ rc _ bytes _ key _ ovlp);
+ ngx_log_debug(log, "iocp: %d, %d, %d:%08x" _ rc _ bytes _ key _ ovlp);
if (rc == 0) {
err = ngx_errno;
@@ -179,13 +204,17 @@ ngx_log_debug(log, "iocp ev: %08x" _ ev);
switch (key) {
case NGX_IOCP_IO:
ev->ready = 1;
- ev->available = bytes;
break;
case NGX_IOCP_ACCEPT:
+ if (bytes) {
+ ev->ready = 1;
+ }
break;
}
+ ev->available = bytes;
+
ngx_log_debug(log, "iocp ev handler: %08x" _ ev->event_handler);
ev->event_handler(ev);
@@ -203,6 +232,8 @@ static void *ngx_iocp_create_conf(ngx_pool_t *pool)
NGX_CONF_ERROR);
cf->threads = NGX_CONF_UNSET;
+ cf->acceptex = NGX_CONF_UNSET;
+ cf->acceptex_read = NGX_CONF_UNSET;
return cf;
}
@@ -213,6 +244,8 @@ static char *ngx_iocp_init_conf(ngx_pool_t *pool, void *conf)
ngx_iocp_conf_t *cf = conf;
ngx_conf_init_value(cf->threads, 0);
+ ngx_conf_init_value(cf->acceptex, 10);
+ ngx_conf_init_value(cf->acceptex_read, 1);
return NGX_CONF_OK;
}
diff --git a/src/event/modules/ngx_iocp_module.h b/src/event/modules/ngx_iocp_module.h
index d7f2f5192..7b61a46f3 100644
--- a/src/event/modules/ngx_iocp_module.h
+++ b/src/event/modules/ngx_iocp_module.h
@@ -2,14 +2,14 @@
#define _NGX_IOCP_MODULE_H_INCLUDED_
-#include <ngx_types.h>
-#include <ngx_log.h>
-#include <ngx_event.h>
+typedef struct {
+ int threads;
+ int acceptex;
+ int acceptex_read;
+} ngx_iocp_conf_t;
-int ngx_iocp_init(int max_connections, ngx_log_t *log);
-int ngx_iocp_add_event(ngx_event_t *ev);
-int ngx_iocp_process_events(ngx_log_t *log);
+extern ngx_module_t ngx_iocp_module;
#endif /* _NGX_IOCP_MODULE_H_INCLUDED_ */
diff --git a/src/event/modules/ngx_select_module.c b/src/event/modules/ngx_select_module.c
index 6f1296660..96a5d678e 100644
--- a/src/event/modules/ngx_select_module.c
+++ b/src/event/modules/ngx_select_module.c
@@ -378,7 +378,9 @@ static char *ngx_select_init_conf(ngx_pool_t *pool, void *conf)
ecf = ngx_event_get_conf(ngx_event_module);
- if (ecf->connections > FD_SETSIZE) {
+ /* the default FD_SETSIZE is 1024U in FreeBSD 5.x */
+
+ if ((unsigned) ecf->connections > FD_SETSIZE) {
return "maximum number of connections "
"supported by select() is " ngx_value(FD_SETSIZE);
}
diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c
index f028f5d65..b7069793a 100644
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -1,8 +1,6 @@
#include <ngx_config.h>
#include <ngx_core.h>
-#include <ngx_listen.h>
-#include <ngx_connection.h>
#include <ngx_event.h>
@@ -23,11 +21,6 @@ extern ngx_module_t ngx_devpoll_module;
#include <ngx_aio_module.h>
#endif
-#if (HAVE_IOCP)
-#include <ngx_event_acceptex.h>
-#include <ngx_iocp_module.h>
-#endif
-
static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static char *ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
@@ -123,11 +116,14 @@ ngx_module_t ngx_event_module = {
int ngx_pre_thread(ngx_array_t *ls, ngx_pool_t *pool, ngx_log_t *log)
{
int m, i, fd;
- ngx_listen_t *s;
- ngx_event_t *ev;
+ ngx_event_t *rev, *wev;
+ ngx_listening_t *s;
ngx_connection_t *c;
ngx_event_conf_t *ecf;
ngx_event_module_t *module;
+#if (WIN32)
+ ngx_iocp_conf_t *iocpcf;
+#endif
ecf = ngx_event_get_conf(ngx_event_module);
@@ -161,71 +157,76 @@ ngx_log_debug(log, "TYPE: %d" _ ecf->use);
NGX_ERROR);
/* for each listening socket */
- s = (ngx_listen_t *) ls->elts;
- for (i = 0; i < ls->nelts; i++) {
+
+ for (s = ls->elts, i = 0; i < ls->nelts; i++) {
fd = s[i].fd;
+#if (WIN32)
+ /*
+ * Winsock assignes a socket number divisible by 4
+ * so to find a connection we divide a socket number by 4.
+ */
+
+ c = &ngx_connections[fd / 4];
+ rev = &ngx_read_events[fd / 4];
+ wev = &ngx_write_events[fd / 4];
+#else
c = &ngx_connections[fd];
- ev = &ngx_read_events[fd];
+ rev = &ngx_read_events[fd];
+ wev = &ngx_write_events[fd];
+#endif
ngx_memzero(c, sizeof(ngx_connection_t));
- ngx_memzero(ev, sizeof(ngx_event_t));
+ ngx_memzero(rev, sizeof(ngx_event_t));
c->fd = fd;
- c->family = s[i].family;
- c->socklen = s[i].socklen;
- c->sockaddr = ngx_palloc(pool, s[i].socklen);
- c->addr = s[i].addr;
- c->addr_text = s[i].addr_text;
- c->addr_text_max_len = s[i].addr_text_max_len;
- c->post_accept_timeout = s[i].post_accept_timeout;
-
- c->handler = s[i].handler;
+ c->listening = &s[i];
+
c->ctx = s[i].ctx;
c->servers = s[i].servers;
c->log = s[i].log;
- c->pool_size = s[i].pool_size;
- ngx_test_null(ev->log,
- ngx_palloc(pool, sizeof(ngx_log_t)),
- NGX_ERROR);
+ ngx_test_null(rev->log, ngx_palloc(pool, sizeof(ngx_log_t)), NGX_ERROR);
- ngx_memcpy(ev->log, c->log, sizeof(ngx_log_t));
- c->read = ev;
- ev->data = c;
- ev->index = NGX_INVALID_INDEX;
+ ngx_memcpy(rev->log, c->log, sizeof(ngx_log_t));
+ c->read = rev;
+ c->write = wev;
+ rev->data = c;
+ rev->index = NGX_INVALID_INDEX;
#if 0
- ev->listening = 1;
+ rev->listening = 1;
#endif
- ev->available = 0;
+ rev->available = 0;
#if (HAVE_DEFERRED_ACCEPT)
- ev->deferred_accept = s[i].deferred_accept;
+ rev->deferred_accept = s[i].deferred_accept;
#endif
-#if (HAVE_IOCP)
+#if (WIN32)
if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) {
- ev->event_handler = &ngx_event_acceptex;
+ rev->event_handler = &ngx_event_acceptex;
- /* LOOK: we call ngx_iocp_add_event() also
- in ngx_event_post_acceptex() */
- if (ngx_iocp_add_event(ev) == NGX_ERROR) {
+ if (ngx_add_event(rev, 0, NGX_IOCP_ACCEPT) == NGX_ERROR) {
return NGX_ERROR;
}
- ngx_event_post_acceptex(&s[i], 1);
+ iocpcf = ngx_event_get_conf(ngx_iocp_module);
+ if (ngx_event_post_acceptex(&s[i], iocpcf->acceptex) == NGX_ERROR) {
+ return NGX_ERROR;
+ }
} else {
- ev->event_handler = &ngx_event_accept;
+ rev->event_handler = &ngx_event_accept;
+ ngx_add_event(rev, NGX_READ_EVENT, 0);
}
#else
- ev->event_handler = &ngx_event_accept;
- ngx_add_event(ev, NGX_READ_EVENT, 0);
+ rev->event_handler = &ngx_event_accept;
+ ngx_add_event(rev, NGX_READ_EVENT, 0);
#endif
}
@@ -384,14 +385,6 @@ static char *ngx_event_init_conf(ngx_pool_t *pool, void *conf)
#endif
-#if (WIN32)
- /*
- * Winsock assignes a socket number according to 4 * N + M,
- * where M is the constant 32 (98SE), 88 (NT) or 100 (W2K).
- * So to find a connection we divide a socket number by 4.
- */
-#endif
-
ngx_conf_init_value(ecf->timer_queues, 10);
return NGX_CONF_OK;
diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h
index f467cc713..9b6dd2399 100644
--- a/src/event/ngx_event.h
+++ b/src/event/ngx_event.h
@@ -270,11 +270,6 @@ typedef struct {
#define ngx_del_conn ngx_event_actions.del_conn
#if 0
-#define ngx_add_timer ngx_event_actions.timer
-#else
-#define ngx_add_timer ngx_event_add_timer
-#endif
-
#if (HAVE_IOCP_EVENT)
#define ngx_event_recv ngx_event_wsarecv
#elif (HAVE_AIO_EVENT)
@@ -283,17 +278,33 @@ typedef struct {
#define ngx_event_recv ngx_io.recv
#define ngx_write_chain ngx_io.send_chain
#endif
+#endif
#endif
+
+
+
+/* ***************************** */
+
+#define ngx_recv ngx_io.recv
+#define ngx_write_chain ngx_io.send_chain
+
+
+#define ngx_add_timer ngx_event_add_timer
+#define ngx_del_timer ngx_event_del_timer
+
+
#if (HAVE_IOCP_EVENT)
#define NGX_IOCP_ACCEPT 0
#define NGX_IOCP_IO 1
#endif
+/* ***************************** */
+
+
-#define ngx_del_timer ngx_event_del_timer
@@ -309,6 +320,8 @@ extern int ngx_event_flags;
+/* ***************************** */
+
#define NGX_EVENT_MODULE 0x544E5645 /* "EVNT" */
#define NGX_EVENT_CONF 0x00200000
@@ -342,6 +355,16 @@ extern ngx_module_t ngx_event_module;
void ngx_event_accept(ngx_event_t *ev);
+#if (WIN32)
+void ngx_event_acceptex(ngx_event_t *ev);
+int ngx_event_post_acceptex(ngx_listening_t *ls, int n);
+#endif
+
+/* ***************************** */
+
+
+
+
ssize_t ngx_event_recv_core(ngx_connection_t *c, char *buf, size_t size);
int ngx_event_close_connection(ngx_event_t *ev);
@@ -351,7 +374,15 @@ int ngx_pre_thread(ngx_array_t *ls, ngx_pool_t *pool, ngx_log_t *log);
void ngx_worker(ngx_log_t *log);
+/* ***************************** */
+
+
#include <ngx_event_timer.h>
+#if (WIN32)
+#include <ngx_iocp_module.h>
+#endif
+
+/* ***************************** */
#endif /* _NGX_EVENT_H_INCLUDED_ */
diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c
index 6f6e5a4ff..7e877617f 100644
--- a/src/event/ngx_event_accept.c
+++ b/src/event/ngx_event_accept.c
@@ -30,21 +30,23 @@ void ngx_event_accept(ngx_event_t *ev)
/*
* Create the pool before accept() to avoid copy the sockaddr.
- * Although accept() can fail it's uncommon case
+ * Although accept() can fail it's an uncommon case
* and the pool can be got from the free pool list
*/
- pool = ngx_create_pool(ls->pool_size, ev->log);
+ pool = ngx_create_pool(ls->listening->pool_size, ev->log);
if (pool == NULL) {
return;
}
- sa = ngx_palloc(pool, ls->socklen);
+ sa = ngx_palloc(pool, ls->listening->socklen);
if (sa == NULL) {
return;
}
- len = ls->socklen;
+ len = ls->listening->socklen;
+
+ngx_log_debug(ev->log, "ADDR %s" _ ls->listening->addr_text.data);
s = accept(ls->fd, sa, &len);
if (s == -1) {
@@ -52,12 +54,13 @@ void ngx_event_accept(ngx_event_t *ev)
if (err == NGX_EAGAIN) {
ngx_log_error(NGX_LOG_NOTICE, ev->log, err,
- "EAGAIN while accept() %s", ls->addr_text.data);
+ "EAGAIN while accept() %s",
+ ls->listening->addr_text.data);
return;
}
ngx_log_error(NGX_LOG_ALERT, ev->log, err,
- "accept() %s failed", ls->addr_text.data);
+ "accept() %s failed", ls->listening->addr_text.data);
ngx_destroy_pool(pool);
return;
@@ -70,12 +73,12 @@ void ngx_event_accept(ngx_event_t *ev)
"accept() %s returned socket #%d while "
"only %d connections was configured, "
"sleeping for 1 second",
- ls->addr_text.data, s, ecf->connections);
+ ls->listening->addr_text.data, s, ecf->connections);
if (ngx_close_socket(s) == -1) {
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
ngx_close_socket_n " %s failed",
- ls->addr_text.data);
+ ls->listening->addr_text.data);
}
ngx_msleep(1000);
@@ -91,12 +94,12 @@ void ngx_event_accept(ngx_event_t *ev)
if (ngx_blocking(s) == -1) {
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
ngx_blocking_n " %s failed",
- ls->addr_text.data);
+ ls->listening->addr_text.data);
if (ngx_close_socket(s) == -1) {
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
ngx_close_socket_n " %s failed",
- ls->addr_text.data);
+ ls->listening->addr_text.data);
}
ngx_destroy_pool(pool);
@@ -109,12 +112,12 @@ void ngx_event_accept(ngx_event_t *ev)
if (ngx_nonblocking(s) == -1) {
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
ngx_nonblocking_n " %s failed",
- ls->addr_text.data);
+ ls->listening->addr_text.data);
if (ngx_close_socket(s) == -1) {
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
ngx_close_socket_n " %s failed",
- ls->addr_text.data);
+ ls->listening->addr_text.data);
}
ngx_destroy_pool(pool);
@@ -123,9 +126,26 @@ void ngx_event_accept(ngx_event_t *ev)
}
}
+#if (WIN32)
+ /*
+ * Winsock assignes a socket number divisible by 4
+ * so to find a connection we divide a socket number by 4.
+ */
+
+ if (s % 4) {
+ ngx_log_error(NGX_LOG_EMERG, ls->log, 0,
+ ngx_socket_n " created socket %d", s);
+ exit(1);
+ }
+
+ rev = &ngx_read_events[s / 4];
+ wev = &ngx_write_events[s / 4];
+ c = &ngx_connections[s / 4];
+#else
rev = &ngx_read_events[s];
wev = &ngx_write_events[s];
c = &ngx_connections[s];
+#endif
instance = rev->instance;
@@ -135,12 +155,9 @@ void ngx_event_accept(ngx_event_t *ev)
c->pool = pool;
+ c->listening = ls->listening;
c->sockaddr = sa;
- c->family = ls->family;
c->socklen = len;
- c->addr = ls->addr;
- c->addr_text_max_len = ls->addr_text_max_len;
- c->post_accept_timeout = ls->post_accept_timeout;
rev->instance = wev->instance = !instance;
@@ -182,7 +199,7 @@ void ngx_event_accept(ngx_event_t *ev)
if (ngx_close_socket(s) == -1) {
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
ngx_close_socket_n " %s failed",
- ls->addr_text.data);
+ ls->listening->addr_text.data);
}
ngx_destroy_pool(pool);
@@ -190,7 +207,7 @@ void ngx_event_accept(ngx_event_t *ev)
}
}
- ls->handler(c);
+ ls->listening->handler(c);
if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
ev->available--;
diff --git a/src/event/ngx_event_acceptex.c b/src/event/ngx_event_acceptex.c
index 8ba56f3d7..04dddb16c 100644
--- a/src/event/ngx_event_acceptex.c
+++ b/src/event/ngx_event_acceptex.c
@@ -1,14 +1,8 @@
#include <ngx_config.h>
#include <ngx_core.h>
-
-#include <ngx_listen.h>
-
#include <ngx_event.h>
-#if 0
-#include <ngx_event_close.h>
-#include <ngx_iocp_module.h>
-#endif
+#include <nginx.h>
void ngx_event_acceptex(ngx_event_t *rev)
@@ -17,11 +11,9 @@ void ngx_event_acceptex(ngx_event_t *rev)
c = (ngx_connection_t *) rev->data;
-ngx_log_debug(rev->log, "ADDR: %s" _ c->addr_text.data);
-
if (rev->ovlp.error) {
- ngx_log_error(NGX_LOG_CRIT, rev->log, rev->ovlp.error,
- "AcceptEx() failed for %s", c->addr_text.data);
+ ngx_log_error(NGX_LOG_CRIT, c->log, rev->ovlp.error,
+ "AcceptEx() %s failed", c->listening->addr_text.data);
return;
}
@@ -30,36 +22,45 @@ ngx_log_debug(rev->log, "ADDR: %s" _ c->addr_text.data);
if (setsockopt(c->fd, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
(char *)&c->listening->fd, sizeof(ngx_socket_t)) == -1)
{
- ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_socket_errno,
+ ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno,
"setsockopt(SO_UPDATE_ACCEPT_CONTEXT) failed for %s",
c->addr_text.data);
} else {
- accept_context_updated = 1;
+ c->accept_context_updated = 1;
}
- getacceptexsockaddrs(c->data, 0,
- c->socklen + 16, c->socklen + 16,
+ getacceptexsockaddrs(c->buffer->pos, c->listening->post_accept_buffer_size,
+ c->listening->socklen + 16,
+ c->listening->socklen + 16,
&c->local_sockaddr, &c->local_socklen,
&c->sockaddr, &c->socklen);
+ if (c->listening->post_accept_buffer_size) {
+ c->buffer->last += rev->available;
+ c->buffer->end = c->buffer->start
+ + c->listening->post_accept_buffer_size;
+
+ } else {
+ c->buffer = NULL;
+ }
+
ngx_event_post_acceptex(c->listening, 1);
- /* STUB: InterlockedInc() */
+ /* TODO: MT */
c->number = ngx_connection_counter++;
- c->handler(c);
+ c->listening->handler(c);
return;
}
-int ngx_event_post_acceptex(ngx_listen_t *ls, int n)
+int ngx_event_post_acceptex(ngx_listening_t *ls, int n)
{
int i;
u_int rcvd;
ngx_err_t err;
- ngx_pool_t *pool;
ngx_event_t *rev, *wev;
ngx_socket_t s;
ngx_connection_t *c;
@@ -68,29 +69,36 @@ int ngx_event_post_acceptex(ngx_listen_t *ls, int n)
/* TODO: look up reused sockets */
- ngx_log_debug(ls->log, "socket: %x" _ ls->flags);
-
s = ngx_socket(ls->family, ls->type, ls->protocol, ls->flags);
+ ngx_log_debug(ls->log, ngx_socket_n ": %d:%d" _ s _ ls->flags);
if (s == -1) {
ngx_log_error(NGX_LOG_ALERT, ls->log, ngx_socket_errno,
- ngx_socket_n " for AcceptEx() post failed");
+ ngx_socket_n " for AcceptEx() %s post failed",
+ ls->addr_text.data);
return NGX_ERROR;
}
- ngx_test_null(pool, ngx_create_pool(ls->pool_size, ls->log), NGX_ERROR);
+ /*
+ * Winsock assignes a socket number divisible by 4
+ * so to find a connection we divide a socket number by 4.
+ */
+
+ if (s % 4) {
+ ngx_log_error(NGX_LOG_EMERG, ls->log, 0,
+ ngx_socket_n " created socket %d", s);
+ exit(1);
+ }
- rev = &ngx_read_events[s];
- wev = &ngx_write_events[s];
- c = &ngx_connections[s];
+ rev = &ngx_read_events[s / 4];
+ wev = &ngx_write_events[s / 4];
+ c = &ngx_connections[s / 4];
ngx_memzero(rev, sizeof(ngx_event_t));
ngx_memzero(wev, sizeof(ngx_event_t));
ngx_memzero(c, sizeof(ngx_connection_t));
- c->pool = pool;
-
rev->index = wev->index = NGX_INVALID_INDEX;
rev->ovlp.event = rev;
@@ -100,53 +108,55 @@ int ngx_event_post_acceptex(ngx_listen_t *ls, int n)
c->read = rev;
c->write = wev;
- c->family = ls->family;
- c->socklen = ls->socklen;
- c->addr = ls->addr;
- c->addr_text_max_len = ls->addr_text_max_len;
- c->post_accept_timeout = ls->post_accept_timeout;
-
c->listening = ls;
c->fd = s;
+ c->ctx = ls->ctx;
+ c->servers = ls->servers;
+
c->unexpected_eof = 1;
wev->write = 1;
-
- c->handler = ls->handler;
rev->event_handler = ngx_event_acceptex;
- c->ctx = ls->ctx;
- c->servers = ls->servers;
+ ngx_test_null(c->pool,
+ ngx_create_pool(ls->pool_size, ls->log),
+ NGX_ERROR);
- ngx_test_null(c->data, ngx_palloc(pool, 2 * (c->socklen + 16)),
+ ngx_test_null(c->buffer,
+ ngx_create_temp_hunk(c->pool,
+ ls->post_accept_buffer_size
+ + 2 * (c->listening->socklen + 16),
+ 0, 0),
NGX_ERROR);
- ngx_test_null(c->local_sockaddr, ngx_palloc(pool, c->socklen),
+
+ ngx_test_null(c->local_sockaddr, ngx_palloc(c->pool, ls->socklen),
NGX_ERROR);
- ngx_test_null(c->sockaddr, ngx_palloc(pool, c->socklen),
+
+ ngx_test_null(c->sockaddr, ngx_palloc(c->pool, ls->socklen),
NGX_ERROR);
ngx_test_null(c->log, ngx_palloc(c->pool, sizeof(ngx_log_t)),
NGX_ERROR);
+
ngx_memcpy(c->log, ls->log, sizeof(ngx_log_t));
- rev->log = wev->log = c->log;
+ c->read->log = c->write->log = c->log;
if (ngx_add_event(rev, 0, NGX_IOCP_IO) == NGX_ERROR) {
return NGX_ERROR;
}
- if (acceptex(ls->fd, s, c->data, 0,
- c->socklen + 16, c->socklen + 16,
- &rcvd, (LPOVERLAPPED) &rev->ovlp) == 0) {
+ if (acceptex(ls->fd, s, c->buffer->pos, ls->post_accept_buffer_size,
+ ls->socklen + 16, ls->socklen + 16,
+ &rcvd, (LPOVERLAPPED) &rev->ovlp) == 0)
+ {
err = ngx_socket_errno;
- if (err == WSA_IO_PENDING) {
- return NGX_OK;
- }
+ if (err != WSA_IO_PENDING) {
+ ngx_log_error(NGX_LOG_ALERT, ls->log, err,
+ "AcceptEx() %s falied", ls->addr_text.data);
- ngx_log_error(NGX_LOG_ALERT, ls->log, err,
- "AcceptEx(%s) falied", ls->addr_text.data);
-
- return NGX_ERROR;
+ return NGX_ERROR;
+ }
}
}
diff --git a/src/event/ngx_event_timer.c b/src/event/ngx_event_timer.c
index 44fb14a57..081afdb25 100644
--- a/src/event/ngx_event_timer.c
+++ b/src/event/ngx_event_timer.c
@@ -1,14 +1,8 @@
#include <ngx_config.h>
-
#include <ngx_core.h>
-#include <ngx_log.h>
-#include <ngx_alloc.h>
-#include <ngx_connection.h>
#include <ngx_event.h>
-#include <ngx_event_timer.h>
-
static ngx_event_t *ngx_timer_queue;
static int ngx_timer_cur_queue;
@@ -49,7 +43,7 @@ void ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer)
ngx_event_t *e;
#if (NGX_DEBUG_EVENT)
- ngx_connection_t *c = (ngx_connection_t *) ev->data;
+ ngx_connection_t *c = ev->data;
ngx_log_debug(ev->log, "set timer: %d:%d, slot: %d" _
c->fd _ timer _ ngx_timer_cur_queue);
#endif
diff --git a/src/event/ngx_event_timer.h b/src/event/ngx_event_timer.h
index cb024a38f..2704c58c9 100644
--- a/src/event/ngx_event_timer.h
+++ b/src/event/ngx_event_timer.h
@@ -3,9 +3,7 @@
#include <ngx_config.h>
-
-#include <ngx_log.h>
-#include <ngx_connection.h>
+#include <ngx_core.h>
#include <ngx_event.h>
@@ -20,8 +18,8 @@ void ngx_event_expire_timers(ngx_msec_t timer);
ngx_inline static void ngx_event_del_timer(ngx_event_t *ev)
{
#if (NGX_DEBUG_EVENT)
- /* STUB - we can not cast (ngx_connection_t *) here */
- ngx_log_debug(ev->log, "del timer: %d" _ *(int *)(ev->data));
+ ngx_connection_t *c = ev->data;
+ ngx_log_debug(ev->log, "del timer: %d" _ c->fd);
#endif
if (!ev->timer_next || !ev->timer_prev) {
diff --git a/src/http/modules/ngx_http_chunked_filter.c b/src/http/modules/ngx_http_chunked_filter.c
index 75a0cdfd6..bdd0a7c7a 100644
--- a/src/http/modules/ngx_http_chunked_filter.c
+++ b/src/http/modules/ngx_http_chunked_filter.c
@@ -85,7 +85,7 @@ static int ngx_http_chunked_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
}
ngx_test_null(chunk, ngx_palloc(r->pool, 11), NGX_ERROR);
- len = ngx_snprintf(chunk, 11, "%x" CRLF, size);
+ len = ngx_snprintf(chunk, 11, SIZEX_FMT CRLF, size);
ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR);
h->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP;
diff --git a/src/http/modules/ngx_http_index_handler.c b/src/http/modules/ngx_http_index_handler.c
index cc7c92790..ffb9779bf 100644
--- a/src/http/modules/ngx_http_index_handler.c
+++ b/src/http/modules/ngx_http_index_handler.c
@@ -240,7 +240,7 @@ static char *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, void *child)
if (conf->max_index_len == 0) {
if (prev->max_index_len != 0) {
- ngx_memcpy(conf, prev, sizeof(ngx_http_index_conf_t));
+ ngx_memcpy(conf, prev, sizeof(ngx_http_index_conf_t));
return NGX_CONF_OK;
}
diff --git a/src/http/modules/ngx_http_range_filter.c b/src/http/modules/ngx_http_range_filter.c
index d32123b12..d0273ec1c 100644
--- a/src/http/modules/ngx_http_range_filter.c
+++ b/src/http/modules/ngx_http_range_filter.c
@@ -61,6 +61,10 @@ static int ngx_http_range_header_filter(ngx_http_request_t *r)
ngx_init_array(r->headers_out.ranges, r->pool, 5, sizeof(ngx_http_range_t),
NGX_ERROR);
+#if (NGX_SUPPRESS_WARN)
+ range = NULL;
+#endif
+
rc = 0;
p = r->headers_in.range->value.data + 6;
@@ -149,7 +153,7 @@ static int ngx_http_range_header_filter(ngx_http_request_t *r)
ngx_palloc(r->pool, 8 + 20 + 1),
NGX_ERROR);
- r->headers_out.content_range->value.len =
+ r->headers_out.content_range->value.len =
ngx_snprintf(r->headers_out.content_range->value.data,
8 + 20 + 1, "bytes */" OFF_FMT,
r->headers_out.content_length);
@@ -170,7 +174,7 @@ static int ngx_http_range_header_filter(ngx_http_request_t *r)
ngx_palloc(r->pool, 6 + 20 + 1 + 20 + 1 + 20 + 1),
NGX_ERROR);
- r->headers_out.content_range->value.len =
+ r->headers_out.content_range->value.len =
ngx_snprintf(r->headers_out.content_range->value.data,
6 + 20 + 1 + 20 + 1 + 20 + 1,
"bytes " OFF_FMT "-" OFF_FMT "/" OFF_FMT,
@@ -244,7 +248,7 @@ static int ngx_http_range_header_filter(ngx_http_request_t *r)
ngx_palloc(r->pool, 20 + 1 + 20 + 1 + 20 + 5),
NGX_ERROR);
- range[i].content_range.len =
+ range[i].content_range.len =
ngx_snprintf(range[i].content_range.data,
20 + 1 + 20 + 1 + 20 + 5,
OFF_FMT "-" OFF_FMT "/" OFF_FMT CRLF CRLF,
diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c
index 44b650e0c..005f230fb 100644
--- a/src/http/ngx_http.c
+++ b/src/http/ngx_http.c
@@ -1,13 +1,10 @@
#include <ngx_config.h>
#include <ngx_core.h>
-
-#include <ngx_listen.h>
-
+#include <ngx_event.h>
#include <ngx_http.h>
-static void ngx_http_init_filters(ngx_pool_t *pool, ngx_module_t **modules);
static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
@@ -54,17 +51,20 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
char *rv;
struct sockaddr_in *addr_in;
ngx_array_t in_ports;
- ngx_listen_t *ls;
+ ngx_listening_t *ls;
ngx_http_module_t *module;
ngx_conf_t pcf;
ngx_http_conf_ctx_t *ctx;
ngx_http_in_port_t *in_port, *inport;
ngx_http_in_addr_t *in_addr, *inaddr;
ngx_http_core_main_conf_t *cmcf;
- ngx_http_core_srv_conf_t **cscfp;
+ ngx_http_core_srv_conf_t **cscfp, *cscf;
ngx_http_core_loc_conf_t **clcfp;
ngx_http_listen_t *lscf;
ngx_http_server_name_t *s_name, *name;
+#if (WIN32)
+ ngx_iocp_conf_t *iocpcf;
+#endif
/* the main http context */
ngx_test_null(ctx,
@@ -431,7 +431,7 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_test_null(ls, ngx_push_array(&ngx_listening_sockets),
NGX_CONF_ERROR);
- ngx_memzero(ls, sizeof(ngx_listen_t));
+ ngx_memzero(ls, sizeof(ngx_listening_t));
ngx_test_null(addr_in,
ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in)),
@@ -456,7 +456,7 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ls->family = AF_INET;
ls->type = SOCK_STREAM;
ls->protocol = IPPROTO_IP;
-#if (NGX_OVERLAPPED)
+#if (WIN32)
ls->flags = WSA_FLAG_OVERLAPPED;
#endif
ls->sockaddr = (struct sockaddr *) addr_in;
@@ -468,8 +468,18 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ls->handler = ngx_http_init_connection;
ls->log = cf->log;
- ls->pool_size = cmcf->connection_pool_size;
- ls->post_accept_timeout = cmcf->post_accept_timeout;
+
+ cscf = in_addr[a].core_srv_conf;
+ ls->pool_size = cscf->connection_pool_size;
+ ls->post_accept_timeout = cscf->post_accept_timeout;
+
+#if (WIN32)
+ iocpcf = ngx_event_get_conf(ngx_iocp_module);
+ if (iocpcf->acceptex_read) {
+ ls->post_accept_buffer_size = cscf->client_header_buffer_size;
+ }
+#endif
+
ls->ctx = ctx;
if (in_port[p].addrs.nelts > 1) {
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 08a9980ea..a4e6023c3 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -1,10 +1,6 @@
#include <ngx_config.h>
#include <ngx_core.h>
-
-/* ???? */
-#include <ngx_listen.h>
-
#include <ngx_http.h>
#include <nginx.h>
@@ -46,17 +42,17 @@ static ngx_command_t ngx_http_core_commands[] = {
NULL},
{ngx_string("connection_pool_size"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
ngx_conf_set_size_slot,
- NGX_HTTP_MAIN_CONF_OFFSET,
- offsetof(ngx_http_core_main_conf_t, connection_pool_size),
+ NGX_HTTP_SRV_CONF_OFFSET,
+ offsetof(ngx_http_core_srv_conf_t, connection_pool_size),
NULL},
{ngx_string("post_accept_timeout"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
ngx_conf_set_msec_slot,
- NGX_HTTP_MAIN_CONF_OFFSET,
- offsetof(ngx_http_core_main_conf_t, post_accept_timeout),
+ NGX_HTTP_SRV_CONF_OFFSET,
+ offsetof(ngx_http_core_srv_conf_t, post_accept_timeout),
NULL},
{ngx_string("request_pool_size"),
@@ -738,9 +734,6 @@ static void *ngx_http_core_create_main_conf(ngx_pool_t *pool)
ngx_palloc(pool, sizeof(ngx_http_core_main_conf_t)),
NGX_CONF_ERROR);
- cmcf->connection_pool_size = NGX_CONF_UNSET;
- cmcf->post_accept_timeout = NGX_CONF_UNSET;
-
ngx_init_array(cmcf->servers, pool, 5, sizeof(ngx_http_core_srv_conf_t *),
NGX_CONF_ERROR);
@@ -752,8 +745,7 @@ static char *ngx_http_core_init_main_conf(ngx_pool_t *pool, void *conf)
{
ngx_http_core_main_conf_t *cmcf = conf;
- ngx_conf_init_size_value(cmcf->connection_pool_size, 16384);
- ngx_conf_init_msec_value(cmcf->post_accept_timeout, 30000);
+ /* TODO: remove it if no directives */
return NGX_CONF_OK;
}
@@ -773,6 +765,8 @@ static void *ngx_http_core_create_srv_conf(ngx_pool_t *pool)
ngx_init_array(cscf->server_names, pool, 5, sizeof(ngx_http_server_name_t),
NGX_CONF_ERROR);
+ cscf->connection_pool_size = NGX_CONF_UNSET;
+ cscf->post_accept_timeout = NGX_CONF_UNSET;
cscf->request_pool_size = NGX_CONF_UNSET;
cscf->client_header_timeout = NGX_CONF_UNSET;
cscf->client_header_buffer_size = NGX_CONF_UNSET;
@@ -827,6 +821,10 @@ static char *ngx_http_core_merge_srv_conf(ngx_pool_t *pool,
n->core_srv_conf = conf;
}
+ ngx_conf_merge_size_value(conf->connection_pool_size,
+ prev->connection_pool_size, 16384);
+ ngx_conf_merge_msec_value(conf->post_accept_timeout,
+ prev->post_accept_timeout, 30000);
ngx_conf_merge_size_value(conf->request_pool_size,
prev->request_pool_size, 16384);
ngx_conf_merge_msec_value(conf->client_header_timeout,
@@ -945,7 +943,7 @@ static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_str_t *args;
ngx_http_listen_t *ls;
- /* TODO: check duplicate 'listen' directives,
+ /* TODO: check duplicate 'listen' directives,
add resolved name to server names ??? */
ngx_test_null(ls, ngx_push_array(&scf->listen), NGX_CONF_ERROR);
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index 113c197a8..4cf966a1d 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -18,9 +18,6 @@ typedef struct {
typedef struct {
- int connection_pool_size;
- int post_accept_timeout;
-
ngx_array_t servers; /* array of ngx_http_core_srv_conf_t */
} ngx_http_core_main_conf_t;
@@ -36,6 +33,8 @@ typedef struct {
ngx_http_conf_ctx_t *ctx; /* server ctx */
+ ngx_msec_t post_accept_timeout;
+ ssize_t connection_pool_size;
size_t request_pool_size;
ngx_msec_t client_header_timeout;
size_t client_header_buffer_size;
diff --git a/src/http/ngx_http_event.c b/src/http/ngx_http_event.c
index be6d3910a..991b87d3b 100644
--- a/src/http/ngx_http_event.c
+++ b/src/http/ngx_http_event.c
@@ -67,14 +67,15 @@ void ngx_http_init_connection(ngx_connection_t *c)
ngx_event_t *rev;
ngx_http_log_ctx_t *lcx;
- c->addr_text.data = ngx_palloc(c->pool, c->addr_text_max_len);
+ c->addr_text.data = ngx_palloc(c->pool, c->listening->addr_text_max_len);
if (c->addr_text.data == NULL) {
ngx_http_close_connection(c);
return;
}
- c->addr_text.len = ngx_sock_ntop(c->family, c->sockaddr,
- c->addr_text.data, c->addr_text_max_len);
+ c->addr_text.len = ngx_sock_ntop(c->listening->family, c->sockaddr,
+ c->addr_text.data,
+ c->listening->addr_text_max_len);
if (c->addr_text.len == 0) {
ngx_http_close_connection(c);
return;
@@ -100,7 +101,7 @@ void ngx_http_init_connection(ngx_connection_t *c)
return;
}
- ngx_add_timer(rev, c->post_accept_timeout);
+ ngx_add_timer(rev, c->listening->post_accept_timeout);
rev->timer_set = 1;
if (ngx_event_flags & (NGX_HAVE_AIO_EVENT|NGX_HAVE_EDGE_EVENT)) {
@@ -158,19 +159,30 @@ static void ngx_http_init_request(ngx_event_t *rev)
if (in_port->addrs.nelts > 1) {
- /* there're the several addresses on this port and one of them
- is "*:port" so getsockname() is needed to determine
- the server address */
+ /*
+ * there're the several addresses on this port and one of them
+ * is "*:port" so getsockname() is needed to determine
+ * the server address.
+ * AcceptEx() already gave this address.
+ */
- /* TODO: AcceptEx() already gave this sockaddr_in */
+#if (WIN32)
+ if (c->local_sockaddr) {
+ r->in_addr =
+ ((struct sockaddr_in *) c->local_sockaddr)->sin_addr.s_addr;
- len = sizeof(struct sockaddr_in);
- if (getsockname(c->fd, (struct sockaddr *) &addr_in, &len) == -1) {
- ngx_log_error(NGX_LOG_CRIT, rev->log, ngx_socket_errno,
- "getsockname() failed");
- ngx_http_close_connection(c);
- return;
+ } else {
+#endif
+ len = sizeof(struct sockaddr_in);
+ if (getsockname(c->fd, (struct sockaddr *) &addr_in, &len) == -1) {
+ ngx_log_error(NGX_LOG_CRIT, rev->log, ngx_socket_errno,
+ "getsockname() failed");
+ ngx_http_close_connection(c);
+ return;
+ }
+#if (WIN32)
}
+#endif
r->in_addr = addr_in.sin_addr.s_addr;
@@ -689,18 +701,19 @@ static ssize_t ngx_http_read_request_header(ngx_http_request_t *r)
ngx_event_t *rev;
ngx_http_core_srv_conf_t *cscf;
+ rev = r->connection->read;
+
n = r->header_in->last - r->header_in->pos;
if (n > 0) {
+ rev->ready = 0;
return n;
}
- n = ngx_event_recv(r->connection, r->header_in->last,
- r->header_in->end - r->header_in->last);
+ n = ngx_recv(r->connection, r->header_in->last,
+ r->header_in->end - r->header_in->last);
if (n == NGX_AGAIN) {
- rev = r->connection->read;
-
if (!r->header_timeout_set) {
if (rev->timer_set) {
ngx_del_timer(rev);
@@ -773,6 +786,20 @@ void ngx_http_finalize_request(ngx_http_request_t *r, int error)
}
rc = ngx_http_special_response_handler(r, rc);
+
+ if (rc == NGX_AGAIN) {
+ return;
+ }
+
+ if (rc == NGX_ERROR) {
+ ngx_http_close_request(r, 0);
+ ngx_http_close_connection(r->connection);
+ return;
+ }
+
+ } else if (rc == NGX_ERROR) {
+ r->keepalive = 0;
+ r->lingering_close = 0;
}
rev = r->connection->read;
@@ -1028,7 +1055,7 @@ static int ngx_http_read_discarded_body(ngx_http_request_t *r)
size = clcf->discarded_buffer_size;
}
- n = ngx_event_recv(r->connection, r->discarded_buffer, size);
+ n = ngx_recv(r->connection, r->discarded_buffer, size);
if (n == NGX_ERROR) {
return NGX_HTTP_BAD_REQUEST;
}
@@ -1169,7 +1196,7 @@ static void ngx_http_keepalive_handler(ngx_event_t *rev)
rev->ignore_econnreset = 1;
ngx_set_socket_errno(0);
- n = ngx_event_recv(c, c->buffer->last, c->buffer->end - c->buffer->last);
+ n = ngx_recv(c, c->buffer->last, c->buffer->end - c->buffer->last);
rev->ignore_econnreset = 0;
if (n == NGX_AGAIN) {
@@ -1307,7 +1334,7 @@ static void ngx_http_lingering_close_handler(ngx_event_t *rev)
}
do {
- n = ngx_event_recv(c, r->discarded_buffer, clcf->discarded_buffer_size);
+ n = ngx_recv(c, r->discarded_buffer, clcf->discarded_buffer_size);
ngx_log_debug(c->log, "lingering read: %d" _ n);
diff --git a/src/http/ngx_http_output_filter.c b/src/http/ngx_http_output_filter.c
index c0c4dd4cf..7ee6a9673 100644
--- a/src/http/ngx_http_output_filter.c
+++ b/src/http/ngx_http_output_filter.c
@@ -5,7 +5,7 @@
typedef struct {
- size_t hunk_size;
+ ssize_t hunk_size;
} ngx_http_output_filter_conf_t;
diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c
index 9a5dea1f8..9e3bb9ae3 100644
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -12,6 +12,16 @@ static char error_tail[] =
;
+static char msie_stub[] =
+"<!-- The padding to disable MSIE's friendly error page -->" CRLF
+"<!-- The padding to disable MSIE's friendly error page -->" CRLF
+"<!-- The padding to disable MSIE's friendly error page -->" CRLF
+"<!-- The padding to disable MSIE's friendly error page -->" CRLF
+"<!-- The padding to disable MSIE's friendly error page -->" CRLF
+"<!-- The padding to disable MSIE's friendly error page -->" CRLF
+;
+
+
static char error_302_page[] =
"<html>" CRLF
"<head><title>302 Found</title></head>" CRLF
@@ -134,8 +144,8 @@ static ngx_str_t error_pages[] = {
int ngx_http_special_response_handler(ngx_http_request_t *r, int error)
{
- int err;
- ngx_hunk_t *message, *tail;
+ int err, rc;
+ ngx_hunk_t *h;
r->headers_out.status = error;
@@ -172,7 +182,8 @@ int ngx_http_special_response_handler(ngx_http_request_t *r, int error)
if (error_pages[err].len) {
r->headers_out.content_length = error_pages[err].len
- + sizeof(error_tail);
+ + sizeof(error_tail) - 1
+ + sizeof(msie_stub) - 1;
ngx_test_null(r->headers_out.content_type,
ngx_push_table(r->headers_out.headers),
@@ -187,29 +198,63 @@ int ngx_http_special_response_handler(ngx_http_request_t *r, int error)
r->headers_out.content_length = -1;
}
- if (ngx_http_send_header(r) == NGX_ERROR) {
+ rc = ngx_http_send_header(r);
+ if (rc == NGX_ERROR) {
return NGX_ERROR;
}
+ if (r->header_only) {
+ if (rc == NGX_AGAIN) {
+ ngx_http_set_write_handler(r);
+ return NGX_AGAIN;
+ }
+
+ return NGX_OK;
+ }
+
if (error_pages[err].len == 0) {
return NGX_OK;
}
- ngx_test_null(message, ngx_pcalloc(r->pool, sizeof(ngx_hunk_t)), NGX_ERROR);
+ ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR);
- message->type = NGX_HUNK_MEMORY|NGX_HUNK_IN_MEMORY;
- message->pos = error_pages[err].data;
- message->last = error_pages[err].data + error_pages[err].len;
+ h->type = NGX_HUNK_MEMORY|NGX_HUNK_IN_MEMORY;
+ h->pos = error_pages[err].data;
+ h->last = error_pages[err].data + error_pages[err].len;
- if (ngx_http_output_filter(r, message) == NGX_ERROR) {
+ if (ngx_http_output_filter(r, h) == NGX_ERROR) {
return NGX_ERROR;
}
- ngx_test_null(tail, ngx_pcalloc(r->pool, sizeof(ngx_hunk_t)), NGX_ERROR);
+ ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR);
+
+ h->type = NGX_HUNK_MEMORY|NGX_HUNK_IN_MEMORY;
+ h->pos = error_tail;
+ h->last = error_tail + sizeof(error_tail) - 1;
+
+ if (1) {
+ if (ngx_http_output_filter(r, h) == NGX_ERROR) {
+ return NGX_ERROR;
+ }
+
+ ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR);
+
+ h->type = NGX_HUNK_MEMORY|NGX_HUNK_IN_MEMORY;
+ h->pos = msie_stub;
+ h->last = msie_stub + sizeof(msie_stub) - 1;
+ }
+
+ h->type |= NGX_HUNK_LAST;
+
+ rc = ngx_http_output_filter(r, h);
+
+ if (r->main == NULL) {
+ if (rc == NGX_AGAIN) {
+ ngx_http_set_write_handler(r);
+ return NGX_AGAIN;
+ }
+ }
- tail->type = NGX_HUNK_MEMORY|NGX_HUNK_LAST|NGX_HUNK_IN_MEMORY;
- tail->pos = error_tail;
- tail->last = error_tail + sizeof(error_tail);
+ return NGX_OK;
- return ngx_http_output_filter(r, tail);
}
diff --git a/src/http/ngx_http_write_filter.c b/src/http/ngx_http_write_filter.c
index 59d4a6925..6b76f7390 100644
--- a/src/http/ngx_http_write_filter.c
+++ b/src/http/ngx_http_write_filter.c
@@ -1,11 +1,12 @@
#include <ngx_config.h>
#include <ngx_core.h>
+#include <ngx_event.h>
#include <ngx_http.h>
typedef struct {
- size_t buffer_output;
+ ssize_t buffer_output;
} ngx_http_write_filter_conf_t;
@@ -139,11 +140,7 @@ int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
return NGX_AGAIN;
}
-#if 1
chain = ngx_write_chain(r->connection, ctx->out);
-#else
- chain = ngx_write_chain(r->connection, ctx->out, flush);
-#endif
#if (NGX_DEBUG_WRITE_FILTER)
ngx_log_debug(r->connection->log, "write filter %x" _ chain);
diff --git a/src/os/unix/ngx_aio_read.c b/src/os/unix/ngx_aio_read.c
index 4896af9ce..bc5055860 100644
--- a/src/os/unix/ngx_aio_read.c
+++ b/src/os/unix/ngx_aio_read.c
@@ -1,6 +1,7 @@
#include <ngx_config.h>
#include <ngx_core.h>
+#include <ngx_event.h>
#include <ngx_aio.h>
#if (HAVE_KQUEUE)
diff --git a/src/os/unix/ngx_aio_write.c b/src/os/unix/ngx_aio_write.c
index 918535aa7..3a4d8e0b4 100644
--- a/src/os/unix/ngx_aio_write.c
+++ b/src/os/unix/ngx_aio_write.c
@@ -1,6 +1,7 @@
#include <ngx_config.h>
#include <ngx_core.h>
+#include <ngx_event.h>
#include <ngx_aio.h>
#if (HAVE_KQUEUE)
@@ -29,6 +30,7 @@ ssize_t ngx_aio_write(ngx_connection_t *c, char *buf, size_t size)
ngx_log_debug(ev->log, "aio: ev->ready: %d" _ ev->ready);
ngx_log_debug(ev->log, "aio: aiocb: %08x" _ &ev->aiocb);
+#if 0
if (ev->timedout) {
ngx_set_socket_errno(NGX_ETIMEDOUT);
ngx_log_error(NGX_LOG_ERR, ev->log, 0, "aio_write() timed out");
@@ -46,6 +48,7 @@ ngx_log_debug(ev->log, "aio: aiocb: %08x" _ &ev->aiocb);
ev->ready = 1;
}
+#endif
first = 0;
diff --git a/src/os/unix/ngx_freebsd_config.h b/src/os/unix/ngx_freebsd_config.h
index 0a7eedd10..6fd0a694e 100644
--- a/src/os/unix/ngx_freebsd_config.h
+++ b/src/os/unix/ngx_freebsd_config.h
@@ -22,9 +22,22 @@
#include <osreldate.h>
-#define QD_FMT "%qd"
-#define QX_FMT "%qx"
-#define OFF_FMT "%qd"
+/* STUB */
+#define QD_FMT "%lld"
+#define QX_FMT "%llx"
+/**/
+
+#if (i386)
+#define OFF_FMT "%lld"
+#define SIZE_FMT "%d"
+#define SIZEX_FMT "%x"
+#else
+#define OFF_FMT "%ld"
+#define SIZE_FMT "%ld"
+#define SIZEX_FMT "%lx"
+#endif
+
+#define PID_FMT "%d"
#ifndef HAVE_SELECT
diff --git a/src/os/unix/ngx_freebsd_sendfile_chain.c b/src/os/unix/ngx_freebsd_sendfile_chain.c
index a888c3613..a3c813e38 100644
--- a/src/os/unix/ngx_freebsd_sendfile_chain.c
+++ b/src/os/unix/ngx_freebsd_sendfile_chain.c
@@ -15,7 +15,8 @@
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 4.5+ only.
+ So we use TCP_NOPUSH on FreeBSD prior to 4.5 only if the connection
+ is not needed not keepalive.
*/
@@ -23,7 +24,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
{
int rc, eintr, tcp_nopush;
char *prev;
- size_t hsize, size;
+ ssize_t hsize, size;
off_t sent;
struct iovec *iov;
struct sf_hdtr hdtr;
diff --git a/src/os/unix/ngx_linux_config.h b/src/os/unix/ngx_linux_config.h
index 96e1d8856..27fa317bc 100644
--- a/src/os/unix/ngx_linux_config.h
+++ b/src/os/unix/ngx_linux_config.h
@@ -29,14 +29,11 @@
#include <netdb.h>
-typedef unsigned int u_int;
-typedef unsigned short u_short;
-typedef unsigned char u_char;
-
-#define QD_FMT "%qd"
-#define QX_FMT "%qx"
-#define OFF_FMT "%qd"
+#define QD_FMT "%qd"
+#define QX_FMT "%qx"
+#define OFF_FMT "%qd"
+#define PID_FMT "%d"
#ifndef HAVE_SELECT
@@ -63,7 +60,7 @@ typedef unsigned char u_char;
#ifndef HAVE_FIONBIO
-#define HAVE_FIONBIO 1
+#define HAVE_FIONBIO 1
#endif
diff --git a/src/os/unix/ngx_readv_chain.c b/src/os/unix/ngx_readv_chain.c
index 8432f0c8d..744bf99bc 100644
--- a/src/os/unix/ngx_readv_chain.c
+++ b/src/os/unix/ngx_readv_chain.c
@@ -1,6 +1,7 @@
#include <ngx_config.h>
#include <ngx_core.h>
+#include <ngx_event.h>
ssize_t ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *entry)
diff --git a/src/os/unix/ngx_recv.c b/src/os/unix/ngx_recv.c
index 98607d0c7..154565413 100644
--- a/src/os/unix/ngx_recv.c
+++ b/src/os/unix/ngx_recv.c
@@ -1,6 +1,7 @@
#include <ngx_config.h>
#include <ngx_core.h>
+#include <ngx_event.h>
static int ngx_unix_recv_error(ngx_event_t *rev, ngx_err_t err);
diff --git a/src/os/unix/ngx_socket.c b/src/os/unix/ngx_socket.c
index 941fc8cd1..48016cb10 100644
--- a/src/os/unix/ngx_socket.c
+++ b/src/os/unix/ngx_socket.c
@@ -55,8 +55,7 @@ int ngx_tcp_push(ngx_socket_t s)
(const void *) &tcp_nopush, sizeof(int));
}
-#else
-
+#else
int ngx_tcp_nopush(ngx_socket_t s)
{
diff --git a/src/os/unix/ngx_solaris_config.h b/src/os/unix/ngx_solaris_config.h
index e7946449d..78eeb7213 100644
--- a/src/os/unix/ngx_solaris_config.h
+++ b/src/os/unix/ngx_solaris_config.h
@@ -30,6 +30,7 @@ typedef uint32_t u_int32_t;
#define QD_FMT "%lld"
#define QX_FMT "%llx"
#define OFF_FMT "%lld"
+#define PID_FMT "%ld"
#ifndef HAVE_SELECT
@@ -62,7 +63,7 @@ typedef uint32_t u_int32_t;
#ifndef HAVE_FIONBIO
-#define HAVE_FIONBIO 1
+#define HAVE_FIONBIO 1
#endif
diff --git a/src/os/unix/ngx_writev_chain.c b/src/os/unix/ngx_writev_chain.c
index b667bc507..32b2dd48d 100644
--- a/src/os/unix/ngx_writev_chain.c
+++ b/src/os/unix/ngx_writev_chain.c
@@ -6,15 +6,14 @@
ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in)
{
char *prev;
- size_t size;
- ssize_t n;
+ ssize_t n, size;
off_t sent;
struct iovec *iov;
ngx_err_t err;
- ngx_array_t io;
+ ngx_array_t iovecs;
ngx_chain_t *ce;
- ngx_init_array(io, c->pool, 10, sizeof(struct iovec), NGX_CHAIN_ERROR);
+ ngx_init_array(iovecs, c->pool, 10, sizeof(struct iovec), NGX_CHAIN_ERROR);
prev = NULL;
iov = NULL;
@@ -27,14 +26,14 @@ ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in)
prev = ce->hunk->last;
} else {
- ngx_test_null(iov, ngx_push_array(&io), NGX_CHAIN_ERROR);
+ ngx_test_null(iov, ngx_push_array(&iovecs), NGX_CHAIN_ERROR);
iov->iov_base = ce->hunk->pos;
iov->iov_len = ce->hunk->last - ce->hunk->pos;
prev = ce->hunk->last;
}
}
- n = writev(c->fd, (struct iovec *) io.elts, io.nelts);
+ n = writev(c->fd, iovecs.elts, iovecs.nelts);
if (n == -1) {
err = ngx_errno;
@@ -93,7 +92,7 @@ ngx_log_debug(c->log, "SIZE: %d" _ size);
break;
}
- ngx_destroy_array(&io);
+ ngx_destroy_array(&iovecs);
return ce;
}
diff --git a/src/os/win32/ngx_errno.c b/src/os/win32/ngx_errno.c
index d0cff7b73..30c1b9315 100644
--- a/src/os/win32/ngx_errno.c
+++ b/src/os/win32/ngx_errno.c
@@ -9,9 +9,29 @@
#include <ngx_core.h>
+ngx_str_t wsa_errors[] = {
+ ngx_string("Invalid argument"), /* 10022 */
+ ngx_null_string, /* 10023 */
+ ngx_null_string, /* 10024 */
+ ngx_null_string, /* 10025 */
+ ngx_null_string, /* 10026 */
+ ngx_null_string, /* 10027 */
+ ngx_null_string, /* 10028 */
+ ngx_null_string, /* 10029 */
+ ngx_null_string, /* 10030 */
+ ngx_null_string, /* 10031 */
+ ngx_null_string, /* 10032 */
+ ngx_null_string, /* 10033 */
+ ngx_null_string, /* 10034 */
+ ngx_string("Resource temporarily unavailable") /* 10035 */
+};
+
+
int ngx_strerror_r(ngx_err_t err, char *errstr, size_t size)
{
- int len;
+ int n;
+ u_int len;
+ ngx_err_t format_error;
len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS,
@@ -19,12 +39,28 @@ int ngx_strerror_r(ngx_err_t err, char *errstr, size_t size)
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
errstr, size, NULL);
- /* add WSA error messages */
-
if (len == 0) {
+ format_error = GetLastError();
+
+ if (format_error == ERROR_MR_MID_NOT_FOUND) {
+ n = err - WSABASEERR - 22;
+
+ if (n >= 0 && n < 14) {
+ len = wsa_errors[n].len;
+
+ if (len) {
+ if (len > size) {
+ len = size;
+ }
+
+ ngx_memcpy(errstr, wsa_errors[n].data, len);
+ return len;
+ }
+ }
+ }
len = ngx_snprintf(errstr, size,
- "FormatMessage error:(%d)", GetLastError());
+ "FormatMessage() error:(%d)", format_error);
return len;
}
diff --git a/src/os/win32/ngx_os_init.h b/src/os/win32/ngx_os_init.h
index 4a00a3a05..8ab820694 100644
--- a/src/os/win32/ngx_os_init.h
+++ b/src/os/win32/ngx_os_init.h
@@ -8,5 +8,7 @@
int ngx_os_init(ngx_log_t *log);
+ssize_t ngx_wsarecv(ngx_connection_t *c, char *buf, size_t size);
+
#endif /* _NGX_OS_INIT_H_INCLUDED_ */
diff --git a/src/os/win32/ngx_socket.h b/src/os/win32/ngx_socket.h
index f86a39aff..55629a1a9 100644
--- a/src/os/win32/ngx_socket.h
+++ b/src/os/win32/ngx_socket.h
@@ -16,6 +16,7 @@ typedef int socklen_t;
#define ngx_socket(af, type, proto, flags) \
WSASocket(af, type, proto, NULL, 0, flags)
+
#define ngx_socket_n "WSASocket()"
int ngx_nonblocking(ngx_socket_t s);
@@ -36,4 +37,11 @@ extern LPFN_GETACCEPTEXSOCKADDRS getacceptexsockaddrs;
extern LPFN_TRANSMITFILE transmitfile;
+ngx_inline int ngx_tcp_push(s) {
+ return 0;
+}
+
+#define ngx_tcp_push_n "tcp_push()"
+
+
#endif /* _NGX_SOCKET_H_INCLUDED_ */
diff --git a/src/os/win32/ngx_types.h b/src/os/win32/ngx_types.h
index 1c4ff0c02..b858faee9 100644
--- a/src/os/win32/ngx_types.h
+++ b/src/os/win32/ngx_types.h
@@ -19,6 +19,7 @@ typedef BY_HANDLE_FILE_INFORMATION ngx_file_info_t;
#define QD_FMT "%I64d"
#define QX_FMT "%I64x"
#define OFF_FMT "%I64d"
+#define PID_FMT "%d"
#endif /* _NGX_TYPES_H_INCLUDED_ */
diff --git a/src/os/win32/ngx_init.c b/src/os/win32/ngx_win32_init.c
index c57ce6c9d..6bc69e4c9 100644
--- a/src/os/win32/ngx_init.c
+++ b/src/os/win32/ngx_win32_init.c
@@ -2,15 +2,23 @@
#include <ngx_config.h>
#include <ngx_core.h>
+/* STUB */
+ssize_t ngx_wsarecv(ngx_connection_t *c, char *buf, size_t size);
+ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in);
+/* */
+
+int ngx_win32_version;
int ngx_max_sockets;
+int ngx_inherited_nonblocking = 1;
ngx_os_io_t ngx_os_io = {
ngx_wsarecv,
NULL,
NULL,
- NULL
+ ngx_wsasend_chain,
+ 0
};
@@ -26,7 +34,7 @@ static GUID tf_guid = WSAID_TRANSMITFILE;
int ngx_os_init(ngx_log_t *log)
{
- u_int sp;
+ u_int osviex;
DWORD bytes;
SOCKET s;
WSADATA wsd;
@@ -34,14 +42,14 @@ int ngx_os_init(ngx_log_t *log)
/* get Windows version */
- ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
+ ngx_memzero(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
osviex = GetVersionEx((OSVERSIONINFO *) &osvi);
if (osviex == 0) {
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
- if (GetVersionEx((OSVERSIONINFO *) &osvi) == 0)
+ if (GetVersionEx((OSVERSIONINFO *) &osvi) == 0) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
"GetVersionEx() failed");
return NGX_ERROR;
@@ -49,27 +57,36 @@ int ngx_os_init(ngx_log_t *log)
}
/*
- * Windows 95 1400
- * Windows 98 1410
- * Windows ME 1490
- * Windows NT 3.51 2351
- * Windows NT 4.0 2400
- * Windows 2000 2500
- * Windows XP 2501
- * Windows 2003 2502
+ * Windows 95 140000
+ * Windows 98 141000
+ * Windows ME 149000
+ * Windows NT 3.51 235100
+ * Windows NT 4.0 240000
+ * Windows NT 4.0 SP5 240050
+ * Windows 2000 250000
+ * Windows XP 250100
+ * Windows 2003 250200
*/
- ngx_win32_version = osvi.dwPlatformId * 1000
- + osvi.dwMajorVersion * 100
- + osvi.dwMinorVersion;
+ ngx_win32_version = osvi.dwPlatformId * 100000
+ + osvi.dwMajorVersion * 10000
+ + osvi.dwMinorVersion * 100;
if (osviex) {
- sp = osvi.wServicePackMajor * 100 + osvi.wServicePackMinor;
+ ngx_win32_version += osvi.wServicePackMajor * 10
+ + osvi.wServicePackMinor;
+
+ ngx_log_error(NGX_LOG_INFO, log, 0,
+ "OS: %u build:%u, %s, suite:%x, type:%u",
+ ngx_win32_version, osvi.dwBuildNumber, osvi.szCSDVersion,
+ osvi.wReserved[0], osvi.wReserved[1]);
+#if 0
ngx_log_error(NGX_LOG_INFO, log, 0,
- "OS: %u build:%u, %s, SP:%u, suite:%x, type:%u",
+ "OS: %u build:%u, %s, suite:%x, type:%u",
ngx_win32_version, osvi.dwBuildNumber, osvi.szCSDVersion,
- sp, osvi.wSuiteMask, osvi.wProductType);
+ osvi.wSuiteMask, osvi.wProductType);
+#endif
} else {
ngx_log_error(NGX_LOG_INFO, log, 0, "OS: %u build:%u, %s",
diff --git a/src/os/win32/ngx_wsarecv.c b/src/os/win32/ngx_wsarecv.c
new file mode 100644
index 000000000..038554a68
--- /dev/null
+++ b/src/os/win32/ngx_wsarecv.c
@@ -0,0 +1,90 @@
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_event.h>
+
+
+ssize_t ngx_wsarecv(ngx_connection_t *c, char *buf, size_t size)
+{
+ int rc;
+ u_int flags;
+ size_t bytes;
+ WSABUF wsabuf[1];
+ ngx_err_t err;
+ ngx_event_t *rev;
+ LPWSAOVERLAPPED ovlp;
+
+ rev = c->read;
+ bytes = 0;
+
+ if ((ngx_event_flags & NGX_HAVE_AIO_EVENT) && rev->ready) {
+ rev->ready = 0;
+
+ /* the overlapped WSARecv() completed */
+
+ if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) {
+ if (rev->ovlp.error) {
+ ngx_log_error(NGX_LOG_ERR, c->log, rev->ovlp.error,
+ "WSARecv() failed");
+ return NGX_ERROR;
+ }
+
+ return rev->available;
+ }
+
+ if (WSAGetOverlappedResult(c->fd, (LPWSAOVERLAPPED) &rev->ovlp,
+ &bytes, 0, NULL) == 0) {
+ err = ngx_socket_errno;
+ ngx_log_error(NGX_LOG_CRIT, c->log, err,
+ "WSARecv() or WSAGetOverlappedResult() failed");
+
+ return NGX_ERROR;
+ }
+
+ return bytes;
+ }
+
+ if (ngx_event_flags & NGX_HAVE_AIO_EVENT) {
+ ovlp = (LPWSAOVERLAPPED) &c->read->ovlp;
+ ngx_memzero(ovlp, sizeof(WSAOVERLAPPED));
+
+ } else {
+ ovlp = NULL;
+ }
+
+ wsabuf[0].buf = buf;
+ wsabuf[0].len = size;
+ flags = 0;
+
+ rc = WSARecv(c->fd, wsabuf, 1, &bytes, &flags, ovlp, NULL);
+
+ ngx_log_debug(c->log, "WSARecv: %d:%d" _ rc _ bytes);
+
+ if (rc == -1) {
+ err = ngx_socket_errno;
+ if (err == WSA_IO_PENDING) {
+ return NGX_AGAIN;
+
+ } else if (err == WSAEWOULDBLOCK) {
+ ngx_log_error(NGX_LOG_INFO, c->log, err, "WSARecv() EAGAIN");
+ return NGX_AGAIN;
+
+ } else {
+ ngx_log_error(NGX_LOG_CRIT, c->log, err, "WSARecv() failed");
+ return NGX_ERROR;
+ }
+ }
+
+ if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) {
+
+ /*
+ * If a socket was bound with I/O completion port
+ * then GetQueuedCompletionStatus() would anyway return its status
+ * despite that WSARecv() was already completed.
+ */
+
+ return NGX_AGAIN;
+ }
+
+ return bytes;
+}
diff --git a/src/os/win32/ngx_wsasend_chain.c b/src/os/win32/ngx_wsasend_chain.c
new file mode 100644
index 000000000..ebaa77e96
--- /dev/null
+++ b/src/os/win32/ngx_wsasend_chain.c
@@ -0,0 +1,181 @@
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_event.h>
+
+
+ngx_chain_t *ngx_wsasend_chain(ngx_connection_t *c, ngx_chain_t *in)
+{
+ int rc;
+ char *prev;
+ size_t size, sent;
+ LPWSABUF wsabuf;
+ ngx_err_t err;
+ ngx_event_t *wev;
+ ngx_array_t wsabufs;
+ ngx_chain_t *ce;
+ LPWSAOVERLAPPED ovlp;
+
+#if 0
+
+iocp:
+ if ready
+ get result
+ update chain
+ return if done;
+ wsasend
+
+non-block
+ for ( ;; ) {
+ wsasend
+ if no again
+ update chain
+ return if done;
+ }
+
+
+ for ( ;; ) {
+
+ make buffers and limit data for both ovlp and nonblocked,
+ configured in events module
+
+ if (iocp && ready) {
+ get result
+
+ } else {
+ if (file)
+ transmitfile
+ else
+ wsasend
+
+ if (iocp)
+ return chain
+ return chain if again
+ here is result
+ }
+
+ if (result)
+ update chain;
+ return chain if done
+ }
+ }
+
+
+#endif
+
+ wev = c->write;
+
+ if (((ngx_event_flags & NGX_HAVE_AIO_EVENT) && !wev->ready)
+ || ((ngx_event_flags & NGX_HAVE_AIO_EVENT) == 0))
+ {
+ /*
+ * WSABUFs must be 4-byte aligned otherwise
+ * WSASend() will return undocumented WSAEINVAL error.
+ */
+
+ ngx_init_array(wsabufs, c->pool, 10, sizeof(WSABUF), NGX_CHAIN_ERROR);
+
+ prev = NULL;
+ wsabuf = NULL;
+
+ /* create the WSABUF and coalesce the neighbouring chain entries */
+ for (ce = in; ce; ce = ce->next) {
+
+ if (prev == ce->hunk->pos) {
+ wsabuf->len += ce->hunk->last - ce->hunk->pos;
+ prev = ce->hunk->last;
+
+ } else {
+ ngx_test_null(wsabuf, ngx_push_array(&wsabufs),
+ NGX_CHAIN_ERROR);
+ wsabuf->buf = ce->hunk->pos;
+ wsabuf->len = ce->hunk->last - ce->hunk->pos;
+ prev = ce->hunk->last;
+ }
+ }
+
+ if (ngx_event_flags & NGX_HAVE_AIO_EVENT) {
+ ovlp = (LPWSAOVERLAPPED) &c->write->ovlp;
+ ngx_memzero(ovlp, sizeof(WSAOVERLAPPED));
+
+ } else {
+ ovlp = NULL;
+ }
+
+ rc = WSASend(c->fd, wsabufs.elts, wsabufs.nelts, &sent, 0, ovlp, NULL);
+
+ if (rc == -1) {
+ err = ngx_errno;
+ if (err == WSA_IO_PENDING) {
+ sent = 0;
+
+ } else if (err == WSAEWOULDBLOCK) {
+ sent = 0;
+ ngx_log_error(NGX_LOG_INFO, c->log, err, "WSASend() EAGAIN");
+
+ } else {
+ ngx_log_error(NGX_LOG_CRIT, c->log, err, "WSASend() failed");
+ return NGX_CHAIN_ERROR;
+ }
+
+ } else {
+
+ if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) {
+
+ /*
+ * If a socket was bound with I/O completion port then
+ * GetQueuedCompletionStatus() would anyway return its status
+ * despite that WSASend() was already completed.
+ */
+
+ sent = 0;
+ }
+ }
+
+ } else {
+ if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) {
+ wev->ready = 0;
+
+ /* the overlapped WSASend() completed */
+
+ if (wev->ovlp.error) {
+ ngx_log_error(NGX_LOG_ERR, c->log, wev->ovlp.error,
+ "WSASend() failed");
+ return NGX_CHAIN_ERROR;
+ }
+
+ sent = wev->available;
+ }
+ }
+
+#if (NGX_DEBUG_WRITE_CHAIN)
+ ngx_log_debug(c->log, "WSASend(): %d" _ sent);
+#endif
+
+ c->sent += sent;
+
+ for (ce = in; ce && sent > 0; ce = ce->next) {
+
+ size = ce->hunk->last - ce->hunk->pos;
+
+ if (sent >= size) {
+ sent -= size;
+
+ if (ce->hunk->type & NGX_HUNK_IN_MEMORY) {
+ ce->hunk->pos = ce->hunk->last;
+ }
+
+ continue;
+ }
+
+ if (ce->hunk->type & NGX_HUNK_IN_MEMORY) {
+ ce->hunk->pos += sent;
+ }
+
+ break;
+ }
+
+ ngx_destroy_array(&wsabufs);
+
+ return ce;
+}