memory: Fix a memory leak in stack_context.
Fixed based on
https://github.com/tornadoweb/tornado/commit/bff07405549a6eb173a4cfc9bbc3fc7c6da5cdd7
Change-Id: Ib14bcc837b9951f5b9fca4e92ece3e721b6d9d0c
diff --git a/tornado/gen.py b/tornado/gen.py
index 506697d..03d08ba 100644
--- a/tornado/gen.py
+++ b/tornado/gen.py
@@ -354,6 +354,7 @@
"finished without waiting for callbacks %r" %
self.pending_callbacks)
self.deactivate_stack_context()
+ self.deactivate_stack_context = None
return
except Exception:
self.finished = True
diff --git a/tornado/stack_context.py b/tornado/stack_context.py
index 1843762..63f9ac4 100644
--- a/tornado/stack_context.py
+++ b/tornado/stack_context.py
@@ -129,6 +129,7 @@
return self.context.__exit__(type, value, traceback)
finally:
_state.contexts = self.old_contexts
+ self.old_contexts = None
class ExceptionStackContext(object):
diff --git a/tornado/test/gen_test.py b/tornado/test/gen_test.py
index d9ac9da..f2b2eb8 100644
--- a/tornado/test/gen_test.py
+++ b/tornado/test/gen_test.py
@@ -269,6 +269,28 @@
initial_stack_depth = len(stack_context._state.contexts)
self.run_gen(outer)
+ def test_stack_context_leak_exception(self):
+ # same as previous, but with a function that exits with an exception
+ from tornado import stack_context
+
+ @gen.engine
+ def inner(callback):
+ yield gen.Task(self.io_loop.add_callback)
+ 1 / 0
+
+ @gen.engine
+ def outer():
+ for i in xrange(10):
+ try:
+ yield gen.Task(inner)
+ except ZeroDivisionError:
+ pass
+ stack_increase = len(stack_context._state.contexts) - initial_stack_depth
+ self.assertTrue(stack_increase <= 2)
+ self.stop()
+ initial_stack_depth = len(stack_context._state.contexts)
+ self.run_gen(outer)
+
class GenSequenceHandler(RequestHandler):
@asynchronous