# Accept4 should be used in nginx( linux platform)

**URL:** <https://www.ruby-forum.com/t/accept4-should-be-used-in-nginx-linux-platform/198773>\
**Category:** NGINX\
**Created:** [November 7, 2010, 3:32pm UTC](https://www.ruby-forum.com/t/accept4-should-be-used-in-nginx-linux-platform/198773 "2010-11-07T15:32:18Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Dobai-Pataky\_BSSSSl](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/77aa72/32.png) [@Dobai-Pataky\_BSSSSl](https://www.ruby-forum.com/u/Dobai-Pataky_BSSSSl)\
**Post date:** [November 7, 2010, 3:32pm UTC](https://www.ruby-forum.com/t/accept4-should-be-used-in-nginx-linux-platform/198773/1 "2010-11-07T15:32:18Z")

</div>

Hi igor.

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;  
}  
}

thanks!

–  
博观约取

豆瓣:www.douban.com/people/mustang/

blog: www.pagefault.info

twitter: [www.twitter.com/minibobo](http://www.twitter.com/minibobo)

---

<div class="post-metadata">

**Author:** ![monad](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/49beb7/32.png) [@monad](https://www.ruby-forum.com/u/monad)\
**Post date:** [November 7, 2010, 4:13pm UTC](https://www.ruby-forum.com/t/accept4-should-be-used-in-nginx-linux-platform/198773/2 "2010-11-07T16:13:49Z")

</div>

Hello!

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.

Maxim D.

---

<div class="post-metadata">

**Author:** ![monad](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/49beb7/32.png) [@monad](https://www.ruby-forum.com/u/monad)\
**Post date:** [November 7, 2010, 5:37pm UTC](https://www.ruby-forum.com/t/accept4-should-be-used-in-nginx-linux-platform/198773/3 "2010-11-07T17:37:24Z")

</div>

this patch suit for nginx-0.8.53, and i test in my arch linux. Thanks.

diff -Naur nginx-0.8.53/auto/os/features  
nginx-0.8.53\_accpet4/auto/os/features  
— nginx-0.8.53/auto/os/features 2010-07-05 21:49:16.000000000 +0800  
+++ nginx-0.8.53\_accpet4/auto/os/features 2010-11-08 00:20:28.126666705  
+0800  
@@ -352,3 +352,12 @@  
fi  
fi  
fi  
+  
+ngx\_feature=“accept4()”  
+ngx\_feature\_name=“NGX\_HAVE\_ACCEPT4”  
+ngx\_feature\_run=no  
+ngx\_feature\_incs=“#include \<sys/socket.h\>”  
+ngx\_feature\_path=  
+ngx\_feature\_libs=  
+ngx\_feature\_test=“accept4(0, NULL, NULL, SOCK\_NONBLOCK)”  
+. auto/feature  
diff -Naur nginx-0.8.53/src/event/ngx\_event\_accept.c  
nginx-0.8.53\_accpet4/src/event/ngx\_event\_accept.c  
— nginx-0.8.53/src/event/ngx\_event\_accept.c 2009-11-02  
03:29:49.000000000  
+0800  
+++ nginx-0.8.53\_accpet4/src/event/ngx\_event\_accept.c 2010-11-08  
00:27:21.630000043 +0800  
@@ -45,8 +45,12 @@

```
 do {
     socklen = NGX_SOCKADDRLEN;

```

- 

- 

+#if (NGX\_HAVE\_ACCEPT4)

- 

```
   s = accept4(lc->fd, (struct sockaddr *) sa, &socklen,

```

SOCK\_NONBLOCK);  
+#else  
s = accept(lc-\>fd, (struct sockaddr \*) sa, &socklen);  
+#endif

```
     if (s == -1) {
         err = ngx_socket_errno;

```

## @@ -115,9 +119,9 @@ ngx\_close\_accepted\_connection(c); return; }

- 

## +#ifndef NGX\_HAVE\_ACCEPT4 /\* set a blocking mode for aio and non-blocking mode for others \*/

```
     if (ngx_inherited_nonblocking) {
         if (ngx_event_flags & NGX_USE_AIO_EVENT) {
             if (ngx_blocking(s) == -1) {

```

## @@ -138,7 +142,8 @@ } } }

+#endif  
+  
\*log = ls-\>log;

```
     c->recv = ngx_recv;

```

On Sun, Nov 7, 2010 at 11:12 PM, Maxim D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> > And so if use accept4, this will be to save twice systemcall,
> 
> * * *
> 
> nginx mailing list  
> [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> [mailman.nginx.org archive](http://nginx.org/mailman/listinfo/nginx)

–  
博观约取

豆瓣:www.douban.com/people/mustang/

blog: www.pagefault.info

twitter: [www.twitter.com/minibobo](http://www.twitter.com/minibobo)

---

<div class="post-metadata">

**Author:** ![monad](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/49beb7/32.png) [@monad](https://www.ruby-forum.com/u/monad)\
**Post date:** [November 7, 2010, 6:56pm UTC](https://www.ruby-forum.com/t/accept4-should-be-used-in-nginx-linux-platform/198773/4 "2010-11-07T18:56:55Z")

</div>

thank you!

On Mon, Nov 8, 2010 at 1:34 AM, Maxim D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > +0800  
> > +ngx\_feature\_libs=  
> > +ngx\_feature\_test=“accept4(0, NULL, NULL, SOCK\_NONBLOCK)”  
> > +. auto/feature
> 
> 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.

thank you,I will test this situation.

> > ```
> > socklen = NGX_SOCKADDRLEN;
> > err = ngx_socket_errno;
> > 
> > ```
> > 
> > ## @@ -115,9 +119,9 @@ ngx\_close\_accepted\_connection(c); return; }
> > 
> > -
> 
> Stray -/+ probably indicate some unrelated whitespace changes  
> (though patch seems to be corrupted by MUA anyway).

this is my mistake.

> > ```
> > }
> > 
> > ```
> > 
> > - 
> > 
> > +#endif
> 
> This part is wrong: with socket AIO sockets should be set to  
> blocking mode. The same code path as with  
> ngx\_inherited\_nonblocking should be followed.

in linux platform , NGX\_HAVE\_INHERITED\_NONBLOCK is 0, and in  
ngx\_os\_init:

#if (NGX\_HAVE\_INHERITED\_NONBLOCK)  
ngx\_inherited\_nonblocking = 1;  
#else  
ngx\_inherited\_nonblocking = 0;  
#endif

–  
博观约取

豆瓣:www.douban.com/people/mustang/

blog: www.pagefault.info

twitter: [www.twitter.com/minibobo](http://www.twitter.com/minibobo)

---

<div class="post-metadata">

**Author:** ![monad](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/49beb7/32.png) [@monad](https://www.ruby-forum.com/u/monad)\
**Post date:** [November 7, 2010, 6:36pm UTC](https://www.ruby-forum.com/t/accept4-should-be-used-in-nginx-linux-platform/198773/5 "2010-11-07T18:36:09Z")

</div>

Hello!

On Mon, Nov 08, 2010 at 12:33:04AM +0800, BoBo wrote:

> fi  
> +  
> +ngx\_feature=“accept4()”  
> +ngx\_feature\_name=“NGX\_HAVE\_ACCEPT4”  
> +ngx\_feature\_run=no  
> +ngx\_feature\_incs=“#include \<sys/socket.h\>”  
> +ngx\_feature\_path=  
> +ngx\_feature\_libs=  
> +ngx\_feature\_test=“accept4(0, NULL, NULL, SOCK\_NONBLOCK)”  
> +. auto/feature

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.

> - 
> 
> ## @@ -115,9 +119,9 @@ ngx\_close\_accepted\_connection(c); return; }
> 
> -

Stray -/+ probably indicate some unrelated whitespace changes  
(though patch seems to be corrupted by MUA anyway).

> - 
> 
> +#endif

This part is wrong: with socket AIO sockets should be set to  
blocking mode. The same code path as with  
ngx\_inherited\_nonblocking should be followed.

Maxim D.

---

<div class="post-metadata">

**Author:** ![monad](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/49beb7/32.png) [@monad](https://www.ruby-forum.com/u/monad)\
**Post date:** [November 7, 2010, 7:07pm UTC](https://www.ruby-forum.com/t/accept4-should-be-used-in-nginx-linux-platform/198773/6 "2010-11-07T19:07:39Z")

</div>

Hello!

On Mon, Nov 08, 2010 at 01:55:31AM +0800, Simon L. wrote:

[…]

> > > ```
> > > }
> > > 
> > > ```
> 
> #if (NGX\_HAVE\_INHERITED\_NONBLOCK)  
> ngx\_inherited\_nonblocking = 1;  
> #else  
> ngx\_inherited\_nonblocking = 0;  
> #endif

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.

Maxim D.

---

<div class="post-metadata">

**Author:** ![monad](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/49beb7/32.png) [@monad](https://www.ruby-forum.com/u/monad)\
**Post date:** [January 2, 2011, 11:16am UTC](https://www.ruby-forum.com/t/accept4-should-be-used-in-nginx-linux-platform/198773/7 "2011-01-02T11:16:12Z")

</div>

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:

> **[Re: accept4 should be used in nginx( linux platform)](https://forum.nginx.org/read.php?2,148446,162830#msg-162830)**
>
> Hi igor. 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...
