[Python-checkins] cpython (3.4): asyncio: Fix the second half of issue #21447: race in _write_to_self().

guido.van.rossum python-checkins at python.org
Tue May 6 23:47:24 CEST 2014


http://hg.python.org/cpython/rev/afe8c4bd3230
changeset:   90575:afe8c4bd3230
branch:      3.4
parent:      90571:b4b10afd2fe6
user:        Guido van Rossum <guido at python.org>
date:        Tue May 06 14:42:40 2014 -0700
summary:
  asyncio: Fix the second half of issue #21447: race in _write_to_self().

files:
  Lib/asyncio/selector_events.py                |  15 +++++++--
  Lib/test/test_asyncio/test_selector_events.py |   5 ++-
  2 files changed, 14 insertions(+), 6 deletions(-)


diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py
--- a/Lib/asyncio/selector_events.py
+++ b/Lib/asyncio/selector_events.py
@@ -87,10 +87,17 @@
             pass
 
     def _write_to_self(self):
-        try:
-            self._csock.send(b'x')
-        except (BlockingIOError, InterruptedError):
-            pass
+        # This may be called from a different thread, possibly after
+        # _close_self_pipe() has been called or even while it is
+        # running.  Guard for self._csock being None or closed.  When
+        # a socket is closed, send() raises OSError (with errno set to
+        # EBADF, but let's not rely on the exact error code).
+        csock = self._csock
+        if csock is not None:
+            try:
+                csock.send(b'x')
+            except OSError:
+                pass
 
     def _start_serving(self, protocol_factory, sock,
                        sslcontext=None, server=None):
diff --git a/Lib/test/test_asyncio/test_selector_events.py b/Lib/test/test_asyncio/test_selector_events.py
--- a/Lib/test/test_asyncio/test_selector_events.py
+++ b/Lib/test/test_asyncio/test_selector_events.py
@@ -121,8 +121,9 @@
         self.assertIsNone(self.loop._write_to_self())
 
     def test_write_to_self_exception(self):
-        self.loop._csock.send.side_effect = OSError()
-        self.assertRaises(OSError, self.loop._write_to_self)
+        # _write_to_self() swallows OSError
+        self.loop._csock.send.side_effect = RuntimeError()
+        self.assertRaises(RuntimeError, self.loop._write_to_self)
 
     def test_sock_recv(self):
         sock = mock.Mock()

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list