Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible (and safe) to make an accepting socket non-blocking?

I'm looking for a way to interrupt an accept() call on a blocking socket. Using signals is not an option, as this is meant to be in a library and I don't want to clutter the user signals. Using select() is another option, buf for various reason it's not very appealing in my case.

What would work well, if possible, is to set the socket to non-blocking mode (using fcntl() and O_NONBLOCK) from another thread, while the socket is blocked on an accept() call. The expected behaviour is that the accept() call will return with EAGAIN or EWOULDBLOCK in errno.

Would it indeed work like that? Is it safe? Portable?

If you know about the applicability of this method to Windows (where you need to use WSAIoctl() and FONBIO), I'm also interested.

like image 584
Norswap Avatar asked Oct 12 '12 15:10

Norswap


1 Answers

No idea about Windows, but the behavior you want is guaranteed by POSIX:

If the listen queue is empty of connection requests and O_NONBLOCK is not set on the file descriptor for the socket, accept() shall block until a connection is present. If the listen() queue is empty of connection requests and O_NONBLOCK is set on the file descriptor for the socket, accept() shall fail and set errno to [EAGAIN] or [EWOULDBLOCK].

Source: http://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html

Also, select or poll can be used to check for incoming connections by polling for the listening socket in the reading set.

like image 94
R.. GitHub STOP HELPING ICE Avatar answered Sep 19 '22 18:09

R.. GitHub STOP HELPING ICE