self.current_index = self.current_future = None
self._running_future = None
+ # Use a weak reference to self to avoid cycles that may delay
+ # garbage collection.
self_ref = weakref.ref(self)
for future in futures:
future.add_done_callback(functools.partial(
the inputs.
"""
self._running_future = TracebackFuture()
+ # As long as there is an active _running_future, we must
+ # ensure that the WaitIterator is not GC'd (due to the
+ # use of weak references in __init__). Add a callback that
+ # references self so there is a hard reference that will be
+ # cleared automatically when this Future finishes.
+ self._running_future.add_done_callback(lambda f: self)
if self._finished:
self._return_result(self._finished.popleft())
self.assertEqual(g.current_index, 3, 'wrong index')
i += 1
+ @gen_test
+ def test_no_ref(self):
+ # In this usage, there is no direct hard reference to the
+ # WaitIterator itself, only the Future it returns. Since
+ # WaitIterator uses weak references internally to improve GC
+ # performance, this used to cause problems.
+ yield gen.with_timeout(datetime.timedelta(seconds=0.1),
+ gen.WaitIterator(gen.sleep(0)).next())
+
+
if __name__ == '__main__':
unittest.main()