Commit 0da93240 authored by Mark Florisson's avatar Mark Florisson

Lock around error info decrefs in nogil try/finally

parent 86be47c1
......@@ -5488,10 +5488,16 @@ class TryFinallyStatNode(StatNode):
over_label = code.new_label()
code.put_goto(over_label)
code.put_label(finally_error_label)
code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
if self.is_try_finally_in_nogil:
code.put_ensure_gil(declare_gilstate=False)
for var in Naming.exc_vars:
code.putln("Py_XDECREF(%s);" % var)
if self.is_try_finally_in_nogil:
code.put_release_ensured_gil()
code.putln("}")
code.put_goto(old_error_label)
code.put_label(over_label)
......@@ -5543,7 +5549,8 @@ class TryFinallyStatNode(StatNode):
def put_error_uncatcher(self, code, i, error_label):
code.globalstate.use_utility_code(restore_exception_utility_code)
code.putln("case %s: {" % i)
code.putln(
"case %s: {" % i)
if self.is_try_finally_in_nogil:
code.put_ensure_gil(declare_gilstate=False)
......@@ -5555,10 +5562,12 @@ class TryFinallyStatNode(StatNode):
code.put_release_ensured_gil()
for var in Naming.exc_vars:
code.putln("%s = 0;" % var)
code.putln(
"%s = 0;" % var)
code.put_goto(error_label)
code.putln("}")
code.putln(
"}")
def annotate(self, code):
self.body.annotate(code)
......
......@@ -157,6 +157,6 @@ _ERRORS = u"""
59:17: Truth-testing Python object not allowed without gil
61:8: For-loop using object bounds or target not allowed without gil
63:8: Try-except statement not allowed without gil
67:8: Try-finally statement not allowed without gil
67:8: Cannot use try/finally in nogil sections unless it contains a 'with gil' statement.
84:8: For-loop using object bounds or target not allowed without gil
"""
......@@ -387,3 +387,48 @@ def test_nogil_try_finally_propagate_exception():
puts("Execute finally clause")
except Exception, e:
print e
def test_nogil_try_finally_return_in_with_gil(x):
"""
>>> test_nogil_try_finally_return_in_with_gil(10)
(None, None, None)
10
"""
# For some reason, this exception is set, clear it first
# (<type 'exceptions.ImportError'>,
# ImportError('cannot import name _TextTestResult',),
# <traceback object at 0x10073c4d0>)
sys.exc_clear()
with nogil:
try:
with gil:
raise Exception("Swallow me!")
finally:
with gil:
print sys.exc_info()
return x
print "I am not executed", sys.exc_info()
cdef void nogil_try_finally_return() nogil:
try:
with gil:
raise Exception("I am swallowed in nogil code... right?")
finally:
with gil:
print sys.exc_info()
return
with gil:
print "I am not executed", sys.exc_info()
def test_nogil_try_finally_return():
"""
>>> test_nogil_try_finally_return()
(None, None, None)
"""
sys.exc_clear()
with nogil:
nogil_try_finally_return()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment