nginx-0.0.1-2003-05-21-17:28:21 import
diff --git a/src/core/ngx_config.h b/src/core/ngx_config.h
index 690cb32..b724129 100644
--- a/src/core/ngx_config.h
+++ b/src/core/ngx_config.h
@@ -4,218 +4,59 @@
#include <ngx_auto_config.h>
-/*
- auto_conf
- ngx_inline inline __inline __inline__
-*/
-/* STUB */
+#if defined __FreeBSD__
+#include <ngx_freebsd_config.h>
+
+
+#elif defined __linux__
+#include <ngx_linux_config.h>
+
+
+ /* Solaris */
+#elif defined(sun) && (defined(__svr4__) || defined(__SVR4))
+#include <ngx_solaris_config.h>
+
+
+#elif defined _WIN32
+
+/* STUB to allocate a big ngx_connections */
#undef FD_SETSIZE
#define FD_SETSIZE 1024
+#include <ngx_win32_config.h>
-/* auto_conf */
-#define NGX_ALIGN (4 - 1)
-#define NGX_ALIGN_TYPE unsigned
-#define ngx_align(p) (char *) (((NGX_ALIGN_TYPE) p + NGX_ALIGN) & ~NGX_ALIGN)
+#else /* posix */
+
+#endif
-/* Platform specific: array[NGX_INVALID_ARRAY_INDEX] should cause SIGSEGV */
+/* TODO: platform specific: array[NGX_INVALID_ARRAY_INDEX] must cause SIGSEGV */
#define NGX_INVALID_ARRAY_INDEX 0x80000000
-#ifdef _WIN32
+/* TODO: auto_conf */
+#define NGX_ALIGN (4 - 1)
+#define NGX_ALIGN_TYPE (unsigned int)
-#define WIN32 1
-
-#include <winsock2.h>
-#include <mswsock.h>
-#include <stddef.h> /* offsetof */
-#include <stdio.h>
-#include <stdarg.h>
+#define ngx_align(p) (char *) ((NGX_ALIGN_TYPE p + NGX_ALIGN) & ~NGX_ALIGN)
-#define ngx_inline __inline
-
-
-#ifndef HAVE_INHERITED_NONBLOCK
-#define HAVE_INHERITED_NONBLOCK 1
-#endif
-
-#ifndef HAVE_WIN32_TRANSMITPACKETS
-#define HAVE_WIN32_TRANSMITPACKETS 1
-#define HAVE_WIN32_TRANSMITFILE 0
-#endif
-
-#ifndef HAVE_WIN32_TRANSMITFILE
-#define HAVE_WIN32_TRANSMITFILE 1
-#endif
-
-#if (HAVE_WIN32_TRANSMITPACKETS) || (HAVE_WIN32_TRANSMITFILE)
-#define HAVE_SENDFILE 1
-#endif
-
-#else /* POSIX */
-
-
-
-/* Solaris */
-#if defined(sun) && (defined(__svr4__) || defined(__SVR4))
-
-#define SOLARIS 1
-
-#define _FILE_OFFSET_BITS 64 /* should be before sys/types.h */
-
-#ifndef HAVE_INHERITED_NONBLOCK
-#define HAVE_INHERITED_NONBLOCK 1
-#endif
-
-#include <sys/stropts.h> /* INFTIM */
-
-#endif /* Solaris */
-
-
-
-#include <unistd.h>
-#include <stddef.h> /* offsetof */
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/wait.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <sys/resource.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-
-
-#ifndef HAVE_POLL
-#define HAVE_POLL 1
-#include <poll.h>
-#endif
-
-
-#if (HAVE_DEVPOLL) && !(TEST_DEVPOLL)
-#include <sys/ioctl.h>
-#include <sys/devpoll.h> /* Solaris, HP/UX */
-#endif
-
-
-#if (HAVE_AIO)
-#include <aio.h>
-#endif
-
-
+/* TODO: auto_conf: ngx_inline inline __inline __inline__ */
+#ifndef ngx_inline
#define ngx_inline inline
+#endif
-#endif /* POSIX */
-
-
-
-#define LF 10
-#define CR 13
-#define CRLF "\x0d\x0a"
-
+#ifndef INADDR_NONE /* Solaris */
+#define INADDR_NONE ((unsigned long) -1)
+#endif
#ifndef INET_ADDRSTRLEN
#define INET_ADDRSTRLEN 16
#endif
-#if defined SO_ACCEPTFILTER || defined TCP_DEFER_ACCEPT
-
-#ifndef HAVE_DEFERRED_ACCEPT
-#define HAVE_DEFERRED_ACCEPT 1
-#endif
-
-#endif
-
-
-#ifndef HAVE_SELECT
-#define HAVE_SELECT 1
-#endif
-
-
-#ifdef __FreeBSD__
-
-#include <osreldate.h>
-
-#ifndef HAVE_INHERITED_NONBLOCK
-#define HAVE_INHERITED_NONBLOCK 1
-#endif
-
-/* FreeBSD sendfile */
-#if __FreeBSD_version >= 300007
-
-#ifndef HAVE_FREEBSD_SENDFILE
-#define HAVE_FREEBSD_SENDFILE 1
-#endif
-
-#ifndef HAVE_FREEBSD_SENDFILE_NBYTES_BUG
-#define HAVE_FREEBSD_SENDFILE_NBYTES_BUG 2
-#endif
-
-#endif /* FreeBSD sendfile */
-
-/* FreeBSD sendfile nbytes bug */
-#if (__FreeBSD__ == 4 && __FreeBSD_version >= 460100) \
- || __FreeBSD_version == 460001 \
- || __FreeBSD_version >= 500029
-
-#if (HAVE_FREEBSD_SENDFILE_NBYTES_BUG == 2)
-#undef HAVE_FREEBSD_SENDFILE_NBYTES_BUG
-#define HAVE_FREEBSD_SENDFILE_NBYTES_BUG 0
-#endif
-
-#endif /* FreeBSD sendfile nbytes bug */
-
-#if (HAVE_FREEBSD_SENDFILE)
-#define HAVE_SENDFILE 1
-#endif
-
-
-/* FreeBSD kqueue */
-#if (__FreeBSD__ == 4 && __FreeBSD_version >= 410000) \
- || __FreeBSD_version >= 500011
-
-#ifndef HAVE_KQUEUE
-#define HAVE_KQUEUE 1
-#include <sys/event.h>
-#endif
-
-/* kqueue's NOTE_LOWAT */
-#if (__FreeBSD__ == 4 && __FreeBSD_version >= 430000) \
- || __FreeBSD_version >= 500018
-
-#ifndef HAVE_LOWAT_EVENT
-#define HAVE_LOWAT_EVENT 1
-#endif
-
-#endif
-
-#endif /* FreeBSD kqueue */
-
-
-#endif /* __FreeBSD__ */
-
-
-#ifdef __SOME_OS_TEMPLATE__
-
-#ifndef HAVE_INHERITED_NONBLOCK
-#define HAVE_INHERITED_NONBLOCK 1
-#endif
-
-#endif
-
-
#endif /* _NGX_CONFIG_H_INCLUDED_ */
diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h
index 76003fb..aabbbc7 100644
--- a/src/core/ngx_core.h
+++ b/src/core/ngx_core.h
@@ -37,6 +37,12 @@
*/
+#define LF 10
+#define CR 13
+#define CRLF "\x0d\x0a"
+
+
+
#define NGX_MAXHOSTNAMELEN 32
/*
#define NGX_MAXHOSTNAMELEN MAXHOSTNAMELEN
diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c
index d70004b..b85b472 100644
--- a/src/core/ngx_file.c
+++ b/src/core/ngx_file.c
@@ -81,7 +81,7 @@
if (ngx_create_path(file, path) == NGX_ERROR) {
return NGX_ERROR;
- }
+ }
}
}
diff --git a/src/core/ngx_hunk.c b/src/core/ngx_hunk.c
index d2c31d5..691387f 100644
--- a/src/core/ngx_hunk.c
+++ b/src/core/ngx_hunk.c
@@ -25,9 +25,9 @@
return h;
}
-
+
ngx_hunk_t *ngx_create_hunk_before(ngx_pool_t *pool, ngx_hunk_t *hunk, int size)
-{
+{
ngx_hunk_t *h;
ngx_test_null(h, ngx_palloc(pool, sizeof(ngx_hunk_t)), NULL);
@@ -47,7 +47,7 @@
} else {
ngx_test_null(h->pre_start, ngx_palloc(pool, size), NULL);
- h->start = h->pos = h->last = h->pre_start;
+ h->start = h->pos = h->last = h->pre_start;
h->end = h->post_end = h->start + size;
h->file_pos = h->file_last = 0;
@@ -84,7 +84,7 @@
} else {
ngx_test_null(h->pre_start, ngx_palloc(pool, size), NULL);
- h->start = h->pos = h->last = h->pre_start;
+ h->start = h->pos = h->last = h->pre_start;
h->end = h->post_end = h->start + size;
h->file_pos = h->file_last = 0;
diff --git a/src/core/ngx_log.c b/src/core/ngx_log.c
index fee6018..aff3998 100644
--- a/src/core/ngx_log.c
+++ b/src/core/ngx_log.c
@@ -147,7 +147,7 @@
n = read((ngx_fd_t) ev->data, errstr, sizeof(errstr - 1));
if (n == -1) {
- err = ngx_errno;
+ err = ngx_errno;
if (err == NGX_EAGAIN) {
return;
}
diff --git a/src/core/ngx_modules.c b/src/core/ngx_modules.c
index 5e5f5a8..cf5458c 100644
--- a/src/core/ngx_modules.c
+++ b/src/core/ngx_modules.c
@@ -17,6 +17,9 @@
#if (HAVE_DEVPOLL)
extern ngx_module_t ngx_devpoll_module;
#endif
+#if (HAVE_AIO)
+extern ngx_module_t ngx_aio_module;
+#endif
extern ngx_module_t ngx_http_module;
@@ -47,6 +50,9 @@
#if (HAVE_DEVPOLL)
&ngx_devpoll_module,
#endif
+#if (HAVE_AIO)
+ &ngx_aio_module,
+#endif
/* http */
diff --git a/src/core/ngx_os_init.h b/src/core/ngx_os_init.h
index b65932d..8a14ad0 100644
--- a/src/core/ngx_os_init.h
+++ b/src/core/ngx_os_init.h
@@ -4,23 +4,40 @@
#include <ngx_config.h>
#include <ngx_core.h>
-#if 0
-#include <ngx_connection.h>
+
+
+#define NGX_IO_SENDFILE 1
+#define NGX_IO_ZEROCOPY 2
+
+#if (HAVE_SENDFILE)
+#define NGX_HAVE_SENDFILE NGX_IO_SENDFILE
+#else
+#define NGX_HAVE_SENDFILE 0
#endif
+#if (HAVE_ZEROCOPY)
+#define NGX_HAVE_ZEROCOPY NGX_IO_ZEROCOPY
+#else
+#define NGX_HAVE_ZEROCOPY 0
+#endif
+
+
typedef struct {
ssize_t (*recv)(ngx_connection_t *c, char *buf, size_t size);
void *dummy_recv_chain;
void *dummy_send;
ngx_chain_t *(*send_chain)(ngx_connection_t *c, ngx_chain_t *in);
+ int flags;
} ngx_os_io_t;
int ngx_os_init(ngx_log_t *log);
+
extern ngx_os_io_t ngx_os_io;
extern int ngx_max_sockets;
+extern int ngx_inherited_nonblocking;
#endif /* _NGX_OS_INIT_H_INCLUDED_ */
diff --git a/src/event/modules/ngx_aio_module.c b/src/event/modules/ngx_aio_module.c
index 20cb1a6..24d049f 100644
--- a/src/event/modules/ngx_aio_module.c
+++ b/src/event/modules/ngx_aio_module.c
@@ -1,39 +1,109 @@
#include <ngx_config.h>
-
#include <ngx_core.h>
-#include <ngx_types.h>
-#include <ngx_log.h>
-#include <ngx_connection.h>
#include <ngx_event.h>
-#include <ngx_event_timer.h>
+#include <ngx_aio.h>
#if (HAVE_KQUEUE)
#include <ngx_kqueue_module.h>
#endif
-int ngx_aio_init(int max_connections, ngx_log_t *log)
-{
+static int ngx_aio_init(ngx_log_t *log);
+static void ngx_aio_done(ngx_log_t *log);
+static int ngx_aio_add_event(ngx_event_t *ev, int event, u_int flags);
+static int ngx_aio_del_event(ngx_event_t *ev, int event, u_int flags);
+static int ngx_aio_process_events(ngx_log_t *log);
+
+
+ngx_os_io_t ngx_os_aio = {
+ ngx_aio_read,
+ NULL,
+ ngx_aio_write,
+ ngx_aio_write_chain,
+ NGX_HAVE_ZEROCOPY
+};
+
+
+static ngx_str_t aio_name = ngx_string("aio");
+
+ngx_event_module_t ngx_aio_module_ctx = {
+ NGX_EVENT_MODULE,
+ &aio_name,
+ NULL, /* create configuration */
+ NULL, /* init configuration */
+
+ {
+ ngx_aio_add_event, /* add an event */
+ ngx_aio_del_event, /* delete an event */
+ NULL, /* enable an event */
+ NULL, /* disable an event */
+ NULL, /* add an connection */
+ NULL, /* delete an connection */
+ ngx_aio_process_events, /* process the events */
+ ngx_aio_init, /* init the events */
+ ngx_aio_done /* done the events */
+ }
+
+};
+
+ngx_module_t ngx_aio_module = {
+ &ngx_aio_module_ctx, /* module context */
+ 0, /* module index */
+ NULL, /* module directives */
+ NGX_EVENT_MODULE_TYPE, /* module type */
+ NULL /* init module */
+};
+
+
+
#if (HAVE_KQUEUE)
- int rc;
-
- rc = ngx_kqueue_init(max_connections, log);
+static int ngx_aio_init(ngx_log_t *log)
+{
+ if (ngx_kqueue_module_ctx.actions.init(log) == NGX_ERROR) {
+ return NGX_ERROR;
+ }
ngx_event_flags = NGX_HAVE_AIO_EVENT|NGX_USE_AIO_EVENT;
- ngx_write_chain_proc = ngx_aio_write_chain;
+ ngx_event_actions = ngx_aio_module_ctx.actions;
+ ngx_io = ngx_os_aio;
- return rc;
-#endif
+ return NGX_OK;
}
+static void ngx_aio_done(ngx_log_t *log)
+{
+ ngx_kqueue_module_ctx.actions.done(log);
+}
+/* The event adding and deleteing are needed for the listening sockets */
+
+static int ngx_aio_add_event(ngx_event_t *ev, int event, u_int flags)
+{
+ return ngx_kqueue_module_ctx.actions.add(ev, event, flags);
+}
+
+
+static int ngx_aio_del_event(ngx_event_t *ev, int event, u_int flags)
+{
+ return ngx_kqueue_module_ctx.actions.del(ev, event, flags);
+}
+
+
+static int ngx_aio_process_events(ngx_log_t *log)
+{
+ return ngx_kqueue_module_ctx.actions.process(log);
+}
+
+#endif
+
#if 0
+
/* 1 */
int ngx_posix_aio_process_events(ngx_log_t *log)
{
@@ -66,6 +136,7 @@
/* 3 */
int ngx_posix_aio_process_events(ngx_log_t *log)
{
+#if 0
unmask signal
/* BUG: AIO signal can be delivered before select() */
@@ -73,6 +144,9 @@
select(listen);
mask signal
+#endif
+
+ pselect(listen, mask);
if (ngx_socket_errno == NGX_EINTR)
look ready array
@@ -82,4 +156,5 @@
{
push siginfo->si_value.sival_ptr
}
+
#endif
diff --git a/src/event/modules/ngx_devpoll_module.c b/src/event/modules/ngx_devpoll_module.c
index 72efda4..531e96a 100644
--- a/src/event/modules/ngx_devpoll_module.c
+++ b/src/event/modules/ngx_devpoll_module.c
@@ -10,7 +10,7 @@
#include <ngx_event.h>
-#if (TEST_DEVPOLL)
+#if (TEST_BUILD_DEVPOLL)
/* Solaris declarations */
diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c
index 81475f7..b8398b5 100644
--- a/src/event/modules/ngx_kqueue_module.c
+++ b/src/event/modules/ngx_kqueue_module.c
@@ -66,7 +66,7 @@
NULL, /* delete an connection */
ngx_kqueue_process_events, /* process the events */
ngx_kqueue_init, /* init the events */
- ngx_kqueue_done, /* done the events */
+ ngx_kqueue_done /* done the events */
}
};
@@ -343,22 +343,23 @@
}
ev = (ngx_event_t *) event_list[i].udata;
- instance = (uintptr_t) ev & 1;
- ev = (void *) ((uintptr_t) ev & ~1);
-
- /* It's a stale event from a file descriptor
- that was just closed in this iteration */
-
- if (ev->active == 0 || ev->instance != instance) {
- ngx_log_debug(log, "stale kevent");
- continue;
- }
switch (event_list[i].filter) {
case EVFILT_READ:
case EVFILT_WRITE:
+ instance = (uintptr_t) ev & 1;
+ ev = (void *) ((uintptr_t) ev & ~1);
+
+ /* It's a stale event from a file descriptor
+ that was just closed in this iteration */
+
+ if (ev->active == 0 || ev->instance != instance) {
+ ngx_log_debug(log, "stale kevent");
+ continue;
+ }
+
ev->available = event_list[i].data;
if (event_list[i].flags & EV_EOF) {
diff --git a/src/event/modules/ngx_kqueue_module.h b/src/event/modules/ngx_kqueue_module.h
index 4f41ae7..72b85d2 100644
--- a/src/event/modules/ngx_kqueue_module.h
+++ b/src/event/modules/ngx_kqueue_module.h
@@ -9,6 +9,8 @@
extern int ngx_kqueue;
+/* STUB */ extern ngx_event_module_t ngx_kqueue_module_ctx;
+
#endif /* _NGX_KQUEUE_MODULE_H_INCLUDED_ */
diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c
index dc46c6f..9a4796a 100644
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -31,7 +31,7 @@
static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, char *dummy);
-static char *ngx_event_set_type(ngx_conf_t *cf, ngx_command_t *cmd, char *conf);
+static char *ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, char *conf);
static void *ngx_event_create_conf(ngx_pool_t *pool);
static char *ngx_event_init_conf(ngx_pool_t *pool, void *conf);
@@ -84,9 +84,9 @@
offsetof(ngx_event_conf_t, connections),
NULL},
- {ngx_string("type"),
+ {ngx_string("use"),
NGX_EVENT_CONF|NGX_CONF_TAKE1,
- ngx_event_set_type,
+ ngx_event_use,
0,
0,
NULL},
@@ -135,7 +135,7 @@
ecf = ngx_event_get_conf(ngx_event_module_ctx);
ngx_log_debug(log, "CONN: %d" _ ecf->connections);
-ngx_log_debug(log, "TYPE: %d" _ ecf->type);
+ngx_log_debug(log, "TYPE: %d" _ ecf->use);
for (m = 0; ngx_modules[m]; m++) {
if (ngx_modules[m]->type != NGX_EVENT_MODULE_TYPE) {
@@ -143,7 +143,7 @@
}
module = ngx_modules[m]->ctx;
- if (module->index == ecf->type) {
+ if (module->index == ecf->use) {
if (module->actions.init(log) == NGX_ERROR) {
return NGX_ERROR;
}
@@ -317,7 +317,7 @@
}
-static char *ngx_event_set_type(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
+static char *ngx_event_use(ngx_conf_t *cf, ngx_command_t *cmd, char *conf)
{
ngx_event_conf_t *ecf = (ngx_event_conf_t *) conf;
@@ -325,8 +325,8 @@
ngx_str_t *args;
ngx_event_module_t *module;
- if (ecf->type != NGX_CONF_UNSET) {
- return "duplicate event type" ;
+ if (ecf->use != NGX_CONF_UNSET) {
+ return "is duplicate" ;
}
args = cf->args->elts;
@@ -339,7 +339,7 @@
module = ngx_modules[m]->ctx;
if (module->name->len == args[1].len) {
if (ngx_strcmp(module->name->data, args[1].data) == 0) {
- ecf->type = module->index;
+ ecf->use = module->index;
return NGX_CONF_OK;
}
}
@@ -358,7 +358,7 @@
ecf->connections = NGX_CONF_UNSET;
ecf->timer_queues = NGX_CONF_UNSET;
- ecf->type = NGX_CONF_UNSET;
+ ecf->use = NGX_CONF_UNSET;
return ecf;
}
@@ -380,19 +380,19 @@
#endif
ngx_conf_init_value(ecf->connections, DEF_CONNECTIONS);
- ngx_conf_init_value(ecf->type, ngx_kqueue_module_ctx.index);
+ ngx_conf_init_value(ecf->use, ngx_kqueue_module_ctx.index);
#elif (HAVE_DEVPOLL)
ngx_conf_init_value(ecf->connections, DEF_CONNECTIONS);
- ngx_conf_init_value(ecf->type, ngx_devpoll_module_ctx.index);
+ ngx_conf_init_value(ecf->use, ngx_devpoll_module_ctx.index);
#else /* HAVE_SELECT */
ngx_conf_init_value(ecf->connections,
FD_SETSIZE < DEF_CONNECTIONS ? FD_SETSIZE : DEF_CONNECTIONS);
- ngx_conf_init_value(ecf->type, ngx_select_module_ctx.index);
+ ngx_conf_init_value(ecf->use, ngx_select_module_ctx.index);
#endif
diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h
index 4325ab3..c3f925f 100644
--- a/src/event/ngx_event.h
+++ b/src/event/ngx_event.h
@@ -327,7 +327,7 @@
typedef struct {
int connections;
int timer_queues;
- int type;
+ int use;
} ngx_event_conf_t;
diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c
index 75dda55..76eae62 100644
--- a/src/event/ngx_event_accept.c
+++ b/src/event/ngx_event_accept.c
@@ -65,39 +65,28 @@
return;
}
+ /* set a blocking mode for aio and non-blocking mode for others */
-#if (HAVE_INHERITED_NONBLOCK)
+ if (ngx_inherited_nonblocking) {
+ if ((ngx_event_flags & NGX_USE_AIO_EVENT)) {
+ 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);
+ return;
+ }
+ }
-#if (HAVE_AIO_EVENT)
- if ((ngx_event_flags & NGX_HAVE_AIO_EVENT)) {
- 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);
- return;
+ } else {
+ if ((ngx_event_flags & NGX_USE_AIO_EVENT) == 0) {
+ 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);
+ return;
+ }
}
}
-#endif
-
-#else /* !HAVE_INHERITED_NONBLOCK */
-
-#if (HAVE_AIO_EVENT)
- if (!(ngx_event_flags & NGX_HAVE_AIO_EVENT)) {
- 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);
- return;
- }
- }
-#else
- 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);
- return;
- }
-#endif
-
-#endif /* HAVE_INHERITED_NONBLOCK */
-
rev = &ngx_read_events[s];
wev = &ngx_write_events[s];
@@ -130,15 +119,9 @@
c->unexpected_eof = 1;
wev->write = 1;
-#if (USE_KQUEUE)
- wev->ready = 1;
-#else
if ((ngx_event_flags & NGX_USE_AIO_EVENT) == 0) {
wev->ready = 1;
}
-#endif
-
- /* STUB ? */ wev->timer = rev->timer = 10000;
c->ctx = ls->ctx;
c->servers = ls->servers;
@@ -174,17 +157,10 @@
ls->handler(c);
-#if (USE_KQUEUE)
-
- ev->available--;
-
-#elif (HAVE_KQUEUE)
-
if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
ev->available--;
}
-#endif
} while (ev->available);
return;
diff --git a/src/event/ngx_event_acceptex.c b/src/event/ngx_event_acceptex.c
index ce46a16..fceb725 100644
--- a/src/event/ngx_event_acceptex.c
+++ b/src/event/ngx_event_acceptex.c
@@ -29,6 +29,22 @@
return NGX_OK;
}
+#if 0
+
+ /* can we do SO_UPDATE_ACCEPT_CONTEXT just before shutdown() ???
+ or AcceptEx's context will be lost ??? */
+
+ /* SO_UPDATE_ACCEPT_CONTEXT is required for shutdown() to work */
+ if (setsockopt(context->accept_socket, SOL_SOCKET,
+ SO_UPDATE_ACCEPT_CONTEXT, (char *)&nsd,
+ sizeof(nsd))) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, WSAGetLastError(), server_conf,
+ "setsockopt(SO_UPDATE_ACCEPT_CONTEXT) failed.");
+
+ /* non fatal - we can not only do lingering close */
+
+#endif
+
getacceptexsockaddrs(c->data, 0,
c->socklen + 16, c->socklen + 16,
&c->local_sockaddr, &c->local_socklen,
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 9b9d209..3ca006d 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -134,6 +134,13 @@
offsetof(ngx_http_core_loc_conf_t, send_timeout),
NULL},
+ {ngx_string("keepalive_timeout"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_msec_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_core_loc_conf_t, keepalive_timeout),
+ NULL},
+
{ngx_string("lingering_time"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_msec_slot,
@@ -912,6 +919,7 @@
lcf->send_timeout = NGX_CONF_UNSET;
lcf->discarded_buffer_size = NGX_CONF_UNSET;
+ lcf->keepalive_timeout = NGX_CONF_UNSET;
lcf->lingering_time = NGX_CONF_UNSET;
lcf->lingering_timeout = NGX_CONF_UNSET;
@@ -981,6 +989,8 @@
ngx_conf_merge_size_value(conf->discarded_buffer_size,
prev->discarded_buffer_size, 1500);
+ ngx_conf_merge_msec_value(conf->keepalive_timeout, prev->keepalive_timeout,
+ 70000);
ngx_conf_merge_msec_value(conf->lingering_time, prev->lingering_time,
30000);
ngx_conf_merge_msec_value(conf->lingering_timeout, prev->lingering_timeout,
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index cfe0d91..2a94ea4 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -100,6 +100,7 @@
ngx_msec_t send_timeout; /* send_timeout */
size_t send_lowat; /* send_lowa */
size_t discarded_buffer_size; /* discarded_buffer_size */
+ ngx_msec_t keepalive_timeout; /* keepalive_timeout */
ngx_msec_t lingering_time; /* lingering_time */
ngx_msec_t lingering_timeout; /* lingering_timeout */
diff --git a/src/http/ngx_http_event.c b/src/http/ngx_http_event.c
index f14dd96..83f0f68 100644
--- a/src/http/ngx_http_event.c
+++ b/src/http/ngx_http_event.c
@@ -996,6 +996,7 @@
ngx_connection_t *c;
ngx_http_log_ctx_t *ctx;
ngx_http_core_main_conf_t *cmcf;
+ ngx_http_core_loc_conf_t *clcf;
c = (ngx_connection_t *) r->connection;
rev = c->read;
@@ -1004,6 +1005,17 @@
ctx->action = "closing request";
ngx_http_close_request(r, 0);
+ if (rev->timer_set) {
+ ngx_del_timer(rev);
+ } else {
+ rev->timer_set = 1;
+ }
+
+ clcf = (ngx_http_core_loc_conf_t *)
+ ngx_http_get_module_loc_conf(r, ngx_http_core_module_ctx);
+
+ ngx_add_timer(rev, clcf->keepalive_timeout);
+
if (rev->blocked && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) == NGX_ERROR) {
ngx_http_close_connection(c);
diff --git a/src/os/unix/ngx_aio.h b/src/os/unix/ngx_aio.h
new file mode 100644
index 0000000..a37dafc
--- /dev/null
+++ b/src/os/unix/ngx_aio.h
@@ -0,0 +1,13 @@
+#ifndef _NGX_AIO_H_INCLUDED_
+#define _NGX_AIO_H_INCLUDED_
+
+
+#include <ngx_core.h>
+
+
+ssize_t ngx_aio_read(ngx_connection_t *c, char *buf, size_t size);
+ssize_t ngx_aio_write(ngx_connection_t *c, char *buf, size_t size);
+ngx_chain_t *ngx_aio_write_chain(ngx_connection_t *c, ngx_chain_t *in);
+
+
+#endif /* _NGX_AIO_H_INCLUDED_ */
diff --git a/src/os/unix/ngx_aio_read.c b/src/os/unix/ngx_aio_read.c
new file mode 100644
index 0000000..4896af9
--- /dev/null
+++ b/src/os/unix/ngx_aio_read.c
@@ -0,0 +1,110 @@
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_aio.h>
+
+#if (HAVE_KQUEUE)
+#include <ngx_kqueue_module.h>
+#endif
+
+
+/*
+ The data is ready - 3 syscalls:
+ aio_read(), aio_error(), aio_return()
+ The data is not ready - 4 (kqueue) or 5 syscalls:
+ aio_read(), aio_error(), notifiction,
+ aio_error(), aio_return()
+ aio_cancel(), aio_error()
+*/
+
+
+ssize_t ngx_aio_read(ngx_connection_t *c, char *buf, size_t size)
+{
+ int rc, first, canceled;
+ ngx_event_t *ev;
+
+ ev = c->read;
+
+ canceled = 0;
+
+ if (ev->timedout) {
+ ngx_set_socket_errno(NGX_ETIMEDOUT);
+ ngx_log_error(NGX_LOG_ERR, ev->log, 0, "aio_read() timed out");
+
+ rc = aio_cancel(c->fd, &ev->aiocb);
+ if (rc == -1) {
+ ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_errno,
+ "aio_cancel() failed");
+ return NGX_ERROR;
+ }
+
+ ngx_log_debug(ev->log, "aio_cancel: %d" _ rc);
+
+ canceled = 1;
+
+ ev->ready = 1;
+ }
+
+ first = 0;
+
+ if (!ev->ready) {
+ ngx_memzero(&ev->aiocb, sizeof(struct aiocb));
+
+ ev->aiocb.aio_fildes = c->fd;
+ ev->aiocb.aio_buf = buf;
+ ev->aiocb.aio_nbytes = size;
+
+#if (HAVE_KQUEUE)
+ ev->aiocb.aio_sigevent.sigev_notify_kqueue = ngx_kqueue;
+ ev->aiocb.aio_sigevent.sigev_notify = SIGEV_KEVENT;
+ ev->aiocb.aio_sigevent.sigev_value.sigval_ptr = ev;
+#endif
+
+ if (aio_read(&ev->aiocb) == -1) {
+ ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_errno,
+ "aio_read() failed");
+ return NGX_ERROR;
+ }
+
+ ngx_log_debug(ev->log, "aio_read: OK");
+
+ ev->active = 1;
+ first = 1;
+ }
+
+ ev->ready = 0;
+
+ rc = aio_error(&ev->aiocb);
+ if (rc == -1) {
+ ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_errno, "aio_error() failed");
+ return NGX_ERROR;
+ }
+
+ if (rc != 0) {
+ if (rc == NGX_EINPROGRESS) {
+ if (!first) {
+ ngx_log_error(NGX_LOG_CRIT, ev->log, rc,
+ "aio_read() still in progress");
+ }
+ return NGX_AGAIN;
+ }
+
+ if (rc == NGX_ECANCELED && canceled) {
+ return NGX_ERROR;
+ }
+
+ ngx_log_error(NGX_LOG_CRIT, ev->log, rc, "aio_read() failed");
+ return NGX_ERROR;
+ }
+
+ rc = aio_return(&ev->aiocb);
+ if (rc == -1) {
+ ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_errno, "aio_return() failed");
+
+ return NGX_ERROR;
+ }
+
+ ngx_log_debug(ev->log, "aio_read: %d" _ rc);
+
+ return rc;
+}
diff --git a/src/os/unix/ngx_aio_write.c b/src/os/unix/ngx_aio_write.c
new file mode 100644
index 0000000..918535a
--- /dev/null
+++ b/src/os/unix/ngx_aio_write.c
@@ -0,0 +1,112 @@
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_aio.h>
+
+#if (HAVE_KQUEUE)
+#include <ngx_kqueue_module.h>
+#endif
+
+
+/*
+ The data is ready - 3 syscalls:
+ aio_write(), aio_error(), aio_return()
+ The data is not ready - 4 (kqueue) or 5 syscalls:
+ aio_write(), aio_error(), notifiction,
+ aio_error(), aio_return()
+ aio_cancel(), aio_error()
+*/
+
+ssize_t ngx_aio_write(ngx_connection_t *c, char *buf, size_t size)
+{
+ int rc, first, canceled;
+ ngx_event_t *ev;
+
+ ev = c->write;
+
+ canceled = 0;
+
+ngx_log_debug(ev->log, "aio: ev->ready: %d" _ ev->ready);
+ngx_log_debug(ev->log, "aio: aiocb: %08x" _ &ev->aiocb);
+
+ if (ev->timedout) {
+ ngx_set_socket_errno(NGX_ETIMEDOUT);
+ ngx_log_error(NGX_LOG_ERR, ev->log, 0, "aio_write() timed out");
+
+ rc = aio_cancel(c->fd, &ev->aiocb);
+ if (rc == -1) {
+ ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_errno,
+ "aio_cancel() failed");
+ return NGX_ERROR;
+ }
+
+ ngx_log_debug(ev->log, "aio_cancel: %d" _ rc);
+
+ canceled = 1;
+
+ ev->ready = 1;
+ }
+
+ first = 0;
+
+ if (!ev->ready) {
+ ngx_memzero(&ev->aiocb, sizeof(struct aiocb));
+
+ ev->aiocb.aio_fildes = c->fd;
+ ev->aiocb.aio_buf = buf;
+ ev->aiocb.aio_nbytes = size;
+
+#if (HAVE_KQUEUE)
+ ev->aiocb.aio_sigevent.sigev_notify_kqueue = ngx_kqueue;
+ ev->aiocb.aio_sigevent.sigev_notify = SIGEV_KEVENT;
+ ev->aiocb.aio_sigevent.sigev_value.sigval_ptr = ev;
+#endif
+
+ if (aio_write(&ev->aiocb) == -1) {
+ ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_errno,
+ "aio_write() failed");
+ return NGX_ERROR;
+ }
+
+ ngx_log_debug(ev->log, "aio_write: OK");
+
+ ev->active = 1;
+ first = 1;
+ }
+
+ ev->ready = 0;
+
+ rc = aio_error(&ev->aiocb);
+ if (rc == -1) {
+ ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_errno, "aio_error() failed");
+ return NGX_ERROR;
+ }
+
+ if (rc != 0) {
+ if (rc == NGX_EINPROGRESS) {
+ if (!first) {
+ ngx_log_error(NGX_LOG_CRIT, ev->log, rc,
+ "aio_write() still in progress");
+ }
+ return NGX_AGAIN;
+ }
+
+ if (rc == NGX_ECANCELED && canceled) {
+ return NGX_ERROR;
+ }
+
+ ngx_log_error(NGX_LOG_CRIT, ev->log, rc, "aio_write() failed");
+ return NGX_ERROR;
+ }
+
+ rc = aio_return(&ev->aiocb);
+ if (rc == -1) {
+ ngx_log_error(NGX_LOG_CRIT, ev->log, ngx_errno, "aio_return() failed");
+
+ return NGX_ERROR;
+ }
+
+ ngx_log_debug(ev->log, "aio_write: %d" _ rc);
+
+ return rc;
+}
diff --git a/src/os/unix/ngx_aio_write_chain.c b/src/os/unix/ngx_aio_write_chain.c
index 34c4f40..14586ce 100644
--- a/src/os/unix/ngx_aio_write_chain.c
+++ b/src/os/unix/ngx_aio_write_chain.c
@@ -1,14 +1,7 @@
#include <ngx_config.h>
-
#include <ngx_core.h>
-#include <ngx_types.h>
-#include <ngx_alloc.h>
-#include <ngx_array.h>
-#include <ngx_hunk.h>
-#include <ngx_connection.h>
-#include <ngx_sendv.h>
-#include <ngx_sendfile.h>
+#include <ngx_aio.h>
ngx_chain_t *ngx_aio_write_chain(ngx_connection_t *c, ngx_chain_t *in)
@@ -25,19 +18,19 @@
while (ce) {
-ngx_log_debug(c->log, "aio_write ce: %x" _ ce->hunk->pos.mem);
+ngx_log_debug(c->log, "aio_write ce: %x" _ ce->hunk->pos);
- buf = prev = ce->hunk->pos.mem;
+ buf = prev = ce->hunk->pos;
size = 0;
/* coalesce the neighbouring chain entries */
- while (ce && prev == ce->hunk->pos.mem) {
- size += ce->hunk->last.mem - ce->hunk->pos.mem;
- prev = ce->hunk->last.mem;
+ while (ce && prev == ce->hunk->pos) {
+ size += ce->hunk->last - ce->hunk->pos;
+ prev = ce->hunk->last;
ce = ce->next;
}
- rc = ngx_event_aio_write(c, buf, size);
+ rc = ngx_aio_write(c, buf, size);
ngx_log_debug(c->log, "aio_write rc: %d" _ rc);
@@ -62,27 +55,27 @@
#if (NGX_DEBUG_WRITE_CHAIN)
ngx_log_debug(c->log, "write chain: %x %qx %qd" _
ce->hunk->type _
- ce->hunk->pos.file _
- ce->hunk->last.file - ce->hunk->pos.file);
+ ce->hunk->file_pos _
+ ce->hunk->file_last - ce->hunk->file_pos);
#endif
- if (sent >= ce->hunk->last.file - ce->hunk->pos.file) {
- sent -= ce->hunk->last.file - ce->hunk->pos.file;
- ce->hunk->pos.file = ce->hunk->last.file;
+ if (sent >= ce->hunk->file_last - ce->hunk->file_pos) {
+ sent -= ce->hunk->file_last - ce->hunk->file_pos;
+ ce->hunk->file_pos = ce->hunk->file_last;
#if (NGX_DEBUG_WRITE_CHAIN)
ngx_log_debug(c->log, "write chain done: %qx %qd" _
- ce->hunk->pos.file _ sent);
+ ce->hunk->file_pos _ sent);
#endif
continue;
}
- ce->hunk->pos.file += sent;
+ ce->hunk->file_pos += sent;
#if (NGX_DEBUG_WRITE_CHAIN)
ngx_log_debug(c->log, "write chain rest: %qx %qd" _
- ce->hunk->pos.file _
- ce->hunk->last.file - ce->hunk->pos.file);
+ ce->hunk->file_pos _
+ ce->hunk->file_last - ce->hunk->file_pos);
#endif
break;
diff --git a/src/os/unix/ngx_freebsd_config.h b/src/os/unix/ngx_freebsd_config.h
new file mode 100644
index 0000000..f8066e5
--- /dev/null
+++ b/src/os/unix/ngx_freebsd_config.h
@@ -0,0 +1,112 @@
+#ifndef _NGX_FREEBSD_CONFIG_H_INCLUDED_
+#define _NGX_FREEBSD_CONFIG_H_INCLUDED_
+
+
+#include <unistd.h>
+#include <stddef.h> /* offsetof */
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <sys/ioctl.h>
+#include <sys/resource.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include <osreldate.h>
+
+
+#ifndef HAVE_SELECT
+#define HAVE_SELECT 1
+#endif
+
+
+#ifndef HAVE_POLL
+#define HAVE_POLL 1
+#endif
+#if (HAVE_POLL)
+#include <poll.h>
+#endif
+
+ /* FreeBSD aio supported via kqueue */
+
+#if (__FreeBSD__ == 4 && __FreeBSD_version >= 430000) \
+ || __FreeBSD_version >= 500014
+
+#ifndef HAVE_AIO
+#define HAVE_AIO 1
+#endif
+
+#endif
+
+#if (HAVE_AIO)
+#include <aio.h>
+#endif
+
+
+#if defined SO_ACCEPTFILTER && !defined HAVE_DEFERRED_ACCEPT
+#define HAVE_DEFERRED_ACCEPT 1
+#endif
+
+
+ /* FreeBSD sendfile */
+
+#if __FreeBSD_version >= 300007
+
+#ifndef HAVE_FREEBSD_SENDFILE
+#define HAVE_FREEBSD_SENDFILE 1
+#endif
+
+#endif
+
+
+#if (HAVE_FREEBSD_SENDFILE)
+#define HAVE_SENDFILE 1
+#endif
+
+
+ /* FreeBSD kqueue */
+
+#if (__FreeBSD__ == 4 && __FreeBSD_version >= 410000) \
+ || __FreeBSD_version >= 500011
+
+#ifndef HAVE_KQUEUE
+#define HAVE_KQUEUE 1
+#endif
+
+#endif
+
+#if (HAVE_KQUEUE)
+#include <sys/event.h>
+#endif
+
+
+ /* kqueue's NOTE_LOWAT */
+
+#if (__FreeBSD__ == 4 && __FreeBSD_version >= 430000) \
+ || __FreeBSD_version >= 500018
+
+#ifndef HAVE_LOWAT_EVENT
+#define HAVE_LOWAT_EVENT 1
+#endif
+
+#endif
+
+
+
+
+#ifndef HAVE_INHERITED_NONBLOCK
+#define HAVE_INHERITED_NONBLOCK 1
+#endif
+
+
+#endif /* _NGX_FREEBSD_CONFIG_H_INCLUDED_ */
diff --git a/src/os/unix/ngx_freebsd_init.c b/src/os/unix/ngx_freebsd_init.c
index f9cba48..aac8ed9 100644
--- a/src/os/unix/ngx_freebsd_init.c
+++ b/src/os/unix/ngx_freebsd_init.c
@@ -12,9 +12,10 @@
ngx_os_io_t ngx_os_io = {
ngx_unix_recv,
+ ngx_readv_chain,
NULL,
- NULL,
- ngx_freebsd_write_chain
+ ngx_freebsd_write_chain,
+ NGX_HAVE_SENDFILE|NGX_HAVE_ZEROCOPY
};
@@ -107,5 +108,5 @@
ngx_log_error(NGX_LOG_INFO, log, 0, "net.inet.tcp.sendspace: %d",
ngx_freebsd_net_inet_tcp_sendspace);
- return ngx_unix_init(log);
+ return ngx_posix_init(log);
}
diff --git a/src/os/unix/ngx_freebsd_init.h b/src/os/unix/ngx_freebsd_init.h
index 6f58625..e81942b 100644
--- a/src/os/unix/ngx_freebsd_init.h
+++ b/src/os/unix/ngx_freebsd_init.h
@@ -7,8 +7,11 @@
#include <sys/sysctl.h>
-int ngx_unix_init(ngx_log_t *log);
+/* STUB */
+int ngx_posix_init(ngx_log_t *log);
ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size);
+ssize_t ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *entry);
+/* */
extern int ngx_freebsd_kern_osreldate;
diff --git a/src/os/unix/ngx_freebsd_rfork_thread.c b/src/os/unix/ngx_freebsd_rfork_thread.c
index 88ceced..8199d0b 100644
--- a/src/os/unix/ngx_freebsd_rfork_thread.c
+++ b/src/os/unix/ngx_freebsd_rfork_thread.c
@@ -168,7 +168,7 @@
static inline int ngx_gettid()
-{
+{
char *sp;
if (stack_size == 0) {
diff --git a/src/os/unix/ngx_linux_config.h b/src/os/unix/ngx_linux_config.h
new file mode 100644
index 0000000..69a607e
--- /dev/null
+++ b/src/os/unix/ngx_linux_config.h
@@ -0,0 +1,48 @@
+#ifndef _NGX_LINUX_CONFIG_H_INCLUDED_
+#define _NGX_LINUX_CONFIG_H_INCLUDED_
+
+
+#include <unistd.h>
+#include <stddef.h> /* offsetof */
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <sys/resource.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+
+#ifndef HAVE_SELECT
+#define HAVE_SELECT 1
+#endif
+
+
+#ifndef HAVE_POLL
+#define HAVE_POLL 1
+#endif
+#if (HAVE_POLL)
+#include <poll.h>
+#endif
+
+
+#if defined TCP_DEFER_ACCEPT && !defined HAVE_DEFERRED_ACCEPT
+#define HAVE_DEFERRED_ACCEPT 1
+#endif
+
+
+#ifndef HAVE_INHERITED_NONBLOCK
+#define HAVE_INHERITED_NONBLOCK 1
+#endif
+
+
+#endif /* _NGX_LINUX_CONFIG_H_INCLUDED_ */
diff --git a/src/os/unix/ngx_posix_init.c b/src/os/unix/ngx_posix_init.c
new file mode 100644
index 0000000..aadb64c
--- /dev/null
+++ b/src/os/unix/ngx_posix_init.c
@@ -0,0 +1,70 @@
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+int ngx_max_sockets;
+int ngx_inherited_nonblocking;
+
+
+int ngx_posix_init(ngx_log_t *log)
+{
+ struct sigaction sa;
+ struct rlimit rlmt;
+
+ ngx_memzero(&sa, sizeof(struct sigaction));
+ sa.sa_handler = SIG_IGN;
+ sigemptyset(&sa.sa_mask);
+
+ if (sigaction(SIGPIPE, &sa, NULL) == -1) {
+ ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
+ "sigaction(SIGPIPE, SIG_IGN) failed");
+ return NGX_ERROR;
+ }
+
+
+ if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
+ ngx_log_error(NGX_LOG_ALERT, log, errno,
+ "getrlimit(RLIMIT_NOFILE) failed)");
+ return NGX_ERROR;
+ }
+
+ ngx_log_error(NGX_LOG_INFO, log, 0,
+ "getrlimit(RLIMIT_NOFILE): %qd:%qd",
+ rlmt.rlim_cur, rlmt.rlim_max);
+
+ ngx_max_sockets = rlmt.rlim_cur;
+
+#if (HAVE_INHERITED_NONBLOCK)
+ ngx_inherited_nonblocking = 1;
+#else
+ ngx_inherited_nonblocking = 0;
+#endif
+
+ return NGX_OK;
+}
+
+
+int ngx_posix_post_conf_init(ngx_log_t *log)
+{
+ ngx_fd_t pp[2];
+
+ if (pipe(pp) == -1) {
+ ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "pipe() failed");
+ return NGX_ERROR;
+ }
+
+ if (dup2(pp[1], STDERR_FILENO) == -1) {
+ ngx_log_error(NGX_LOG_EMERG, log, errno, "dup2(STDERR) failed");
+ return NGX_ERROR;
+ }
+
+ if (pp[1] > STDERR_FILENO) {
+ if (close(pp[1]) == -1) {
+ ngx_log_error(NGX_LOG_EMERG, log, errno, "close() failed");
+ return NGX_ERROR;
+ }
+ }
+
+ return NGX_OK;
+}
diff --git a/src/os/unix/ngx_recv_chain.c b/src/os/unix/ngx_readv_chain.c
similarity index 87%
rename from src/os/unix/ngx_recv_chain.c
rename to src/os/unix/ngx_readv_chain.c
index 4e93168..8432f0c 100644
--- a/src/os/unix/ngx_recv_chain.c
+++ b/src/os/unix/ngx_readv_chain.c
@@ -1,12 +1,9 @@
#include <ngx_config.h>
#include <ngx_core.h>
-#include <ngx_errno.h>
-#include <ngx_log.h>
-#include <ngx_connection.h>
-ssize_t ngx_recv_chain(ngx_connection_t *c, ngx_chain_t *entry)
+ssize_t ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *entry)
{
ssize_t n;
struct iovec *iov;
diff --git a/src/os/unix/ngx_recv.c b/src/os/unix/ngx_recv.c
index c6e8b03..b2be905 100644
--- a/src/os/unix/ngx_recv.c
+++ b/src/os/unix/ngx_recv.c
@@ -17,7 +17,7 @@
#if (HAVE_KQUEUE) /* DEBUG */
if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
- ngx_log_debug(c->log, "ngx_recv: eof:%d, avail:%d, err:%d" _
+ ngx_log_debug(c->log, "recv: eof:%d, avail:%d, err:%d" _
ev->eof _ ev->available _ ev->error);
}
#endif
@@ -38,7 +38,7 @@
} else {
n = recv(c->fd, buf, size, 0);
-ngx_log_debug(c->log, "ngx_recv: read:%d:%d" _ n _ size);
+ngx_log_debug(c->log, "recv: read:%d:%d" _ n _ size);
if (n == -1) {
err = ngx_socket_errno;
@@ -49,6 +49,8 @@
n = recv(c->fd, buf, size, 0);
+ngx_log_debug(c->log, "recv: read:%d:%d" _ n _ size);
+
if (n == -1) {
err = ngx_socket_errno;
}
diff --git a/src/os/unix/ngx_socket.c b/src/os/unix/ngx_socket.c
index d213fa8..0746fa0 100644
--- a/src/os/unix/ngx_socket.c
+++ b/src/os/unix/ngx_socket.c
@@ -2,12 +2,15 @@
#include <ngx_socket.h>
-/* ioctl(FIONBIO) set blocking mode with one syscall only while
+/*
+ ioctl(FIONBIO) set blocking mode with one syscall only while
fcntl(F_SETFL, ~O_NONBLOCK) need to know previous state
using fcntl(F_GETFL).
- On FreeBSD both are syscall */
-#ifdef __FreeBSD__
+ ioctl() and fcntl() are syscalls on FreeBSD, Solaris 7/8 and Linux
+*/
+
+#if 1
int ngx_nonblocking(ngx_socket_t s)
{
diff --git a/src/os/unix/ngx_socket.h b/src/os/unix/ngx_socket.h
index 937c12d..cee1f4a 100644
--- a/src/os/unix/ngx_socket.h
+++ b/src/os/unix/ngx_socket.h
@@ -4,10 +4,6 @@
#include <ngx_config.h>
-#ifdef __FreeBSD__
-#include <sys/ioctl.h>
-#endif
-
#define NGX_WRITE_SHUTDOWN SHUT_WR
@@ -17,7 +13,7 @@
#define ngx_socket_n "socket()"
-#ifdef __FreeBSD__
+#if 1
int ngx_nonblocking(ngx_socket_t s);
int ngx_blocking(ngx_socket_t s);
diff --git a/src/os/unix/ngx_solaris_config.h b/src/os/unix/ngx_solaris_config.h
new file mode 100644
index 0000000..1545fc9
--- /dev/null
+++ b/src/os/unix/ngx_solaris_config.h
@@ -0,0 +1,64 @@
+#ifndef _NGX_SOLARIS_CONFIG_H_INCLUDED_
+#define _NGX_SOLARIS_CONFIG_H_INCLUDED_
+
+
+#define SOLARIS 1
+
+#define _FILE_OFFSET_BITS 64 /* must be before sys/types.h */
+
+#include <unistd.h>
+#include <stddef.h> /* offsetof */
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <time.h>
+#include <signal.h>
+#include <string.h>
+#include <strings.h> /* bzero() */
+#include <sys/types.h>
+#include <sys/filio.h> /* FIONBIO */
+#include <sys/stropts.h> /* INFTIM */
+#include <sys/mman.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <sys/resource.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+
+typedef uint32_t u_int32_t;
+
+
+#ifndef HAVE_SELECT
+#define HAVE_SELECT 1
+#endif
+
+
+#ifndef HAVE_POLL
+#define HAVE_POLL 1
+#endif
+#if (HAVE_POLL)
+#include <poll.h>
+#endif
+
+
+#if (HAVE_AIO)
+#include <aio.h>
+#endif
+
+
+#if (HAVE_DEVPOLL)
+#include <sys/ioctl.h>
+#include <sys/devpoll.h>
+#endif
+
+
+#ifndef HAVE_INHERITED_NONBLOCK
+#define HAVE_INHERITED_NONBLOCK 1
+#endif
+
+
+#endif /* _NGX_SOLARIS_CONFIG_H_INCLUDED_ */
diff --git a/src/os/unix/ngx_unix_init.c b/src/os/unix/ngx_unix_init.c
index 7b38bb1..9574164 100644
--- a/src/os/unix/ngx_unix_init.c
+++ b/src/os/unix/ngx_unix_init.c
@@ -3,61 +3,30 @@
#include <ngx_core.h>
-int ngx_max_sockets;
+/* STUB */
+ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size);
+ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in);
+int ngx_posix_init(ngx_log_t *log);
+int ngx_posix_post_conf_init(ngx_log_t *log);
+/* */
-int ngx_unix_init(ngx_log_t *log)
+ngx_os_io_t ngx_os_io = {
+ ngx_unix_recv,
+ NULL,
+ NULL,
+ ngx_writev_chain,
+ NGX_HAVE_ZEROCOPY
+};
+
+
+int ngx_os_init(ngx_log_t *log)
{
- struct sigaction sa;
- struct rlimit rlmt;
-
- ngx_memzero(&sa, sizeof(struct sigaction));
- sa.sa_handler = SIG_IGN;
- sigemptyset(&sa.sa_mask);
-
- if (sigaction(SIGPIPE, &sa, NULL) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
- "sigaction(SIGPIPE, SIG_IGN) failed");
- return NGX_ERROR;
- }
-
-
- if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
- ngx_log_error(NGX_LOG_ALERT, log, errno,
- "getrlimit(RLIMIT_NOFILE) failed)");
- return NGX_ERROR;
- }
-
- ngx_log_error(NGX_LOG_INFO, log, 0,
- "getrlimit(RLIMIT_NOFILE): %qd:%qd",
- rlmt.rlim_cur, rlmt.rlim_max);
-
- ngx_max_sockets = rlmt.rlim_cur;
-
- return NGX_OK;
+ return ngx_posix_init(log);
}
-int ngx_unix_post_conf_init(ngx_log_t *log)
+int ngx_os_post_conf_init(ngx_log_t *log)
{
- ngx_fd_t pp[2];
-
- if (pipe(pp) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "pipe() failed");
- return NGX_ERROR;
- }
-
- if (dup2(pp[1], STDERR_FILENO) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, errno, "dup2(STDERR) failed");
- return NGX_ERROR;
- }
-
- if (pp[1] > STDERR_FILENO) {
- if (close(pp[1]) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, errno, "close() failed");
- return NGX_ERROR;
- }
- }
-
- return NGX_OK;
+ return ngx_posix_post_conf_init(log);
}
diff --git a/src/os/unix/ngx_writev_chain.c b/src/os/unix/ngx_writev_chain.c
new file mode 100644
index 0000000..fdaa52a
--- /dev/null
+++ b/src/os/unix/ngx_writev_chain.c
@@ -0,0 +1,93 @@
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in)
+{
+ char *prev;
+ size_t size;
+ ssize_t n;
+ off_t sent;
+ struct iovec *iov;
+ ngx_err_t err;
+ ngx_array_t io;
+ ngx_chain_t *ce;
+
+ ngx_init_array(io, c->pool, 10, sizeof(struct iovec), NGX_CHAIN_ERROR);
+
+ prev = NULL;
+ iov = NULL;
+
+ /* create the iovec and coalesce the neighbouring chain entries */
+ for (ce = in; ce; ce = ce->next) {
+
+ if (prev == ce->hunk->pos) {
+ iov->iov_len += ce->hunk->last - ce->hunk->pos;
+ prev = ce->hunk->last;
+
+ } else {
+ ngx_test_null(iov, ngx_push_array(&io), 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);
+
+ if (n == -1) {
+ err = ngx_errno;
+ if (err == NGX_EAGAIN) {
+ ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EAGAIN");
+
+ } else if (err == NGX_EINTR) {
+ ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EINTR");
+
+ } else {
+ ngx_log_error(NGX_LOG_CRIT, c->log, err, "writev() failed");
+ return NGX_CHAIN_ERROR;
+ }
+ }
+
+ sent = n > 0 ? n : 0;
+
+#if (NGX_DEBUG_WRITE_CHAIN)
+ ngx_log_debug(c->log, "writev: %qd" _ 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;
+ }
+
+ if (ce->hunk->type & NGX_HUNK_FILE) {
+ ce->hunk->file_pos = ce->hunk->file_last;
+ }
+
+ continue;
+ }
+
+ if (ce->hunk->type & NGX_HUNK_IN_MEMORY) {
+ ce->hunk->pos += sent;
+ }
+
+ if (ce->hunk->type & NGX_HUNK_FILE) {
+ ce->hunk->file_pos += sent;
+ }
+
+ break;
+ }
+
+ ngx_destroy_array(&io);
+
+ return ce;
+}
diff --git a/src/os/win32/ngx_init.c b/src/os/win32/ngx_init.c
index 8c3511f..4f356a1 100644
--- a/src/os/win32/ngx_init.c
+++ b/src/os/win32/ngx_init.c
@@ -7,17 +7,10 @@
ngx_os_io_t ngx_os_io = {
-#if 0
- ngx_unix_recv,
- NULL,
- NULL,
- ngx_freebsd_write_chain
-#else
- NULL,
+ ngx_wsarecv,
NULL,
NULL,
NULL
-#endif
};
diff --git a/src/os/win32/ngx_recv.c b/src/os/win32/ngx_recv.c
new file mode 100644
index 0000000..ad2232c
--- /dev/null
+++ b/src/os/win32/ngx_recv.c
@@ -0,0 +1,93 @@
+
+#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;
+ ngx_err_t err;
+ WSABUF wsabuf[1];
+ ngx_event_t *ev;
+ LPWSAOVERLAPPED_COMPLETION_ROUTINE handler;
+
+ ev = c->read;
+
+/* DEBUG */ bytes = 0;
+
+ if (ev->timedout) {
+ ngx_set_socket_errno(NGX_ETIMEDOUT);
+ ngx_log_error(NGX_LOG_ERR, ev->log, 0, "WSARecv() timed out");
+
+ return NGX_ERROR;
+ }
+
+ if (ev->ready) {
+ ev->ready = 0;
+
+#if (HAVE_IOCP_EVENT) /* iocp */
+
+ if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) {
+ if (ev->ovlp.error) {
+ ngx_log_error(NGX_LOG_ERR, c->log, ev->ovlp.error,
+ "WSARecv() failed");
+ return NGX_ERROR;
+ }
+
+ return ev->available;
+ }
+
+#endif
+
+ if (WSAGetOverlappedResult(c->fd, (LPWSAOVERLAPPED) &ev->ovlp,
+ &bytes, 0, NULL) == 0) {
+ err = ngx_socket_errno;
+ ngx_log_error(NGX_LOG_CRIT, ev->log, err,
+ "WSARecv() or WSAGetOverlappedResult() failed");
+
+ return NGX_ERROR;
+ }
+
+ return bytes;
+ }
+
+ ngx_memzero(&ev->ovlp, sizeof(WSAOVERLAPPED));
+ wsabuf[0].buf = buf;
+ wsabuf[0].len = size;
+ flags = 0;
+
+#if 0
+ handler = ev->handler;
+#else
+ handler = NULL;
+#endif
+
+ rc = WSARecv(c->fd, wsabuf, 1, &bytes, &flags,
+ (LPWSAOVERLAPPED) &ev->ovlp, handler);
+
+ ngx_log_debug(ev->log, "WSARecv: %d:%d" _ rc _ bytes);
+
+ if (rc == -1) {
+ err = ngx_socket_errno;
+ if (err == WSA_IO_PENDING) {
+ return NGX_AGAIN;
+
+ } else {
+ ngx_log_error(NGX_LOG_CRIT, ev->log, err, "WSARecv() failed");
+ return NGX_ERROR;
+ }
+ }
+
+#if (HAVE_IOCP_EVENT) /* iocp */
+
+ if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) {
+ return NGX_AGAIN;
+ }
+
+#endif
+
+ return bytes;
+}
diff --git a/src/os/win32/ngx_win32_config.h b/src/os/win32/ngx_win32_config.h
new file mode 100644
index 0000000..1cad3ed
--- /dev/null
+++ b/src/os/win32/ngx_win32_config.h
@@ -0,0 +1,35 @@
+#ifndef _NGX_WIN32_CONFIG_H_INCLUDED_
+#define _NGX_WIN32_CONFIG_H_INCLUDED_
+
+
+#define WIN32 1
+
+#include <winsock2.h>
+#include <mswsock.h>
+#include <stddef.h> /* offsetof */
+#include <stdio.h>
+#include <stdarg.h>
+
+
+#define ngx_inline __inline
+
+
+#ifndef HAVE_INHERITED_NONBLOCK
+#define HAVE_INHERITED_NONBLOCK 1
+#endif
+
+#ifndef HAVE_WIN32_TRANSMITPACKETS
+#define HAVE_WIN32_TRANSMITPACKETS 1
+#define HAVE_WIN32_TRANSMITFILE 0
+#endif
+
+#ifndef HAVE_WIN32_TRANSMITFILE
+#define HAVE_WIN32_TRANSMITFILE 1
+#endif
+
+#if (HAVE_WIN32_TRANSMITPACKETS) || (HAVE_WIN32_TRANSMITFILE)
+#define HAVE_SENDFILE 1
+#endif
+
+
+#endif /* _NGX_WIN32_CONFIG_H_INCLUDED_ */