diff options
-rw-r--r-- | Lib/asyncio/selector_events.py | 12 | ||||
-rw-r--r-- | Lib/test/test_asyncio/test_selector_events.py | 15 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2018-04-11-20-29-19.bpo-33263.B56Hc1.rst | 1 |
3 files changed, 25 insertions, 3 deletions
diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index 354bf9d1c2..f9533a1d77 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -706,6 +706,12 @@ class _SelectorTransport(transports._FlowControlMixin, def get_write_buffer_size(self): return len(self._buffer) + def _add_reader(self, fd, callback, *args): + if self._closing: + return + + self._loop._add_reader(fd, callback, *args) + class _SelectorSocketTransport(_SelectorTransport): @@ -732,7 +738,7 @@ class _SelectorSocketTransport(_SelectorTransport): self._loop.call_soon(self._protocol.connection_made, self) # only start reading when connection_made() has been called - self._loop.call_soon(self._loop._add_reader, + self._loop.call_soon(self._add_reader, self._sock_fd, self._read_ready) if waiter is not None: # only wake up the waiter when connection_made() has been called @@ -754,7 +760,7 @@ class _SelectorSocketTransport(_SelectorTransport): if self._closing or not self._paused: return self._paused = False - self._loop._add_reader(self._sock_fd, self._read_ready) + self._add_reader(self._sock_fd, self._read_ready) if self._loop.get_debug(): logger.debug("%r resumes reading", self) @@ -930,7 +936,7 @@ class _SelectorDatagramTransport(_SelectorTransport): self._address = address self._loop.call_soon(self._protocol.connection_made, self) # only start reading when connection_made() has been called - self._loop.call_soon(self._loop._add_reader, + self._loop.call_soon(self._add_reader, self._sock_fd, self._read_ready) if waiter is not None: # only wake up the waiter when connection_made() has been called diff --git a/Lib/test/test_asyncio/test_selector_events.py b/Lib/test/test_asyncio/test_selector_events.py index 219ab0eb5b..684c29dec3 100644 --- a/Lib/test/test_asyncio/test_selector_events.py +++ b/Lib/test/test_asyncio/test_selector_events.py @@ -871,6 +871,21 @@ class SelectorTransportTests(test_utils.TestCase): self.assertIsNone(tr._protocol) self.assertIsNone(tr._loop) + def test__add_reader(self): + tr = self.create_transport() + tr._buffer.extend(b'1') + tr._add_reader(7, mock.sentinel) + self.assertTrue(self.loop.readers) + + tr._force_close(None) + + self.assertTrue(tr.is_closing()) + self.assertFalse(self.loop.readers) + + # can not add readers after closing + tr._add_reader(7, mock.sentinel) + self.assertFalse(self.loop.readers) + class SelectorSocketTransportTests(test_utils.TestCase): diff --git a/Misc/NEWS.d/next/Library/2018-04-11-20-29-19.bpo-33263.B56Hc1.rst b/Misc/NEWS.d/next/Library/2018-04-11-20-29-19.bpo-33263.B56Hc1.rst new file mode 100644 index 0000000000..77994f6a59 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-04-11-20-29-19.bpo-33263.B56Hc1.rst @@ -0,0 +1 @@ +Fix FD leak in `_SelectorSocketTransport` Patch by Vlad Starostin. |