diff options
| -rw-r--r-- | auto/modules | 1 | ||||
| -rw-r--r-- | auto/os/linux | 16 | ||||
| -rw-r--r-- | src/event/modules/ngx_epoll_module.c | 7 | ||||
| -rw-r--r-- | src/event/ngx_event.c | 29 | ||||
| -rw-r--r-- | src/event/ngx_event.h | 8 |
5 files changed, 58 insertions, 3 deletions
diff --git a/auto/modules b/auto/modules index 829079842..614037cb1 100644 --- a/auto/modules +++ b/auto/modules @@ -43,6 +43,7 @@ fi if [ $NGX_TEST_BUILD_EPOLL = YES ]; then have=NGX_HAVE_EPOLL . auto/have have=NGX_HAVE_EPOLLRDHUP . auto/have + have=NGX_HAVE_EPOLLEXCLUSIVE . 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 132ce3b42..fae8842c6 100644 --- a/auto/os/linux +++ b/auto/os/linux @@ -70,6 +70,22 @@ if [ $ngx_found = yes ]; then ee.data.ptr = NULL; epoll_ctl(efd, EPOLL_CTL_ADD, fd, &ee)" . auto/feature + + + # EPOLLEXCLUSIVE appeared in Linux 4.5, glibc 2.24 + + ngx_feature="EPOLLEXCLUSIVE" + ngx_feature_name="NGX_HAVE_EPOLLEXCLUSIVE" + 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|EPOLLEXCLUSIVE; + 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 dff778831..c267fd6c7 100644 --- a/src/event/modules/ngx_epoll_module.c +++ b/src/event/modules/ngx_epoll_module.c @@ -27,6 +27,7 @@ #define EPOLLRDHUP 0x2000 +#define EPOLLEXCLUSIVE 0x10000000 #define EPOLLONESHOT 0x40000000 #define EPOLLET 0x80000000 @@ -610,6 +611,12 @@ ngx_epoll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) op = EPOLL_CTL_ADD; } +#if (NGX_HAVE_EPOLLEXCLUSIVE && NGX_HAVE_EPOLLRDHUP) + if (flags & NGX_EXCLUSIVE_EVENT) { + events &= ~EPOLLRDHUP; + } +#endif + ee.events = events | (uint32_t) flags; ee.data.ptr = (void *) ((uintptr_t) c | ev->instance); diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c index 2f3a098de..9d6c4c91b 100644 --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -822,15 +822,38 @@ ngx_event_process_init(ngx_cycle_t *cycle) rev->handler = (c->type == SOCK_STREAM) ? ngx_event_accept : ngx_event_recvmsg; - if (ngx_use_accept_mutex #if (NGX_HAVE_REUSEPORT) - && !ls[i].reuseport + + if (ls[i].reuseport) { + if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) { + return NGX_ERROR; + } + + continue; + } + #endif - ) + + if (ngx_use_accept_mutex) { + continue; + } + +#if (NGX_HAVE_EPOLLEXCLUSIVE) + + if ((ngx_event_flags & NGX_USE_EPOLL_EVENT) + && ccf->worker_processes > 1) { + if (ngx_add_event(rev, NGX_READ_EVENT, NGX_EXCLUSIVE_EVENT) + == NGX_ERROR) + { + return NGX_ERROR; + } + continue; } +#endif + if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) { return NGX_ERROR; } diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h index 394a0e8e5..27139ee8c 100644 --- a/src/event/ngx_event.h +++ b/src/event/ngx_event.h @@ -367,6 +367,9 @@ extern ngx_uint_t ngx_use_epoll_rdhup; #define NGX_ONESHOT_EVENT EPOLLONESHOT #endif +#if (NGX_HAVE_EPOLLEXCLUSIVE) +#define NGX_EXCLUSIVE_EVENT EPOLLEXCLUSIVE +#endif #elif (NGX_HAVE_POLL) @@ -395,6 +398,11 @@ extern ngx_uint_t ngx_use_epoll_rdhup; #endif +#if (NGX_TEST_BUILD_EPOLL) +#define NGX_EXCLUSIVE_EVENT 0 +#endif + + #ifndef NGX_CLEAR_EVENT #define NGX_CLEAR_EVENT 0 /* dummy declaration */ #endif |
