diff src/event/modules/ngx_epoll_module.c @ 5372:36b58ddb566d

Events: support for EPOLLRDHUP (ticket #320). Since Linux 2.6.17, epoll is able to report about peer half-closed connection using special EPOLLRDHUP flag on a read event.
author Valentin Bartenev <vbart@nginx.com>
date Fri, 12 Jul 2013 14:51:07 +0400
parents 4c36e15651f7
children 31dd63dcb9ea
line wrap: on
line diff
--- 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
     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
 
     } else {
         e = c->read;
-        prev = EPOLLIN;
+        prev = EPOLLIN|EPOLLRDHUP;
     }
 
     if (e->active) {
@@ -501,7 +503,7 @@ ngx_epoll_add_connection(ngx_connection_
 {
     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 *cy
 
         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;