bpo-44219: Release the GIL during isatty syscalls (GH-28250)

Release the GIL while performing isatty() system calls on arbitrary
file descriptors. In particular, this affects os.isatty(),
os.device_encoding() and io.TextIOWrapper. By extension,
io.open() in text mode is also affected.
This commit is contained in:
Vincent Michel 2021-09-09 15:12:03 +02:00 committed by GitHub
parent 04676b6946
commit 06148b1870
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 20 additions and 2 deletions

View file

@ -0,0 +1,4 @@
Release the GIL while performing ``isatty`` system calls on arbitrary file
descriptors. In particular, this affects :func:`os.isatty`,
:func:`os.device_encoding` and :class:`io.TextIOWrapper`. By extension,
:func:`io.open` in text mode is also affected.

View file

@ -10066,9 +10066,11 @@ os_isatty_impl(PyObject *module, int fd)
/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/ /*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
{ {
int return_value; int return_value;
Py_BEGIN_ALLOW_THREADS
_Py_BEGIN_SUPPRESS_IPH _Py_BEGIN_SUPPRESS_IPH
return_value = isatty(fd); return_value = isatty(fd);
_Py_END_SUPPRESS_IPH _Py_END_SUPPRESS_IPH
Py_END_ALLOW_THREADS
return return_value; return return_value;
} }

View file

@ -67,9 +67,11 @@ PyObject *
_Py_device_encoding(int fd) _Py_device_encoding(int fd)
{ {
int valid; int valid;
Py_BEGIN_ALLOW_THREADS
_Py_BEGIN_SUPPRESS_IPH _Py_BEGIN_SUPPRESS_IPH
valid = isatty(fd); valid = isatty(fd);
_Py_END_SUPPRESS_IPH _Py_END_SUPPRESS_IPH
Py_END_ALLOW_THREADS
if (!valid) if (!valid)
Py_RETURN_NONE; Py_RETURN_NONE;
@ -1776,12 +1778,22 @@ _Py_write_impl(int fd, const void *buf, size_t count, int gil_held)
_Py_BEGIN_SUPPRESS_IPH _Py_BEGIN_SUPPRESS_IPH
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
if (count > 32767 && isatty(fd)) { if (count > 32767) {
/* Issue #11395: the Windows console returns an error (12: not /* Issue #11395: the Windows console returns an error (12: not
enough space error) on writing into stdout if stdout mode is enough space error) on writing into stdout if stdout mode is
binary and the length is greater than 66,000 bytes (or less, binary and the length is greater than 66,000 bytes (or less,
depending on heap usage). */ depending on heap usage). */
count = 32767; if (gil_held) {
Py_BEGIN_ALLOW_THREADS
if (isatty(fd)) {
count = 32767;
}
Py_END_ALLOW_THREADS
} else {
if (isatty(fd)) {
count = 32767;
}
}
} }
#endif #endif
if (count > _PY_WRITE_MAX) { if (count > _PY_WRITE_MAX) {