diff options
author | Kyle Evans <kevans91@users.noreply.github.com> | 2020-10-11 20:18:53 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-11 20:18:53 (GMT) |
commit | 1800c600801709958af66bebfa683a4e7570810f (patch) | |
tree | 6ac63c960220b9e666db1e8d2f36dd3f39068c92 /Modules/posixmodule.c | |
parent | c230fde8475e4e5581e74a4235654d17ccf4cff8 (diff) | |
download | cpython-1800c600801709958af66bebfa683a4e7570810f.zip cpython-1800c600801709958af66bebfa683a4e7570810f.tar.gz cpython-1800c600801709958af66bebfa683a4e7570810f.tar.bz2 |
bpo-40423: Optimization: use close_range(2) if available (GH-22651)
close_range(2) should be preferred at all times if it's available, otherwise we'll use closefrom(2) if available with a fallback to fdwalk(3) or plain old loop over fd range in order of most efficient to least.
[note that this version does check for ENOSYS, but currently ignores all other errors]
Automerge-Triggered-By: @pablogsal
Diffstat (limited to 'Modules/posixmodule.c')
-rw-r--r-- | Modules/posixmodule.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 321eaec..2e0caaa 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -8741,12 +8741,15 @@ os_close_impl(PyObject *module, int fd) } /* Our selection logic for which function to use is as follows: - * 1. If closefrom(2) is available, we'll attempt to use that next if we're + * 1. If close_range(2) is available, always prefer that; it's better for + * contiguous ranges like this than fdwalk(3) which entails iterating over + * the entire fd space and simply doing nothing for those outside the range. + * 2. If closefrom(2) is available, we'll attempt to use that next if we're * closing up to sysconf(_SC_OPEN_MAX). - * 1a. Fallback to fdwalk(3) if we're not closing up to sysconf(_SC_OPEN_MAX), + * 2a. Fallback to fdwalk(3) if we're not closing up to sysconf(_SC_OPEN_MAX), * as that will be more performant if the range happens to have any chunk of * non-opened fd in the middle. - * 1b. If fdwalk(3) isn't available, just do a plain close(2) loop. + * 2b. If fdwalk(3) isn't available, just do a plain close(2) loop. */ #ifdef __FreeBSD__ #define USE_CLOSEFROM @@ -8779,6 +8782,14 @@ void _Py_closerange(int first, int last) { first = Py_MAX(first, 0); +#ifdef HAVE_CLOSE_RANGE + if (close_range(first, last, 0) == 0 || errno != ENOSYS) { + /* Any errors encountered while closing file descriptors are ignored; + * ENOSYS means no kernel support, though, + * so we'll fallback to the other methods. */ + } + else +#endif /* HAVE_CLOSE_RANGE */ #ifdef USE_CLOSEFROM if (last >= sysconf(_SC_OPEN_MAX)) { /* Any errors encountered while closing file descriptors are ignored */ |