mirror of
https://github.com/python/cpython.git
synced 2025-08-03 00:23:06 +00:00
[3.11] gh-88863: Clear ref cycles to resolve leak when asyncio.open_connection raises (GH-95739) (#99721)
Break reference cycles to resolve memory leak, by
removing local exception and future instances from the frame.
(cherry picked from commit 995f6170c7
)
Co-authored-by: Dong Uk, Kang <nailbrainz@gmail.com>
This commit is contained in:
parent
609273eb52
commit
24fad64cef
4 changed files with 36 additions and 12 deletions
|
@ -975,6 +975,8 @@ class BaseEventLoop(events.AbstractEventLoop):
|
|||
if sock is not None:
|
||||
sock.close()
|
||||
raise
|
||||
finally:
|
||||
exceptions = my_exceptions = None
|
||||
|
||||
async def create_connection(
|
||||
self, protocol_factory, host=None, port=None,
|
||||
|
@ -1072,17 +1074,20 @@ class BaseEventLoop(events.AbstractEventLoop):
|
|||
|
||||
if sock is None:
|
||||
exceptions = [exc for sub in exceptions for exc in sub]
|
||||
if len(exceptions) == 1:
|
||||
raise exceptions[0]
|
||||
else:
|
||||
# If they all have the same str(), raise one.
|
||||
model = str(exceptions[0])
|
||||
if all(str(exc) == model for exc in exceptions):
|
||||
try:
|
||||
if len(exceptions) == 1:
|
||||
raise exceptions[0]
|
||||
# Raise a combined exception so the user can see all
|
||||
# the various error messages.
|
||||
raise OSError('Multiple exceptions: {}'.format(
|
||||
', '.join(str(exc) for exc in exceptions)))
|
||||
else:
|
||||
# If they all have the same str(), raise one.
|
||||
model = str(exceptions[0])
|
||||
if all(str(exc) == model for exc in exceptions):
|
||||
raise exceptions[0]
|
||||
# Raise a combined exception so the user can see all
|
||||
# the various error messages.
|
||||
raise OSError('Multiple exceptions: {}'.format(
|
||||
', '.join(str(exc) for exc in exceptions)))
|
||||
finally:
|
||||
exceptions = None
|
||||
|
||||
else:
|
||||
if sock is None:
|
||||
|
@ -1875,6 +1880,8 @@ class BaseEventLoop(events.AbstractEventLoop):
|
|||
|
||||
event_list = self._selector.select(timeout)
|
||||
self._process_events(event_list)
|
||||
# Needed to break cycles when an exception occurs.
|
||||
event_list = None
|
||||
|
||||
# Handle 'later' callbacks that are ready.
|
||||
end_time = self.time() + self._clock_resolution
|
||||
|
|
|
@ -630,7 +630,11 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop):
|
|||
|
||||
fut = self.create_future()
|
||||
self._sock_connect(fut, sock, address)
|
||||
return await fut
|
||||
try:
|
||||
return await fut
|
||||
finally:
|
||||
# Needed to break cycles when an exception occurs.
|
||||
fut = None
|
||||
|
||||
def _sock_connect(self, fut, sock, address):
|
||||
fd = sock.fileno()
|
||||
|
@ -652,6 +656,8 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop):
|
|||
fut.set_exception(exc)
|
||||
else:
|
||||
fut.set_result(None)
|
||||
finally:
|
||||
fut = None
|
||||
|
||||
def _sock_write_done(self, fd, fut, handle=None):
|
||||
if handle is None or not handle.cancelled():
|
||||
|
@ -675,6 +681,8 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop):
|
|||
fut.set_exception(exc)
|
||||
else:
|
||||
fut.set_result(None)
|
||||
finally:
|
||||
fut = None
|
||||
|
||||
async def sock_accept(self, sock):
|
||||
"""Accept a connection.
|
||||
|
|
|
@ -439,7 +439,11 @@ class IocpProactor:
|
|||
self._poll(timeout)
|
||||
tmp = self._results
|
||||
self._results = []
|
||||
return tmp
|
||||
try:
|
||||
return tmp
|
||||
finally:
|
||||
# Needed to break cycles when an exception occurs.
|
||||
tmp = None
|
||||
|
||||
def _result(self, value):
|
||||
fut = self._loop.create_future()
|
||||
|
@ -841,6 +845,8 @@ class IocpProactor:
|
|||
else:
|
||||
f.set_result(value)
|
||||
self._results.append(f)
|
||||
finally:
|
||||
f = None
|
||||
|
||||
# Remove unregistered futures
|
||||
for ov in self._unregistered:
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
To avoid apparent memory leaks when :func:`asyncio.open_connection` raises,
|
||||
break reference cycles generated by local exception and future instances
|
||||
(which has exception instance as its member var). Patch by Dong Uk, Kang.
|
Loading…
Add table
Add a link
Reference in a new issue