classification
Title: _Py_set_inheritable(): do nothing if the FD_CLOEXEC close is already set/cleared
Type: performance Stage: commit review
Components: Versions: Python 3.6
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: vstinner Nosy List: martin.panter, python-dev, serhiy.storchaka, steve.dower, vstinner
Priority: normal Keywords: patch

Created on 2016-04-15 13:21 by vstinner, last changed 2016-04-17 14:52 by vstinner. This issue is now closed.

Files
File name Uploaded Description Edit
set_inheritable_fcntl.patch vstinner, 2016-04-15 13:20 review
stress.py vstinner, 2016-04-17 14:50
Messages (7)
msg263493 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2016-04-15 13:20
Attached patch is avoids a syscall in os.set_inheritable() if the FD_CLOEXEC flag is already set/cleared.

The change only impacts platforms using fcntl() in _Py_set_inheritable(). Windows has a different implementation, and Linux uses ioctl() for example.

The same "optimization" is used in socket.socket.setblocking(): see the issue #19827.
msg263494 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2016-04-15 13:21
See also the issue #26769: "Python 2.7: make private file descriptors non inheritable".
msg263603 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2016-04-17 10:33
Changes look pretty innocent. LGTM.
msg263604 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2016-04-17 10:39
Another question: should we handle EINTR in ioctl() and fcntl()? But this is a different issue.
msg263609 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2016-04-17 14:50
> Another question: should we handle EINTR in ioctl() and fcntl()? But this is a different issue.

See attached test stress.py. I tried it with ioctl() and fcntl() implementations of os.set_inheritable() and I got more than 10,000 signals: no syscalls failed with EINTR.

IMHO EINTR is only used when the syscall waits, for example wait for I/O. I don't think that setting FD_CLOEXEC requires any I/O.

Example:

$ ./python stress.py 
got 16871 signals
msg263610 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2016-04-17 14:52
New changeset d268f108ba80 by Victor Stinner in branch 'default':
Avoid fcntl() if possible in set_inheritable()
https://hg.python.org/cpython/rev/d268f108ba80
msg263611 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2016-04-17 14:52
> Changes look pretty innocent. LGTM.

Thanks. I pushed my change.
History
Date User Action Args
2016-04-17 14:52:33vstinnersetstatus: open -> closed
resolution: fixed
messages: + msg263611
2016-04-17 14:52:14python-devsetnosy: + python-dev
messages: + msg263610
2016-04-17 14:50:19vstinnersetfiles: + stress.py

messages: + msg263609
2016-04-17 10:39:06serhiy.storchakasetmessages: + msg263604
2016-04-17 10:33:44serhiy.storchakasetnosy: + steve.dower
messages: + msg263603

assignee: vstinner
stage: commit review
2016-04-15 13:21:33vstinnersetnosy: + martin.panter, serhiy.storchaka
messages: + msg263494
2016-04-15 13:21:00vstinnercreate