mirror of
https://github.com/python/cpython
synced 2024-09-20 03:31:40 +00:00
bpo-33263: Fix FD leak in _SelectorSocketTransport (GH-6450)
* bpo-33263 Fix FD leak in _SelectorSocketTransport. (GH-6450) Under particular circumstances _SelectorSocketTransport can try to add a reader even the transport is already being closed. This can lead to FD leak and invalid stated of the following connections. Fixed the SelectorSocketTransport to add the reader only if the trasport is still active.
This commit is contained in:
parent
4054b172ab
commit
a84d0b361a
|
@ -706,6 +706,12 @@ def _call_connection_lost(self, exc):
|
|||
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 @@ def __init__(self, loop, sock, protocol, waiter=None,
|
|||
|
||||
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 @@ def resume_reading(self):
|
|||
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 @@ def __init__(self, loop, sock, protocol, address=None,
|
|||
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
|
||||
|
|
|
@ -871,6 +871,21 @@ def test_connection_lost(self):
|
|||
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):
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Fix FD leak in `_SelectorSocketTransport` Patch by Vlad Starostin.
|
Loading…
Reference in a new issue