The accept4() system call is available starting with Linux 2.6.28;
support
in glibc is available starting with version 2.10. It can transport the
O_NONBLOCK flags in accept, and in nginx( in linux) after accept fd,
call fcntl(twice) set fd to O_NONBLOCK.
And so if use accept4, this will be to save twice systemcall,
therefore i suggest
nginx(in linux platform) should use accept4.
void
ngx_event_accept(ngx_event_t ev)
{
…
/ replace by s = accept4(lc->fd, (struct sockaddr *) sa, &socklen,
O_NONBLOCK); */
s = accept(lc->fd, (struct sockaddr *) sa, &socklen);
…
if (!(ngx_event_flags &
(NGX_USE_AIO_EVENT|NGX_USE_RTSIG_EVENT))) {
//if use accept4,this will removed.
if (ngx_nonblocking(s) == -1) {
ngx_log_error(NGX_LOG_ALERT, ev->log,
ngx_socket_errno,
ngx_nonblocking_n " failed");
ngx_close_accepted_connection(c);
return;
}
}
On Sun, Nov 07, 2010 at 10:30:41PM +0800, BoBo wrote:
The accept4() system call is available starting with Linux 2.6.28; support
in glibc is available starting with version 2.10. It can transport the
O_NONBLOCK flags in accept, and in nginx( in linux) after accept fd,
call fcntl(twice) set fd to O_NONBLOCK.
And so if use accept4, this will be to save twice systemcall,
therefore i suggest
nginx(in linux platform) should use accept4.
Yes, this make sense for Linux as it has no inheritance for
O_NONBLOCK from listening socket. Care to provide patch?
Just random implementation thoughs: probably emulating
NGX_HAVE_INHERITED_NONBLOCK via accept4() is a right way to go.
What happens when host has new glibc but old kernel? I assume
this test would succeed, but accept4() call will fail with ENOSYS.
Another question to consider is what to do with packages built on
host with accept4() but used on hosts without. Probably some
runtime fallback to usual accept() is needed.
What happens when host has new glibc but old kernel? I assume
this test would succeed, but accept4() call will fail with ENOSYS.
Another question to consider is what to do with packages built on
host with accept4() but used on hosts without. Probably some
runtime fallback to usual accept() is needed.
Yes. And the suggestion is to emulate NGX_HAVE_INHERITED_NONBLOCK
with accept4(): inherited nonblock means that socket returned by
accept() already has O_NONBLOCK set, so we don’t need to set it
(but may want to clear if we need blocking socket for some reason,
e.g. for socket AIO). With accept4() we basically get the same
situation.
I use centos 5.5 system and I can not test accept4() in this. I don’t
want to use a custom kernel and I’m not sure if I can compile a custom
kernel myself.
So, can anyone tell me how much performance gain occour with accept4()
over accept() on linux system?
Posted at Nginx Forum:
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.