Skip to content

Commit 1c5e860

Browse files
[3.10] GH-97001: Release GIL in termios extension (GH-99503) (#99680)
Without releasing the GIL calls to termios APIs might block the entire interpreter.. (cherry picked from commit 959ba45) Co-authored-by: Ronald Oussoren <[email protected]>
1 parent 99e852c commit 1c5e860

File tree

2 files changed

+47
-7
lines changed

2 files changed

+47
-7
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Release the GIL when calling termios APIs to avoid blocking threads.

Modules/termios.c

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,12 @@ termios_tcgetattr_impl(PyObject *module, int fd)
8282
{
8383
termiosmodulestate *state = PyModule_GetState(module);
8484
struct termios mode;
85-
if (tcgetattr(fd, &mode) == -1) {
85+
int r;
86+
87+
Py_BEGIN_ALLOW_THREADS
88+
r = tcgetattr(fd, &mode);
89+
Py_END_ALLOW_THREADS
90+
if (r == -1) {
8691
return PyErr_SetFromErrno(state->TermiosError);
8792
}
8893

@@ -169,7 +174,12 @@ termios_tcsetattr_impl(PyObject *module, int fd, int when, PyObject *term)
169174
/* Get the old mode, in case there are any hidden fields... */
170175
termiosmodulestate *state = PyModule_GetState(module);
171176
struct termios mode;
172-
if (tcgetattr(fd, &mode) == -1) {
177+
int r;
178+
179+
Py_BEGIN_ALLOW_THREADS
180+
r = tcgetattr(fd, &mode);
181+
Py_END_ALLOW_THREADS
182+
if (r == -1) {
173183
return PyErr_SetFromErrno(state->TermiosError);
174184
}
175185

@@ -211,7 +221,12 @@ termios_tcsetattr_impl(PyObject *module, int fd, int when, PyObject *term)
211221
return PyErr_SetFromErrno(state->TermiosError);
212222
if (cfsetospeed(&mode, (speed_t) ospeed) == -1)
213223
return PyErr_SetFromErrno(state->TermiosError);
214-
if (tcsetattr(fd, when, &mode) == -1)
224+
225+
Py_BEGIN_ALLOW_THREADS
226+
r = tcsetattr(fd, when, &mode);
227+
Py_END_ALLOW_THREADS
228+
229+
if (r == -1)
215230
return PyErr_SetFromErrno(state->TermiosError);
216231

217232
Py_RETURN_NONE;
@@ -235,7 +250,13 @@ termios_tcsendbreak_impl(PyObject *module, int fd, int duration)
235250
/*[clinic end generated code: output=5945f589b5d3ac66 input=dc2f32417691f8ed]*/
236251
{
237252
termiosmodulestate *state = PyModule_GetState(module);
238-
if (tcsendbreak(fd, duration) == -1) {
253+
int r;
254+
255+
Py_BEGIN_ALLOW_THREADS
256+
r = tcsendbreak(fd, duration);
257+
Py_END_ALLOW_THREADS
258+
259+
if (r == -1) {
239260
return PyErr_SetFromErrno(state->TermiosError);
240261
}
241262

@@ -256,7 +277,13 @@ termios_tcdrain_impl(PyObject *module, int fd)
256277
/*[clinic end generated code: output=5fd86944c6255955 input=c99241b140b32447]*/
257278
{
258279
termiosmodulestate *state = PyModule_GetState(module);
259-
if (tcdrain(fd) == -1) {
280+
int r;
281+
282+
Py_BEGIN_ALLOW_THREADS
283+
r = tcdrain(fd);
284+
Py_END_ALLOW_THREADS
285+
286+
if (r == -1) {
260287
return PyErr_SetFromErrno(state->TermiosError);
261288
}
262289

@@ -282,7 +309,13 @@ termios_tcflush_impl(PyObject *module, int fd, int queue)
282309
/*[clinic end generated code: output=2424f80312ec2f21 input=0f7d08122ddc07b5]*/
283310
{
284311
termiosmodulestate *state = PyModule_GetState(module);
285-
if (tcflush(fd, queue) == -1) {
312+
int r;
313+
314+
Py_BEGIN_ALLOW_THREADS
315+
r = tcflush(fd, queue);
316+
Py_END_ALLOW_THREADS
317+
318+
if (r == -1) {
286319
return PyErr_SetFromErrno(state->TermiosError);
287320
}
288321

@@ -308,7 +341,13 @@ termios_tcflow_impl(PyObject *module, int fd, int action)
308341
/*[clinic end generated code: output=afd10928e6ea66eb input=c6aff0640b6efd9c]*/
309342
{
310343
termiosmodulestate *state = PyModule_GetState(module);
311-
if (tcflow(fd, action) == -1) {
344+
int r;
345+
346+
Py_BEGIN_ALLOW_THREADS
347+
r = tcflow(fd, action);
348+
Py_END_ALLOW_THREADS
349+
350+
if (r == -1) {
312351
return PyErr_SetFromErrno(state->TermiosError);
313352
}
314353

0 commit comments

Comments
 (0)