gh-88863: Clear ref cycles to resolve leak when asyncio.open_connection raises (#95739)

Break reference cycles to resolve memory leak, by
removing local exception and future instances from the frame
This commit is contained in:
Dong Uk, Kang 2022-11-23 00:06:20 +09:00 committed by GitHub
parent 9a91182d4a
commit 995f6170c7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 14 deletions

View file

@ -986,6 +986,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,
@ -1084,19 +1086,22 @@ class BaseEventLoop(events.AbstractEventLoop):
if sock is None:
exceptions = [exc for sub in exceptions for exc in sub]
if all_errors:
raise ExceptionGroup("create_connection failed", exceptions)
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 all_errors:
raise ExceptionGroup("create_connection failed", exceptions)
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:
@ -1904,6 +1909,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