summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--auto/modules1
-rw-r--r--auto/os/linux16
-rw-r--r--src/event/modules/ngx_epoll_module.c18
-rw-r--r--src/event/ngx_event.h9
4 files changed, 37 insertions, 7 deletions
diff --git a/auto/modules b/auto/modules
index e710ae0ff..3feaf53e1 100644
--- a/auto/modules
+++ b/auto/modules
@@ -42,6 +42,7 @@ fi
if [ $NGX_TEST_BUILD_EPOLL = YES ]; then
have=NGX_HAVE_EPOLL . auto/have
+ have=NGX_HAVE_EPOLLRDHUP . auto/have
have=NGX_HAVE_EVENTFD . auto/have
have=NGX_TEST_BUILD_EPOLL . auto/have
EVENT_MODULES="$EVENT_MODULES $EPOLL_MODULE"
diff --git a/auto/os/linux b/auto/os/linux
index c0391d98e..19bf832ce 100644
--- a/auto/os/linux
+++ b/auto/os/linux
@@ -65,6 +65,22 @@ if [ $ngx_found = yes ]; then
CORE_SRCS="$CORE_SRCS $EPOLL_SRCS"
EVENT_MODULES="$EVENT_MODULES $EPOLL_MODULE"
EVENT_FOUND=YES
+
+
+ # EPOLLRDHUP appeared in Linux 2.6.17, glibc 2.8
+
+ ngx_feature="EPOLLRDHUP"
+ ngx_feature_name="NGX_HAVE_EPOLLRDHUP"
+ ngx_feature_run=no
+ ngx_feature_incs="#include <sys/epoll.h>"
+ ngx_feature_path=
+ ngx_feature_libs=
+ ngx_feature_test="int efd = 0, fd = 0;
+ struct epoll_event ee;
+ ee.events = EPOLLIN|EPOLLRDHUP|EPOLLET;
+ ee.data.ptr = NULL;
+ epoll_ctl(efd, EPOLL_CTL_ADD, fd, &ee)"
+ . auto/feature
fi
diff --git a/src/event/modules/ngx_epoll_module.c b/src/event/modules/ngx_epoll_module.c
index ee77d8e4a..f5f663179 100644
--- a/src/event/modules/ngx_epoll_module.c
+++ b/src/event/modules/ngx_epoll_module.c
@@ -25,6 +25,8 @@
#define EPOLLERR 0x008
#define EPOLLHUP 0x010
+#define EPOLLRDHUP 0x2000
+
#define EPOLLET 0x80000000
#define EPOLLONESHOT 0x40000000
@@ -396,13 +398,13 @@ ngx_epoll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
if (event == NGX_READ_EVENT) {
e = c->write;
prev = EPOLLOUT;
-#if (NGX_READ_EVENT != EPOLLIN)
- events = EPOLLIN;
+#if (NGX_READ_EVENT != EPOLLIN|EPOLLRDHUP)
+ events = EPOLLIN|EPOLLRDHUP;
#endif
} else {
e = c->read;
- prev = EPOLLIN;
+ prev = EPOLLIN|EPOLLRDHUP;
#if (NGX_WRITE_EVENT != EPOLLOUT)
events = EPOLLOUT;
#endif
@@ -466,7 +468,7 @@ ngx_epoll_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
} else {
e = c->read;
- prev = EPOLLIN;
+ prev = EPOLLIN|EPOLLRDHUP;
}
if (e->active) {
@@ -501,7 +503,7 @@ ngx_epoll_add_connection(ngx_connection_t *c)
{
struct epoll_event ee;
- ee.events = EPOLLIN|EPOLLOUT|EPOLLET;
+ ee.events = EPOLLIN|EPOLLOUT|EPOLLET|EPOLLRDHUP;
ee.data.ptr = (void *) ((uintptr_t) c | c->read->instance);
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
@@ -666,6 +668,12 @@ ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
if ((revents & EPOLLIN) && rev->active) {
+#if (NGX_HAVE_EPOLLRDHUP)
+ if (revents & EPOLLRDHUP) {
+ rev->pending_eof = 1;
+ }
+#endif
+
if ((flags & NGX_POST_THREAD_EVENTS) && !rev->accept) {
rev->posted_ready = 1;
diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h
index 122b538a7..530c9486c 100644
--- a/src/event/ngx_event.h
+++ b/src/event/ngx_event.h
@@ -71,7 +71,7 @@ struct ngx_event_s {
unsigned deferred_accept:1;
- /* the pending eof reported by kqueue or in aio chain operation */
+ /* the pending eof reported by kqueue, epoll or in aio chain operation */
unsigned pending_eof:1;
#if !(NGX_THREADS)
@@ -349,6 +349,11 @@ extern ngx_event_actions_t ngx_event_actions;
#define NGX_VNODE_EVENT 0
+#if (NGX_HAVE_EPOLL) && !(NGX_HAVE_EPOLLRDHUP)
+#define EPOLLRDHUP 0
+#endif
+
+
#if (NGX_HAVE_KQUEUE)
#define NGX_READ_EVENT EVFILT_READ
@@ -392,7 +397,7 @@ extern ngx_event_actions_t ngx_event_actions;
#elif (NGX_HAVE_EPOLL)
-#define NGX_READ_EVENT EPOLLIN
+#define NGX_READ_EVENT (EPOLLIN|EPOLLRDHUP)
#define NGX_WRITE_EVENT EPOLLOUT
#define NGX_LEVEL_EVENT 0