aboutsummaryrefslogtreecommitdiff
path: root/src/event/modules/ngx_epoll_module.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/event/modules/ngx_epoll_module.c')
-rw-r--r--src/event/modules/ngx_epoll_module.c72
1 files changed, 71 insertions, 1 deletions
diff --git a/src/event/modules/ngx_epoll_module.c b/src/event/modules/ngx_epoll_module.c
index 166c46166..0b23a952f 100644
--- a/src/event/modules/ngx_epoll_module.c
+++ b/src/event/modules/ngx_epoll_module.c
@@ -123,6 +123,7 @@ static ngx_int_t ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
static void ngx_epoll_eventfd_handler(ngx_event_t *ev);
#endif
+static ngx_int_t ngx_epoll_module_init(ngx_cycle_t *cycle);
static void *ngx_epoll_create_conf(ngx_cycle_t *cycle);
static char *ngx_epoll_init_conf(ngx_cycle_t *cycle, void *conf);
@@ -146,6 +147,10 @@ static ngx_connection_t ngx_eventfd_conn;
#endif
+#if (NGX_HAVE_EPOLLRDHUP)
+ngx_uint_t ngx_use_epoll_rdhup;
+#endif
+
static ngx_str_t epoll_name = ngx_string("epoll");
static ngx_command_t ngx_epoll_commands[] = {
@@ -197,7 +202,7 @@ ngx_module_t ngx_epoll_module = {
ngx_epoll_commands, /* module directives */
NGX_EVENT_MODULE, /* module type */
NULL, /* init master */
- NULL, /* init module */
+ ngx_epoll_module_init, /* init module */
NULL, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
@@ -808,6 +813,8 @@ ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
if (revents & EPOLLRDHUP) {
rev->pending_eof = 1;
}
+
+ rev->available = 1;
#endif
rev->ready = 1;
@@ -943,6 +950,69 @@ ngx_epoll_eventfd_handler(ngx_event_t *ev)
#endif
+static ngx_int_t
+ngx_epoll_module_init(ngx_cycle_t *cycle)
+{
+#if (NGX_HAVE_EPOLLRDHUP)
+ int epfd, s[2], events;
+ struct epoll_event ee;
+
+ epfd = epoll_create(1);
+
+ if (epfd == -1) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "epoll_create() failed");
+ return NGX_ERROR;
+ }
+
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) == -1) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "socketpair() failed");
+ return NGX_ERROR;
+ }
+
+ ee.events = EPOLLET|EPOLLIN|EPOLLRDHUP;
+
+ if (epoll_ctl(epfd, EPOLL_CTL_ADD, s[0], &ee) == -1) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "epoll_ctl() failed");
+ return NGX_ERROR;
+ }
+
+ if (close(s[1]) == -1) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "close() failed");
+ return NGX_ERROR;
+ }
+
+ events = epoll_wait(epfd, &ee, 1, 5000);
+
+ if (events == -1) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "epoll_wait() failed");
+ return NGX_ERROR;
+ }
+
+ (void) close(s[0]);
+ (void) close(epfd);
+
+ if (events) {
+ ngx_use_epoll_rdhup = ee.events & EPOLLRDHUP;
+
+ } else {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ "epoll_wait() timedout");
+ }
+
+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,
+ "testing the EPOLLRDHUP flag: %s",
+ ngx_use_epoll_rdhup ? "success" : "fail");
+#endif
+
+ return NGX_OK;
+}
+
+
static void *
ngx_epoll_create_conf(ngx_cycle_t *cycle)
{