This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author vstinner
Recipients gvanrossum, pitrou, vstinner
Date 2013-11-27.11:57:06
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1385553428.3.0.518090447657.issue19813@psf.upfronthosting.co.za>
In-reply-to
Content
Since Linux 2.6.28, socket() syscall accepts a new SOCK_NONBLOCK flag in the socket type. It avoids 1 or 2 extra syscalls to set the socket in non-blocking mode. This flag comes also slowly in other operating systems: NetBSD, FreeBSD, etc.

FreeBSD:
http://lists.freebsd.org/pipermail/freebsd-hackers/2013-March/042242.html

Discussion in the POSIX standard:
http://austingroupbugs.net/view.php?id=411

Avoiding the syscalls has been proposed on python-dev a few months ago:
https://mail.python.org/pipermail/python-dev/2013-January/123661.html

I tried to include SOCK_NONBLOCK in my PEP 446, but I have been asked to treat it separatly because it's completly different than O_CLOEXEC (even it looks similar).
http://hg.python.org/peps/file/fa873d5aed27/pep-0446.txt#l64

I also proposed to add 2 functions in the PEP:

* ``os.get_blocking(fd:int) -> bool``
* ``os.set_blocking(fd:int, blocking: bool)``

I propose to add a new timeout parameter to socket.socket() constructor which would set the timeout internal attribute and set O_NONBLOCK flag using the new SOCK_NONBLOCK flag, ioctl() or fcntl() (depending on the OS and on what is available).

I don't know if something special should be done on Windows for non-blocking sockets? socket.socket.setblocking() already exists and I suppose that it works on Windows :-) See also the discussion in my old PEP for non-blocking operations in files on Windows:
http://hg.python.org/peps/file/fa873d5aed27/pep-0446.txt#l177

I don't know if the new parameter can just be added at the end of the parameter list, or it should be a keyword-only parameter to avoid breakpoint backward compatibility?

socket.socketpair() and socket.socket.dup() and socket.fromfd(), socket.create_connection() (and more generally any function creating a new socket) may also be modified.

--

By the way, internal_setblocking() currently uses 2 fcntl() syscalls on Linux, whereas it could be implemented with a single ioctl() syscall using FIONBIO.

Set O_NONBLOCK flag:

int flag = 1;
ioctl(fd, FIONBIO, &flag);

Clear O_NONBLOCK flag:

int flag = 0;
ioctl(fd, FIONBIO, &flag);

Tell me if you prefer a different issue for this optimization.
History
Date User Action Args
2013-11-27 11:57:08vstinnersetrecipients: + vstinner, gvanrossum, pitrou
2013-11-27 11:57:08vstinnersetmessageid: <1385553428.3.0.518090447657.issue19813@psf.upfronthosting.co.za>
2013-11-27 11:57:08vstinnerlinkissue19813 messages
2013-11-27 11:57:06vstinnercreate