Skip to content

Commit 7dfcc8e

Browse files
bpo-39651: Fix asyncio proactor _write_to_self() (GH-22197)
Fix a race condition in the call_soon_threadsafe() method of asyncio.ProactorEventLoop: do nothing if the self-pipe socket has been closed. (cherry picked from commit 1b0f0e3) Co-authored-by: Victor Stinner <[email protected]>
1 parent 34e3c75 commit 7dfcc8e

File tree

3 files changed

+23
-9
lines changed

3 files changed

+23
-9
lines changed

Lib/asyncio/proactor_events.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -791,8 +791,17 @@ def _loop_self_reading(self, f=None):
791791
f.add_done_callback(self._loop_self_reading)
792792

793793
def _write_to_self(self):
794+
# This may be called from a different thread, possibly after
795+
# _close_self_pipe() has been called or even while it is
796+
# running. Guard for self._csock being None or closed. When
797+
# a socket is closed, send() raises OSError (with errno set to
798+
# EBADF, but let's not rely on the exact error code).
799+
csock = self._csock
800+
if csock is None:
801+
return
802+
794803
try:
795-
self._csock.send(b'\0')
804+
csock.send(b'\0')
796805
except OSError:
797806
if self._debug:
798807
logger.debug("Fail to write a null byte into the "

Lib/asyncio/selector_events.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -133,14 +133,16 @@ def _write_to_self(self):
133133
# a socket is closed, send() raises OSError (with errno set to
134134
# EBADF, but let's not rely on the exact error code).
135135
csock = self._csock
136-
if csock is not None:
137-
try:
138-
csock.send(b'\0')
139-
except OSError:
140-
if self._debug:
141-
logger.debug("Fail to write a null byte into the "
142-
"self-pipe socket",
143-
exc_info=True)
136+
if csock is None:
137+
return
138+
139+
try:
140+
csock.send(b'\0')
141+
except OSError:
142+
if self._debug:
143+
logger.debug("Fail to write a null byte into the "
144+
"self-pipe socket",
145+
exc_info=True)
144146

145147
def _start_serving(self, protocol_factory, sock,
146148
sslcontext=None, server=None, backlog=100,
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix a race condition in the ``call_soon_threadsafe()`` method of
2+
``asyncio.ProactorEventLoop``: do nothing if the self-pipe socket has been
3+
closed.

0 commit comments

Comments
 (0)