diff options
-rw-r--r-- | Lib/asyncio/proactor_events.py | 6 | ||||
-rw-r--r-- | Lib/test/test_asyncio/test_proactor_events.py | 9 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2018-05-16-05-24-43.bpo-26819.taxbVT.rst | 2 |
3 files changed, 15 insertions, 2 deletions
diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py index a81645d..967a696 100644 --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -156,6 +156,7 @@ class _ProactorReadPipeTransport(_ProactorBasePipeTransport, extra=None, server=None): super().__init__(loop, sock, protocol, waiter, extra, server) self._paused = False + self._reschedule_on_resume = False self._loop.call_soon(self._loop_reading) def pause_reading(self): @@ -173,12 +174,15 @@ class _ProactorReadPipeTransport(_ProactorBasePipeTransport, self._paused = False if self._closing: return - self._loop.call_soon(self._loop_reading, self._read_fut) + if self._reschedule_on_resume: + self._loop.call_soon(self._loop_reading, self._read_fut) + self._reschedule_on_resume = False if self._loop.get_debug(): logger.debug("%r resumes reading", self) def _loop_reading(self, fut=None): if self._paused: + self._reschedule_on_resume = True return data = None diff --git a/Lib/test/test_asyncio/test_proactor_events.py b/Lib/test/test_asyncio/test_proactor_events.py index d76da66..edf0461 100644 --- a/Lib/test/test_asyncio/test_proactor_events.py +++ b/Lib/test/test_asyncio/test_proactor_events.py @@ -330,7 +330,7 @@ class ProactorSocketTransportTests(test_utils.TestCase): def test_pause_resume_reading(self): tr = self.socket_transport() futures = [] - for msg in [b'data1', b'data2', b'data3', b'data4', b'']: + for msg in [b'data1', b'data2', b'data3', b'data4', b'data5', b'']: f = asyncio.Future(loop=self.loop) f.set_result(msg) futures.append(f) @@ -352,6 +352,13 @@ class ProactorSocketTransportTests(test_utils.TestCase): self.protocol.data_received.assert_called_with(b'data3') self.loop._run_once() self.protocol.data_received.assert_called_with(b'data4') + + tr.pause_reading() + tr.resume_reading() + self.loop.call_exception_handler = mock.Mock() + self.loop._run_once() + self.loop.call_exception_handler.assert_not_called() + self.protocol.data_received.assert_called_with(b'data5') tr.close() diff --git a/Misc/NEWS.d/next/Library/2018-05-16-05-24-43.bpo-26819.taxbVT.rst b/Misc/NEWS.d/next/Library/2018-05-16-05-24-43.bpo-26819.taxbVT.rst new file mode 100644 index 0000000..d407a58 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-16-05-24-43.bpo-26819.taxbVT.rst @@ -0,0 +1,2 @@ +Fix race condition with `ReadTransport.resume_reading` in Windows proactor +event loop. |