mirror of
https://github.com/python/cpython.git
synced 2025-08-22 17:55:18 +00:00
bpo-31620: have asyncio/queues not leak memory when you've exceptions during waiting (#3813)
This commit is contained in:
parent
c060c7e3d1
commit
c62f0cb3b1
3 changed files with 25 additions and 0 deletions
|
@ -167,6 +167,12 @@ class Queue:
|
||||||
yield from getter
|
yield from getter
|
||||||
except:
|
except:
|
||||||
getter.cancel() # Just in case getter is not done yet.
|
getter.cancel() # Just in case getter is not done yet.
|
||||||
|
|
||||||
|
try:
|
||||||
|
self._getters.remove(getter)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
if not self.empty() and not getter.cancelled():
|
if not self.empty() and not getter.cancelled():
|
||||||
# We were woken up by put_nowait(), but can't take
|
# We were woken up by put_nowait(), but can't take
|
||||||
# the call. Wake up the next in line.
|
# the call. Wake up the next in line.
|
||||||
|
|
|
@ -295,6 +295,23 @@ class QueueGetTests(_QueueTestBase):
|
||||||
loop=self.loop),
|
loop=self.loop),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_cancelled_getters_not_being_held_in_self_getters(self):
|
||||||
|
def a_generator():
|
||||||
|
yield 0.1
|
||||||
|
yield 0.2
|
||||||
|
|
||||||
|
self.loop = self.new_test_loop(a_generator)
|
||||||
|
@asyncio.coroutine
|
||||||
|
def consumer(queue):
|
||||||
|
try:
|
||||||
|
item = yield from asyncio.wait_for(queue.get(), 0.1, loop=self.loop)
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
queue = asyncio.Queue(loop=self.loop, maxsize=5)
|
||||||
|
self.loop.run_until_complete(self.loop.create_task(consumer(queue)))
|
||||||
|
self.assertEqual(len(queue._getters), 0)
|
||||||
|
|
||||||
|
|
||||||
class QueuePutTests(_QueueTestBase):
|
class QueuePutTests(_QueueTestBase):
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
an empty asyncio.Queue now doesn't leak memory when queue.get pollers
|
||||||
|
timeout
|
Loading…
Add table
Add a link
Reference in a new issue