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>2004-04-05 00:32:09 +0400
committerIgor Sysoev <igor@sysoev.ru>2004-04-05 00:32:09 +0400
commit9a864bd8f87efd0fa23f552d4277475dd76bcea4 (patch)
tree748c76cb067e50ae033389a0590fee8b4d76d222
parentc972a3fe2774c329cd64fdaf36f51e28a130bf4c (diff)
nginx-0.0.3-2004-04-05-00:32:09 import
-rw-r--r--auto/cc2
-rw-r--r--auto/lib/md5/conf3
-rw-r--r--auto/lib/pcre/conf3
-rw-r--r--auto/lib/zlib/conf3
-rw-r--r--auto/sources2
-rw-r--r--src/core/ngx_conf_file.h4
-rw-r--r--src/event/modules/ngx_epoll_module.c108
-rw-r--r--src/event/modules/ngx_kqueue_module.c127
-rw-r--r--src/event/modules/ngx_rtsig_module.c2
-rw-r--r--src/event/ngx_event.c19
-rw-r--r--src/event/ngx_event.h39
-rw-r--r--src/event/ngx_event_accept.c18
-rw-r--r--src/event/ngx_event_connect.c17
-rw-r--r--src/event/ngx_event_posted.c76
-rw-r--r--src/event/ngx_event_posted.h28
-rw-r--r--src/event/ngx_event_timer.c21
-rw-r--r--src/http/modules/proxy/ngx_http_proxy_handler.c59
-rw-r--r--src/os/unix/ngx_process.c13
-rw-r--r--src/os/win32/ngx_process_cycle.c2
19 files changed, 370 insertions, 176 deletions
diff --git a/auto/cc b/auto/cc
index b67865192..7f0010201 100644
--- a/auto/cc
+++ b/auto/cc
@@ -2,7 +2,7 @@
case $CC in
*gcc*)
- # gcc 2.95.4, 3.3.2
+ # gcc 2.7.2.3, 2.95.4, 3.3.2, 3.4
# optimization
#CFLAGS="$CFLAGS -O2 -fomit-frame-pointer"
diff --git a/auto/lib/md5/conf b/auto/lib/md5/conf
index 40fd74716..d5b2a0afd 100644
--- a/auto/lib/md5/conf
+++ b/auto/lib/md5/conf
@@ -32,7 +32,8 @@ if [ $MD5 != NONE ]; then
*)
LINK_DEPS="$LINK_DEPS $MD5/libmd5.a"
- CORE_LIBS="$CORE_LIBS -L $MD5 -lmd5"
+ CORE_LIBS="$CORE_LIBS $MD5/libmd5.a"
+ #CORE_LIBS="$CORE_LIBS -L $MD5 -lmd5"
;;
esac
diff --git a/auto/lib/pcre/conf b/auto/lib/pcre/conf
index 3f2c7a1f6..fa50c24e9 100644
--- a/auto/lib/pcre/conf
+++ b/auto/lib/pcre/conf
@@ -31,7 +31,8 @@ if [ $PCRE != NONE ]; then
have=HAVE_PCRE . auto/have
CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
LINK_DEPS="$LINK_DEPS $PCRE/.libs/libpcre.a"
- CORE_LIBS="$CORE_LIBS -L $PCRE/.libs -lpcre"
+ CORE_LIBS="$CORE_LIBS $PCRE/.libs/libpcre.a"
+ #CORE_LIBS="$CORE_LIBS -L $PCRE/.libs -lpcre"
;;
esac
diff --git a/auto/lib/zlib/conf b/auto/lib/zlib/conf
index 82cc5edc8..7376abd70 100644
--- a/auto/lib/zlib/conf
+++ b/auto/lib/zlib/conf
@@ -26,7 +26,8 @@ if [ $ZLIB != NONE ]; then
*)
LINK_DEPS="$LINK_DEPS $ZLIB/libz.a"
- CORE_LIBS="$CORE_LIBS -L $ZLIB -lz"
+ CORE_LIBS="$CORE_LIBS $ZLIB/libz.a"
+ #CORE_LIBS="$CORE_LIBS -L $ZLIB -lz"
;;
esac
diff --git a/auto/sources b/auto/sources
index 9aa9da0b5..eba6eb977 100644
--- a/auto/sources
+++ b/auto/sources
@@ -52,12 +52,14 @@ EVENT_INCS="src/event src/event/modules"
EVENT_DEPS="src/event/ngx_event.h \
src/event/ngx_event_timer.h \
+ src/event/ngx_event_posted.h \
src/event/ngx_event_busy_lock.h \
src/event/ngx_event_connect.h \
src/event/ngx_event_pipe.h"
EVENT_SRCS="src/event/ngx_event.c \
src/event/ngx_event_timer.c \
+ src/event/ngx_event_posted.c \
src/event/ngx_event_busy_lock.c \
src/event/ngx_event_accept.c \
src/event/ngx_event_connect.c \
diff --git a/src/core/ngx_conf_file.h b/src/core/ngx_conf_file.h
index ed73803a9..322b23a6e 100644
--- a/src/core/ngx_conf_file.h
+++ b/src/core/ngx_conf_file.h
@@ -176,12 +176,12 @@ char *ngx_conf_check_num_bounds(ngx_conf_t *cf, void *post, void *data);
}
#define ngx_conf_init_size_value(conf, default) \
- if (conf == NGX_CONF_UNSET) { \
+ if (conf == NGX_CONF_UNSET_SIZE) { \
conf = default; \
}
#define ngx_conf_init_msec_value(conf, default) \
- if (conf == NGX_CONF_UNSET) { \
+ if (conf == NGX_CONF_UNSET_MSEC) { \
conf = default; \
}
diff --git a/src/event/modules/ngx_epoll_module.c b/src/event/modules/ngx_epoll_module.c
index 3f534ff17..fb41fd417 100644
--- a/src/event/modules/ngx_epoll_module.c
+++ b/src/event/modules/ngx_epoll_module.c
@@ -168,10 +168,11 @@ static int ngx_epoll_init(ngx_cycle_t *cycle)
ngx_event_actions = ngx_epoll_module_ctx.actions;
#if (HAVE_CLEAR_EVENT)
- ngx_event_flags = NGX_USE_CLEAR_EVENT;
+ ngx_event_flags = NGX_USE_CLEAR_EVENT
#else
- ngx_event_flags = NGX_USE_LEVEL_EVENT;
+ ngx_event_flags = NGX_USE_LEVEL_EVENT
#endif
+ |NGX_HAVE_INSTANCE_EVENT;
return NGX_OK;
}
@@ -257,7 +258,7 @@ static int ngx_epoll_del_event(ngx_event_t *ev, int event, u_int flags)
/*
* when the file descriptor is closed the epoll automatically deletes
* it from its queue so we do not need to delete explicity the event
- * before the closing the file descriptor.
+ * before the closing the file descriptor
*/
if (flags & NGX_CLOSE_EVENT) {
@@ -339,21 +340,36 @@ static int ngx_epoll_del_connection(ngx_connection_t *c)
int ngx_epoll_process_events(ngx_cycle_t *cycle)
{
- int events;
- ngx_int_t instance, i;
- size_t n;
- ngx_msec_t timer;
- ngx_err_t err;
- struct timeval tv;
- ngx_connection_t *c;
- ngx_epoch_msec_t delta;
-
+ int events;
+ ngx_int_t instance, i;
+ ngx_uint_t lock, expire;
+ size_t n;
+ ngx_msec_t timer;
+ ngx_err_t err;
+ struct timeval tv;
+ ngx_connection_t *c;
+ ngx_epoch_msec_t delta;
timer = ngx_event_find_timer();
ngx_old_elapsed_msec = ngx_elapsed_msec;
if (timer == 0) {
timer = (ngx_msec_t) -1;
+ expire = 0;
+
+ } else {
+ expire = 1;
+ }
+
+ if (ngx_accept_mutex) {
+ if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {
+ return NGX_ERROR;
+ }
+
+ if (ngx_accept_mutex_held == 0 && timer > ngx_accept_mutex_delay) {
+ timer = ngx_accept_mutex_delay;
+ expire = 0;
+ }
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
@@ -382,6 +398,7 @@ int ngx_epoll_process_events(ngx_cycle_t *cycle)
if (events == 0) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
"epoll_wait() returned no events without timeout");
+ ngx_accept_mutex_unlock();
return NGX_ERROR;
}
}
@@ -389,9 +406,17 @@ int ngx_epoll_process_events(ngx_cycle_t *cycle)
if (err) {
ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT,
cycle->log, err, "epoll_wait() failed");
+ ngx_accept_mutex_unlock();
return NGX_ERROR;
}
+ if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
+ ngx_accept_mutex_unlock();
+ return NGX_ERROR;
+ }
+
+ lock = 1;
+
for (i = 0; i < events; i++) {
c = event_list[i].data.ptr;
@@ -434,25 +459,68 @@ int ngx_epoll_process_events(ngx_cycle_t *cycle)
c->fd, event_list[i].events);
}
+ if ((event_list[i].events & (EPOLLOUT|EPOLLERR|EPOLLHUP))
+ && c->write->active)
+ {
+ c->write->ready = 1;
+
+ if (!ngx_threaded && !ngx_accept_mutex_held) {
+ c->write->event_handler(c->write);
+
+ } else {
+ ngx_post_event(c->write);
+ }
+ }
+
+ /*
+ * EPOLLIN must be handled after EPOLLOUT because we use
+ * the optimization to avoid the unnecessary mutex locking/unlocking
+ * if the accept event is the last one.
+ */
+
if ((event_list[i].events & (EPOLLIN|EPOLLERR|EPOLLHUP))
&& c->read->active)
{
c->read->ready = 1;
- c->read->event_handler(c->read);
- }
- if ((event_list[i].events & (EPOLLOUT|EPOLLERR|EPOLLHUP))
- && c->write->active)
- {
- c->write->ready = 1;
- c->write->event_handler(c->write);
+ if (!ngx_threaded && !ngx_accept_mutex_held) {
+ c->read->event_handler(c->read);
+
+ } else if (!c->read->accept) {
+ ngx_post_event(c->read);
+
+ } else {
+ ngx_mutex_unlock(ngx_posted_events_mutex);
+
+ c->read->event_handler(c->read);
+
+ if (i + 1 == events) {
+ lock = 0;
+ break;
+ }
+
+ if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
+ ngx_accept_mutex_unlock();
+ return NGX_ERROR;
+ }
+ }
}
}
- if (timer != (ngx_msec_t) -1 && delta) {
+ if (lock) {
+ ngx_mutex_unlock(ngx_posted_events_mutex);
+ }
+
+ ngx_accept_mutex_unlock();
+
+ if (expire && delta) {
ngx_event_expire_timers((ngx_msec_t) delta);
}
+ if (!ngx_threaded) {
+ ngx_event_process_posted(cycle);
+ }
+
return NGX_OK;
}
diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c
index 7c39d80b9..c339660db 100644
--- a/src/event/modules/ngx_kqueue_module.c
+++ b/src/event/modules/ngx_kqueue_module.c
@@ -22,9 +22,6 @@ static int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags);
static int ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags);
static int ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags);
static int ngx_kqueue_process_events(ngx_cycle_t *cycle);
-#if (NGX_THREADS)
-static void ngx_kqueue_thread_handler(ngx_event_t *ev);
-#endif
static void *ngx_kqueue_create_conf(ngx_cycle_t *cycle);
static char *ngx_kqueue_init_conf(ngx_cycle_t *cycle, void *conf);
@@ -71,9 +68,6 @@ ngx_event_module_t ngx_kqueue_module_ctx = {
NULL, /* add an connection */
NULL, /* delete an connection */
ngx_kqueue_process_events, /* process the events */
-#if (NGX_THREADS0)
- ngx_kqueue_thread_handler, /* process an event by thread */
-#endif
ngx_kqueue_init, /* init the events */
ngx_kqueue_done /* done the events */
}
@@ -161,6 +155,7 @@ static int ngx_kqueue_init(ngx_cycle_t *cycle)
#if (HAVE_LOWAT_EVENT)
|NGX_HAVE_LOWAT_EVENT
#endif
+ |NGX_HAVE_INSTANCE_EVENT
|NGX_HAVE_KQUEUE_EVENT;
return NGX_OK;
@@ -346,8 +341,8 @@ static int ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags)
static ngx_int_t ngx_kqueue_process_events(ngx_cycle_t *cycle)
{
int events;
- ngx_int_t i;
- ngx_uint_t instance;
+ ngx_int_t i, instance;
+ ngx_uint_t lock, expire;
ngx_err_t err;
ngx_msec_t timer;
ngx_event_t *ev;
@@ -364,23 +359,25 @@ static ngx_int_t ngx_kqueue_process_events(ngx_cycle_t *cycle)
/*
* TODO: if timer is 0 and any worker thread is still busy
- * then set 1 second timeout
+ * then set 500 ms timeout
*/
#endif
ngx_old_elapsed_msec = ngx_elapsed_msec;
+ expire = 1;
if (ngx_accept_mutex) {
if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {
return NGX_ERROR;
}
-#if 1
- if (ngx_accept_mutex_held == 0 && timer == 0) {
- /* STUB */ timer = 500;
+ if (ngx_accept_mutex_held == 0
+ && (timer == 0 || timer > ngx_accept_mutex_delay))
+ {
+ timer = ngx_accept_mutex_delay;
+ expire = 0;
}
-#endif
}
if (timer) {
@@ -390,6 +387,7 @@ static ngx_int_t ngx_kqueue_process_events(ngx_cycle_t *cycle)
} else {
tp = NULL;
+ expire = 0;
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
@@ -441,6 +439,8 @@ static ngx_int_t ngx_kqueue_process_events(ngx_cycle_t *cycle)
return NGX_ERROR;
}
+ lock = 1;
+
for (i = 0; i < events; i++) {
ngx_log_debug6(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
@@ -517,105 +517,48 @@ static ngx_int_t ngx_kqueue_process_events(ngx_cycle_t *cycle)
continue;
}
-
- if (ngx_threaded || ngx_accept_mutex_held) {
-
- if (ev->accept) {
- ngx_mutex_unlock(ngx_posted_events_mutex);
-
- ev->event_handler(ev);
-
- if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
- ngx_accept_mutex_unlock();
- return NGX_ERROR;
- }
-
- } else {
- ev->next = (ngx_event_t *) ngx_posted_events;
- ngx_posted_events = ev;
- }
-
+ if (!ngx_threaded && !ngx_accept_mutex_held) {
+ ev->event_handler(ev);
continue;
}
- ev->event_handler(ev);
- }
-
- ngx_mutex_unlock(ngx_posted_events_mutex);
-
- ngx_accept_mutex_unlock();
-
- if (timer && delta) {
- ngx_event_expire_timers((ngx_msec_t) delta);
- }
-
- if (ngx_threaded) {
- return NGX_OK;
- }
-
- for ( ;; ) {
-
- ev = (ngx_event_t *) ngx_posted_events;
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "kevent: posted event " PTR_FMT, ev);
-
- if (ev == NULL) {
- break;
+ if (!ev->accept) {
+ ngx_post_event(ev);
+ continue;
}
- ngx_posted_events = ev->next;
+ ngx_mutex_unlock(ngx_posted_events_mutex);
- if ((!ev->posted && !ev->active)
- || ev->instance != ev->returned_instance)
- {
- /*
- * the stale event from a file descriptor
- * that was just closed in this iteration
- */
+ ev->event_handler(ev);
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
- "kevent: stale event " PTR_FMT, ev);
- continue;
+ if (i + 1 == events) {
+ lock = 0;
+ break;
}
- if (ev->posted) {
- ev->posted = 0;
+ if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
+ ngx_accept_mutex_unlock();
+ return NGX_ERROR;
}
-
- ev->event_handler(ev);
}
- return NGX_OK;
-}
-
+ if (lock) {
+ ngx_mutex_unlock(ngx_posted_events_mutex);
+ }
-#if (NGX_THREADS)
+ ngx_accept_mutex_unlock();
-static void ngx_kqueue_thread_handler(ngx_event_t *ev)
-{
- if ((!ev->posted && !ev->active)
- || ev->instance != ev->returned_instance)
- {
- /*
- * the stale event from a file descriptor
- * that was just closed in this iteration
- */
-
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "kevent: stale event " PTR_FMT, ev);
- return;
+ if (expire && delta) {
+ ngx_event_expire_timers((ngx_msec_t) delta);
}
- if (ev->posted) {
- ev->posted = 0;
+ if (!ngx_threaded) {
+ ngx_event_process_posted(cycle);
}
- ev->event_handler(ev);
+ return NGX_OK;
}
-#endif
-
static void *ngx_kqueue_create_conf(ngx_cycle_t *cycle)
{
diff --git a/src/event/modules/ngx_rtsig_module.c b/src/event/modules/ngx_rtsig_module.c
index 5686b6eec..19234610d 100644
--- a/src/event/modules/ngx_rtsig_module.c
+++ b/src/event/modules/ngx_rtsig_module.c
@@ -117,7 +117,7 @@ static int ngx_rtsig_init(ngx_cycle_t *cycle)
ngx_event_actions = ngx_rtsig_module_ctx.actions;
- ngx_event_flags = NGX_USE_SIGIO_EVENT;
+ ngx_event_flags = NGX_USE_SIGIO_EVENT|NGX_HAVE_INSTANCE_EVENT;
return NGX_OK;
}
diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c
index 9c8411400..ebb56ce84 100644
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -49,13 +49,9 @@ ngx_event_actions_t ngx_event_actions;
ngx_atomic_t *ngx_accept_mutex_ptr;
ngx_atomic_t *ngx_accept_mutex;
ngx_uint_t ngx_accept_mutex_held;
+ngx_msec_t ngx_accept_mutex_delay;
-ngx_thread_volatile ngx_event_t *ngx_posted_events;
-#if (NGX_THREADS)
-ngx_mutex_t *ngx_posted_events_mutex;
-#endif
-
static ngx_str_t events_name = ngx_string("events");
@@ -114,6 +110,13 @@ static ngx_command_t ngx_event_core_commands[] = {
offsetof(ngx_event_conf_t, accept_mutex),
NULL },
+ { ngx_string("accept_mutex_delay"),
+ NGX_EVENT_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_msec_slot,
+ 0,
+ offsetof(ngx_event_conf_t, accept_mutex_delay),
+ NULL },
+
ngx_null_command
};
@@ -186,10 +189,12 @@ static ngx_int_t ngx_event_process_init(ngx_cycle_t *cycle)
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
+ ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module);
if (ccf->worker_processes > 1 && ngx_accept_mutex_ptr) {
ngx_accept_mutex = ngx_accept_mutex_ptr;
ngx_accept_mutex_held = 1;
+ ngx_accept_mutex_delay = ecf->accept_mutex_delay;
}
#if (NGX_THREADS)
@@ -202,8 +207,6 @@ static ngx_int_t ngx_event_process_init(ngx_cycle_t *cycle)
return NGX_ERROR;
}
- ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module);
-
cycle->connection_n = ecf->connections;
for (m = 0; ngx_modules[m]; m++) {
@@ -525,6 +528,7 @@ static void *ngx_event_create_conf(ngx_cycle_t *cycle)
ecf->use = NGX_CONF_UNSET;
ecf->multi_accept = NGX_CONF_UNSET;
ecf->accept_mutex = NGX_CONF_UNSET;
+ ecf->accept_mutex_delay = NGX_CONF_UNSET_MSEC;
ecf->name = (void *) NGX_CONF_UNSET;
return ecf;
@@ -598,6 +602,7 @@ static char *ngx_event_init_conf(ngx_cycle_t *cycle, void *conf)
ngx_conf_init_value(ecf->multi_accept, 0);
ngx_conf_init_value(ecf->accept_mutex, 1);
+ ngx_conf_init_msec_value(ecf->accept_mutex_delay, 500);
return NGX_CONF_OK;
}
diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h
index 7fa1a9365..1dcfe5066 100644
--- a/src/event/ngx_event.h
+++ b/src/event/ngx_event.h
@@ -65,6 +65,7 @@ struct ngx_event_s {
unsigned char write:1;
/* used to detect the stale events in kqueue, rt signals and epoll */
+ unsigned char use_instance:1;
unsigned char instance:1;
unsigned char returned_instance:1;
@@ -79,7 +80,7 @@ struct ngx_event_s {
unsigned char posted:1;
/* the ready event; in aio mode 0 means that no operation can be posted */
- unsigned char ready:1;
+ unsigned short ready:1;
/* aio operation is complete */
unsigned short complete:1;
@@ -196,59 +197,65 @@ extern ngx_event_actions_t ngx_event_actions;
* The event filter requires to read/write the whole data -
* select, poll, /dev/poll, kqueue, epoll.
*/
-#define NGX_USE_LEVEL_EVENT 0x00000001
+#define NGX_USE_LEVEL_EVENT 0x00000001
/*
* The event filter is deleted after a notification without an additional
* syscall - select, poll, kqueue, epoll.
*/
-#define NGX_USE_ONESHOT_EVENT 0x00000002
+#define NGX_USE_ONESHOT_EVENT 0x00000002
/*
* The event filter notifies only the changes and an initial level -
* kqueue, epoll.
*/
-#define NGX_USE_CLEAR_EVENT 0x00000004
+#define NGX_USE_CLEAR_EVENT 0x00000004
/*
* The event filter has kqueue features - the eof flag, errno,
* available data, etc.
*/
-#define NGX_HAVE_KQUEUE_EVENT 0x00000008
+#define NGX_HAVE_KQUEUE_EVENT 0x00000008
/*
* The event filter supports low water mark - kqueue's NOTE_LOWAT.
* kqueue in FreeBSD 4.1-4.2 has no NOTE_LOWAT so we need a separate flag.
*/
-#define NGX_HAVE_LOWAT_EVENT 0x00000010
+#define NGX_HAVE_LOWAT_EVENT 0x00000010
+
+/*
+ * The event filter allows to pass instance information to check stale events -
+ * kqueue, epoll, rt signals.
+ */
+#define NGX_HAVE_INSTANCE_EVENT 0x00000020
/*
* The event filter notifies only the changes (the edges)
* but not an initial level - early epoll patches.
*/
-#define NGX_USE_EDGE_EVENT 0x00000020
+#define NGX_USE_EDGE_EVENT 0x00000040
/*
* No need to add or delete the event filters - rt signals.
*/
-#define NGX_USE_SIGIO_EVENT 0x00000040
+#define NGX_USE_SIGIO_EVENT 0x00000080
/*
* The alternative event method after the rt signals queue overflow.
*/
-#define NGX_OVERFLOW_EVENT 0x00000080
+#define NGX_OVERFLOW_EVENT 0x00000100
/*
* No need to add or delete the event filters - overlapped, aio_read,
* aioread, io_submit.
*/
-#define NGX_USE_AIO_EVENT 0x00000100
+#define NGX_USE_AIO_EVENT 0x00000200
/*
* Need to add socket or handle only once - i/o completion port.
* It also requires HAVE_AIO and NGX_USE_AIO_EVENT to be set.
*/
-#define NGX_USE_IOCP_EVENT 0x00000200
+#define NGX_USE_IOCP_EVENT 0x00000400
@@ -380,6 +387,8 @@ typedef struct {
ngx_flag_t multi_accept;
ngx_flag_t accept_mutex;
+ ngx_msec_t accept_mutex_delay;
+
u_char *name;
} ngx_event_conf_t;
@@ -395,14 +404,11 @@ typedef struct {
-extern ngx_thread_volatile ngx_event_t *ngx_posted_events;
-#if (NGX_THREADS)
-extern ngx_mutex_t *ngx_posted_events_mutex;
-#endif
-
extern ngx_atomic_t *ngx_accept_mutex_ptr;
extern ngx_atomic_t *ngx_accept_mutex;
extern ngx_uint_t ngx_accept_mutex_held;
+extern ngx_msec_t ngx_accept_mutex_delay;
+
#define ngx_accept_mutex_unlock() \
if (ngx_accept_mutex_held) { \
@@ -437,6 +443,7 @@ int ngx_event_post_acceptex(ngx_listening_t *ls, int n);
#include <ngx_event_timer.h>
+#include <ngx_event_posted.h>
#include <ngx_event_busy_lock.h>
#if (WIN32)
diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c
index 41794bea9..c955bbfa3 100644
--- a/src/event/ngx_event_accept.c
+++ b/src/event/ngx_event_accept.c
@@ -218,11 +218,15 @@ void ngx_event_accept(ngx_event_t *ev)
c->sockaddr = sa;
c->socklen = len;
- rev->instance = (u_char) !instance;
- rev->returned_instance = (u_char) rinstance;
-
- wev->instance = (u_char) !instance;
- wev->returned_instance = (u_char) winstance;
+ if (ngx_event_flags & NGX_HAVE_INSTANCE_EVENT) {
+ rev->use_instance = 1;
+ rev->instance = (u_char) !instance;
+ rev->returned_instance = (u_char) rinstance;
+
+ wev->use_instance = 1;
+ wev->instance = (u_char) !instance;
+ wev->returned_instance = (u_char) winstance;
+ }
rev->index = NGX_INVALID_INDEX;
wev->index = NGX_INVALID_INDEX;
@@ -302,7 +306,9 @@ void ngx_event_accept(ngx_event_t *ev)
ngx_int_t ngx_trylock_accept_mutex(ngx_cycle_t *cycle)
{
- if (*ngx_accept_mutex == 0 && ngx_atomic_cmp_set(ngx_accept_mutex, 0, 1)) {
+ if (*ngx_accept_mutex == 0
+ && ngx_atomic_cmp_set(ngx_accept_mutex, 0, ngx_pid))
+ {
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"accept mutex locked");
diff --git a/src/event/ngx_event_connect.c b/src/event/ngx_event_connect.c
index a433e1d90..24fa834ec 100644
--- a/src/event/ngx_event_connect.c
+++ b/src/event/ngx_event_connect.c
@@ -11,7 +11,7 @@
int ngx_event_connect_peer(ngx_peer_connection_t *pc)
{
int rc;
- ngx_uint_t instance;
+ ngx_uint_t instance, rinstance, winstance;
u_int event;
time_t now;
ngx_err_t err;
@@ -156,11 +156,23 @@ int ngx_event_connect_peer(ngx_peer_connection_t *pc)
#endif
instance = rev->instance;
+ rinstance = rev->returned_instance;
+ winstance = wev->returned_instance;
ngx_memzero(c, sizeof(ngx_connection_t));
ngx_memzero(rev, sizeof(ngx_event_t));
ngx_memzero(wev, sizeof(ngx_event_t));
+ if (ngx_event_flags & NGX_HAVE_INSTANCE_EVENT) {
+ rev->use_instance = 1;
+ rev->instance = (u_char) !instance;
+ rev->returned_instance = (u_char) rinstance;
+
+ wev->use_instance = 1;
+ wev->instance = (u_char) !instance;
+ wev->returned_instance = (u_char) winstance;
+ }
+
rev->index = NGX_INVALID_INDEX;
wev->index = NGX_INVALID_INDEX;
@@ -171,9 +183,6 @@ int ngx_event_connect_peer(ngx_peer_connection_t *pc)
c->write = wev;
wev->write = 1;
- rev->instance = (u_char) !instance;
- wev->instance = (u_char) !instance;
-
c->log = pc->log;
rev->log = pc->log;
wev->log = pc->log;
diff --git a/src/event/ngx_event_posted.c b/src/event/ngx_event_posted.c
new file mode 100644
index 000000000..7cdbfa397
--- /dev/null
+++ b/src/event/ngx_event_posted.c
@@ -0,0 +1,76 @@
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_event.h>
+
+
+ngx_thread_volatile ngx_event_t *ngx_posted_events;
+#if (NGX_THREADS)
+ngx_mutex_t *ngx_posted_events_mutex;
+#endif
+
+
+void ngx_event_process_posted(ngx_cycle_t *cycle)
+{
+ ngx_event_t *ev;
+
+ for ( ;; ) {
+
+ ev = (ngx_event_t *) ngx_posted_events;
+
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
+ "posted event " PTR_FMT, ev);
+
+ if (ev == NULL) {
+ return;
+ }
+
+ ngx_posted_events = ev->next;
+
+ if ((!ev->posted && !ev->active)
+ || (ev->use_instance && ev->instance != ev->returned_instance))
+ {
+ /*
+ * the stale event from a file descriptor
+ * that was just closed in this iteration
+ */
+
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
+ "stale posted event " PTR_FMT, ev);
+ continue;
+ }
+
+ if (ev->posted) {
+ ev->posted = 0;
+ }
+
+ ev->event_handler(ev);
+ }
+}
+
+
+#if (NGX_THREADS)
+
+void ngx_event_thread_handler(ngx_event_t *ev)
+{
+ if ((!ev->posted && !ev->active)
+ || (ev->use_instance && ev->instance != ev->returned_instance))
+ {
+ /*
+ * the stale event from a file descriptor
+ * that was just closed in this iteration
+ */
+
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0,
+ "kevent: stale event " PTR_FMT, ev);
+ return;
+ }
+
+ if (ev->posted) {
+ ev->posted = 0;
+ }
+
+ ev->event_handler(ev);
+}
+
+#endif
diff --git a/src/event/ngx_event_posted.h b/src/event/ngx_event_posted.h
new file mode 100644
index 000000000..78f302e0e
--- /dev/null
+++ b/src/event/ngx_event_posted.h
@@ -0,0 +1,28 @@
+#ifndef _NGX_EVENT_POSTED_H_INCLUDED_
+#define _NGX_EVENT_POSTED_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_event.h>
+
+
+#define ngx_post_event(ev) \
+ ev->next = (ngx_event_t *) ngx_posted_events; \
+ ngx_posted_events = ev; \
+ ev->posted = 1;
+
+
+void ngx_event_process_posted(ngx_cycle_t *cycle);
+#if (NGX_THREADS)
+void ngx_event_thread_handler(ngx_event_t *ev);
+#endif
+
+
+extern ngx_thread_volatile ngx_event_t *ngx_posted_events;
+#if (NGX_THREADS)
+extern ngx_mutex_t *ngx_posted_events_mutex;
+#endif
+
+
+#endif /* _NGX_EVENT_POSTED_H_INCLUDED_ */
diff --git a/src/event/ngx_event_timer.c b/src/event/ngx_event_timer.c
index 79a2e195d..b66241b66 100644
--- a/src/event/ngx_event_timer.c
+++ b/src/event/ngx_event_timer.c
@@ -42,18 +42,14 @@ ngx_msec_t ngx_event_find_timer(void)
return 0;
}
-#if (NGX_THREADS)
if (ngx_mutex_lock(ngx_event_timer_mutex) == NGX_ERROR) {
return NGX_TIMER_ERROR;
}
-#endif
node = ngx_rbtree_min((ngx_rbtree_t *) ngx_event_timer_rbtree,
&ngx_event_timer_sentinel);
-#if (NGX_THREADS)
ngx_mutex_unlock(ngx_event_timer_mutex);
-#endif
return (ngx_msec_t)
(node->key * NGX_TIMER_RESOLUTION -
@@ -75,18 +71,14 @@ void ngx_event_expire_timers(ngx_msec_t timer)
break;
}
-#if (NGX_THREADS)
if (ngx_mutex_lock(ngx_event_timer_mutex) == NGX_ERROR) {
return;
}
-#endif
node = ngx_rbtree_min((ngx_rbtree_t *) ngx_event_timer_rbtree,
&ngx_event_timer_sentinel);
-#if (NGX_THREADS)
ngx_mutex_unlock(ngx_event_timer_mutex);
-#endif
if ((ngx_msec_t) node->key <= (ngx_msec_t)
(ngx_old_elapsed_msec + timer) / NGX_TIMER_RESOLUTION)
@@ -106,9 +98,16 @@ void ngx_event_expire_timers(ngx_msec_t timer)
ev->timedout = 1;
}
-#if (NGX_THREADS)
- /* STUB: post event */
-#endif
+ if (ngx_threaded) {
+ if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
+ return;
+ }
+
+ ngx_post_event(ev);
+
+ ngx_mutex_unlock(ngx_posted_events_mutex);
+ continue;
+ }
ev->event_handler(ev);
continue;
diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.c b/src/http/modules/proxy/ngx_http_proxy_handler.c
index cb29559ee..84c926470 100644
--- a/src/http/modules/proxy/ngx_http_proxy_handler.c
+++ b/src/http/modules/proxy/ngx_http_proxy_handler.c
@@ -369,6 +369,9 @@ static int ngx_http_proxy_handler(ngx_http_request_t *r)
void ngx_http_proxy_check_broken_connection(ngx_event_t *ev)
{
+ int n;
+ char buf[1];
+ ngx_err_t err;
ngx_connection_t *c;
ngx_http_request_t *r;
ngx_http_proxy_ctx_t *p;
@@ -376,15 +379,18 @@ void ngx_http_proxy_check_broken_connection(ngx_event_t *ev)
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ev->log, 0,
"http proxy check client, write event:%d", ev->write);
- c = ev->data;
- r = c->data;
- p = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
-
#if (HAVE_KQUEUE)
- /* TODO: KEVENT_EVENT */
+ if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
+
+ if (!ev->kq_eof) {
+ return;
+ }
+
+ c = ev->data;
+ r = c->data;
+ p = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
- if (ev->kq_eof) {
ev->eof = 1;
if (ev->kq_errno) {
@@ -407,17 +413,31 @@ void ngx_http_proxy_check_broken_connection(ngx_event_t *ev)
if (p->upstream == NULL || p->upstream->peer.connection == NULL) {
ngx_http_proxy_finalize_request(p, NGX_HTTP_CLIENT_CLOSED_REQUEST);
}
+
+ return;
}
-#else
+#endif
+
+ c = ev->data;
+ r = c->data;
+ p = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
n = recv(c->fd, buf, 1, MSG_PEEK);
if (n > 0) {
- /* TODO: delete level */
+ if ((ngx_event_flags & NGX_USE_LEVEL_EVENT) && ev->active) {
+ if (ngx_del_event(ev, NGX_READ_EVENT, 0) == NGX_ERROR) {
+ ngx_http_proxy_finalize_request(p,
+ NGX_HTTP_INTERNAL_SERVER_ERROR);
+ }
+ }
+
return;
}
+ ev->eof = 1;
+
if (n == -1) {
err = ngx_socket_errno;
if (err == NGX_EAGAIN) {
@@ -426,9 +446,9 @@ void ngx_http_proxy_check_broken_connection(ngx_event_t *ev)
ev->error = 1;
- } else if (n == 0) {
+ } else {
+ /* n == 0 */
err = 0;
- ev->eof = 1;
}
if (!p->cachable && p->upstream->peer.connection) {
@@ -439,14 +459,12 @@ void ngx_http_proxy_check_broken_connection(ngx_event_t *ev)
return;
}
- ngx_log_error(NGX_LOG_INFO, ev->log, ev->err,
+ ngx_log_error(NGX_LOG_INFO, ev->log, err,
"client have closed prematurely connection");
if (p->upstream == NULL || p->upstream->peer.connection == NULL) {
ngx_http_proxy_finalize_request(p, NGX_HTTP_CLIENT_CLOSED_REQUEST);
}
-
-#endif
}
@@ -870,8 +888,15 @@ static char *ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf,
ngx_conf_merge_size_value(conf->header_buffer_size,
prev->header_buffer_size, 4096);
+
ngx_conf_merge_bufs_value(conf->bufs, prev->bufs, 8, 4096);
+ if (conf->bufs.num < 2) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "there must be at least 2 \"proxy_buffers\"");
+ return NGX_CONF_ERROR;
+ }
+
size = conf->header_buffer_size;
if (size < conf->bufs.size) {
size = conf->bufs.size;
@@ -891,6 +916,14 @@ static char *ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf,
"one of the \"proxy_buffers\"");
return NGX_CONF_ERROR;
+
+ } else if (conf->busy_buffers_size > (conf->bufs.num - 1) * conf->bufs.size)
+ {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "\"proxy_busy_buffers_size\" must be less than "
+ "the size of all \"proxy_buffers\" minus one buffer");
+
+ return NGX_CONF_ERROR;
}
diff --git a/src/os/unix/ngx_process.c b/src/os/unix/ngx_process.c
index d49ba3258..8736da781 100644
--- a/src/os/unix/ngx_process.c
+++ b/src/os/unix/ngx_process.c
@@ -1,6 +1,7 @@
#include <ngx_config.h>
#include <ngx_core.h>
+#include <ngx_event.h>
static void ngx_execute_proc(ngx_cycle_t *cycle, void *data);
@@ -142,6 +143,18 @@ void ngx_process_get_status()
return;
}
+
+ if (ngx_accept_mutex_ptr) {
+
+ /*
+ * unlock the accept mutex if the abnormally exited process
+ * held it
+ */
+
+ ngx_atomic_cmp_set(ngx_accept_mutex_ptr, pid, 0);
+ }
+
+
one = 1;
process = "";
diff --git a/src/os/win32/ngx_process_cycle.c b/src/os/win32/ngx_process_cycle.c
index 1b8f18629..ab387d458 100644
--- a/src/os/win32/ngx_process_cycle.c
+++ b/src/os/win32/ngx_process_cycle.c
@@ -16,6 +16,8 @@ sig_atomic_t ngx_timer;
#endif
+ngx_int_t ngx_threaded;
+
sig_atomic_t ngx_terminate;
sig_atomic_t ngx_quit;