Skip to content

Commit 06148b1

Browse files
authored
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.
1 parent 04676b6 commit 06148b1

File tree

3 files changed

+20
-2
lines changed

3 files changed

+20
-2
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Release the GIL while performing ``isatty`` system calls on arbitrary file
2+
descriptors. In particular, this affects :func:`os.isatty`,
3+
:func:`os.device_encoding` and :class:`io.TextIOWrapper`. By extension,
4+
:func:`io.open` in text mode is also affected.

Modules/posixmodule.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10066,9 +10066,11 @@ os_isatty_impl(PyObject *module, int fd)
1006610066
/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
1006710067
{
1006810068
int return_value;
10069+
Py_BEGIN_ALLOW_THREADS
1006910070
_Py_BEGIN_SUPPRESS_IPH
1007010071
return_value = isatty(fd);
1007110072
_Py_END_SUPPRESS_IPH
10073+
Py_END_ALLOW_THREADS
1007210074
return return_value;
1007310075
}
1007410076

Python/fileutils.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,11 @@ PyObject *
6767
_Py_device_encoding(int fd)
6868
{
6969
int valid;
70+
Py_BEGIN_ALLOW_THREADS
7071
_Py_BEGIN_SUPPRESS_IPH
7172
valid = isatty(fd);
7273
_Py_END_SUPPRESS_IPH
74+
Py_END_ALLOW_THREADS
7375
if (!valid)
7476
Py_RETURN_NONE;
7577

@@ -1776,12 +1778,22 @@ _Py_write_impl(int fd, const void *buf, size_t count, int gil_held)
17761778

17771779
_Py_BEGIN_SUPPRESS_IPH
17781780
#ifdef MS_WINDOWS
1779-
if (count > 32767 && isatty(fd)) {
1781+
if (count > 32767) {
17801782
/* Issue #11395: the Windows console returns an error (12: not
17811783
enough space error) on writing into stdout if stdout mode is
17821784
binary and the length is greater than 66,000 bytes (or less,
17831785
depending on heap usage). */
1784-
count = 32767;
1786+
if (gil_held) {
1787+
Py_BEGIN_ALLOW_THREADS
1788+
if (isatty(fd)) {
1789+
count = 32767;
1790+
}
1791+
Py_END_ALLOW_THREADS
1792+
} else {
1793+
if (isatty(fd)) {
1794+
count = 32767;
1795+
}
1796+
}
17851797
}
17861798
#endif
17871799
if (count > _PY_WRITE_MAX) {

0 commit comments

Comments
 (0)