diff options
author | Dong Uk, Kang <nailbrainz@gmail.com> | 2022-11-22 15:06:20 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-22 15:06:20 (GMT) |
commit | 995f6170c78570eca818f7e7dbd8a7661c171a81 (patch) | |
tree | fdfaf448f9fb3bf4a601c1cb51c001deab62ea01 /Lib/asyncio/base_events.py | |
parent | 9a91182d4a87e4511dad20ad101e3eab0e1c5088 (diff) | |
download | cpython-995f6170c78570eca818f7e7dbd8a7661c171a81.zip cpython-995f6170c78570eca818f7e7dbd8a7661c171a81.tar.gz cpython-995f6170c78570eca818f7e7dbd8a7661c171a81.tar.bz2 |
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
Diffstat (limited to 'Lib/asyncio/base_events.py')
-rw-r--r-- | Lib/asyncio/base_events.py | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index c8a2f9f..91d32e3 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -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 |