diff options
| author | Maxim Dounin <mdounin@mdounin.ru> | 2015-05-20 15:51:56 +0300 |
|---|---|---|
| committer | Maxim Dounin <mdounin@mdounin.ru> | 2015-05-20 15:51:56 +0300 |
| commit | f7f1607bf2b8b7c45834b66cb45f6445bee65587 (patch) | |
| tree | 8a458d848d86e6b0e7f9108fd1b792d709091965 /src/event/ngx_event_accept.c | |
| parent | d5c34785bc55164afb7cfe7de1badcebdb05fb8d (diff) | |
| download | nginx-f7f1607bf2b8b7c45834b66cb45f6445bee65587.tar.gz nginx-f7f1607bf2b8b7c45834b66cb45f6445bee65587.tar.bz2 | |
The "reuseport" option of the "listen" directive.
When configured, an individual listen socket on a given address is
created for each worker process. This allows to reduce in-kernel lock
contention on configurations with high accept rates, resulting in better
performance. As of now it works on Linux and DragonFly BSD.
Note that on Linux incoming connection requests are currently tied up
to a specific listen socket, and if some sockets are closed, connection
requests will be reset, see https://lwn.net/Articles/542629/. With
nginx, this may happen if the number of worker processes is reduced.
There is no such problem on DragonFly BSD.
Based on previous work by Sepherosa Ziehau and Yingqi Lu.
Diffstat (limited to 'src/event/ngx_event_accept.c')
| -rw-r--r-- | src/event/ngx_event_accept.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c index 3f1c0b164..8888f5acc 100644 --- a/src/event/ngx_event_accept.c +++ b/src/event/ngx_event_accept.c @@ -11,7 +11,7 @@ static ngx_int_t ngx_enable_accept_events(ngx_cycle_t *cycle); -static ngx_int_t ngx_disable_accept_events(ngx_cycle_t *cycle); +static ngx_int_t ngx_disable_accept_events(ngx_cycle_t *cycle, ngx_uint_t all); static void ngx_close_accepted_connection(ngx_connection_t *c); @@ -109,7 +109,7 @@ ngx_event_accept(ngx_event_t *ev) } if (err == NGX_EMFILE || err == NGX_ENFILE) { - if (ngx_disable_accept_events((ngx_cycle_t *) ngx_cycle) + if (ngx_disable_accept_events((ngx_cycle_t *) ngx_cycle, 1) != NGX_OK) { return; @@ -390,7 +390,7 @@ ngx_trylock_accept_mutex(ngx_cycle_t *cycle) "accept mutex lock failed: %ui", ngx_accept_mutex_held); if (ngx_accept_mutex_held) { - if (ngx_disable_accept_events(cycle) == NGX_ERROR) { + if (ngx_disable_accept_events(cycle, 0) == NGX_ERROR) { return NGX_ERROR; } @@ -413,7 +413,7 @@ ngx_enable_accept_events(ngx_cycle_t *cycle) c = ls[i].connection; - if (c->read->active) { + if (c == NULL || c->read->active) { continue; } @@ -427,7 +427,7 @@ ngx_enable_accept_events(ngx_cycle_t *cycle) static ngx_int_t -ngx_disable_accept_events(ngx_cycle_t *cycle) +ngx_disable_accept_events(ngx_cycle_t *cycle, ngx_uint_t all) { ngx_uint_t i; ngx_listening_t *ls; @@ -438,10 +438,23 @@ ngx_disable_accept_events(ngx_cycle_t *cycle) c = ls[i].connection; - if (!c->read->active) { + if (c == NULL || !c->read->active) { continue; } +#if (NGX_HAVE_REUSEPORT) + + /* + * do not disable accept on worker's own sockets + * when disabling accept events due to accept mutex + */ + + if (ls[i].reuseport && !all) { + continue; + } + +#endif + if (ngx_del_event(c->read, NGX_READ_EVENT, NGX_DISABLE_EVENT) == NGX_ERROR) { |
