Author: Ronan Lamy <[email protected]>
Branch: testing-cleanup
Changeset: r85226:0fdc10ae15b1
Date: 2016-06-18 21:24 +0100
http://bitbucket.org/pypy/pypy/changeset/0fdc10ae15b1/
Log: Make sure that the GIL is reset properly when an unexpected
exception is raised
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -800,6 +800,21 @@
pypy_debug_catch_fatal_exception()
assert False
+def _restore_gil_state(pygilstate_release, gilstate, gil_release, _gil_auto,
tid):
+ from rpython.rlib import rgil
+ # see "Handling of the GIL" above
+ assert cpyext_glob_tid_ptr[0] == 0
+ if pygilstate_release:
+ from pypy.module.cpyext import pystate
+ unlock = (gilstate == pystate.PyGILState_UNLOCKED)
+ else:
+ unlock = gil_release or _gil_auto
+ if unlock:
+ rgil.release()
+ else:
+ cpyext_glob_tid_ptr[0] = tid
+
+
def make_wrapper_second_level(space, argtypesw, restype,
result_kind, error_value, gil):
from rpython.rlib import rgil
@@ -827,6 +842,7 @@
def wrapper_second_level(callable, pname, *args):
from pypy.module.cpyext.pyobject import make_ref, from_ref, is_pyobj
from pypy.module.cpyext.pyobject import as_pyobj
+ from pypy.module.cpyext import pystate
# we hope that malloc removal removes the newtuple() that is
# inserted exactly here by the varargs specializer
@@ -839,7 +855,6 @@
rgil.acquire()
assert cpyext_glob_tid_ptr[0] == 0
elif pygilstate_ensure:
- from pypy.module.cpyext import pystate
if cpyext_glob_tid_ptr[0] == tid:
cpyext_glob_tid_ptr[0] = 0
args += (pystate.PyGILState_LOCKED,)
@@ -850,6 +865,10 @@
if cpyext_glob_tid_ptr[0] != tid:
no_gil_error(pname)
cpyext_glob_tid_ptr[0] = 0
+ if pygilstate_release:
+ gilstate = rffi.cast(lltype.Signed, args[-1])
+ else:
+ gilstate = pystate.PyGILState_IGNORE
rffi.stackcounter.stacks_counter += 1
llop.gc_stack_bottom(lltype.Void) # marker for trackgcroot.py
@@ -919,24 +938,13 @@
except Exception as e:
unexpected_exception(pname, e, tb)
+ _restore_gil_state(pygilstate_release, gilstate, gil_release,
_gil_auto, tid)
return fatal_value
assert lltype.typeOf(retval) == restype
rffi.stackcounter.stacks_counter -= 1
- # see "Handling of the GIL" above
- assert cpyext_glob_tid_ptr[0] == 0
- if pygilstate_release:
- from pypy.module.cpyext import pystate
- arg = rffi.cast(lltype.Signed, args[-1])
- unlock = (arg == pystate.PyGILState_UNLOCKED)
- else:
- unlock = gil_release or _gil_auto
- if unlock:
- rgil.release()
- else:
- cpyext_glob_tid_ptr[0] = tid
-
+ _restore_gil_state(pygilstate_release, gilstate, gil_release,
_gil_auto, tid)
return retval
wrapper_second_level._dont_inline_ = True
diff --git a/pypy/module/cpyext/pystate.py b/pypy/module/cpyext/pystate.py
--- a/pypy/module/cpyext/pystate.py
+++ b/pypy/module/cpyext/pystate.py
@@ -207,6 +207,7 @@
PyGILState_STATE = rffi.INT
PyGILState_LOCKED = 0
PyGILState_UNLOCKED = 1
+PyGILState_IGNORE = 2
ExecutionContext.cpyext_gilstate_counter_noleave = 0
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit