Author: Ronan Lamy <[email protected]>
Branch: cpyext-threads-gil
Changeset: r90183:8d233583a424
Date: 2017-02-18 16:47 +0000
http://bitbucket.org/pypy/pypy/changeset/8d233583a424/

Log:    Move all GIL handling for PyGILState_* inside the functions

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
@@ -266,9 +266,6 @@
         sig = pycode.cpython_code_signature(callable.func_code)
         assert sig.argnames[0] == 'space'
         self.argnames = sig.argnames[1:]
-        if gil == 'pygilstate_ensure':
-            assert self.argnames[-1] == 'previous_state'
-            del self.argnames[-1]
         assert len(self.argnames) == len(self.argtypes)
 
         self.gil = gil
@@ -851,15 +848,11 @@
         pypy_debug_catch_fatal_exception()
         assert False
 
-def _restore_gil_state(pygilstate_release, gilstate, gil_release, _gil_auto, 
tid):
+def _restore_gil_state(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
+    unlock = gil_release or _gil_auto
     if unlock:
         rgil.release()
     else:
@@ -875,11 +868,9 @@
                                          # have the GIL, and acquire/release it
     gil_acquire = (gil == "acquire" or gil == "around")
     gil_release = (gil == "release" or gil == "around")
-    pygilstate_ensure = (gil == "pygilstate_ensure")
-    pygilstate_release = (gil == "pygilstate_release")
-    assert (gil is None or gil_acquire or gil_release
-            or pygilstate_ensure or pygilstate_release)
-    expected_nb_args = len(argtypesw) + pygilstate_ensure
+    gil_ignore = (gil == "ignore")
+    assert (gil is None or gil_acquire or gil_release or gil_ignore)
+    expected_nb_args = len(argtypesw)
 
     if isinstance(restype, lltype.Ptr) and error_value == 0:
         error_value = lltype.nullptr(restype.TO)
@@ -893,7 +884,6 @@
     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
 
@@ -905,21 +895,12 @@
                 deadlock_error(pname)
             rgil.acquire()
             assert cpyext_glob_tid_ptr[0] == 0
-        elif pygilstate_ensure:
-            if cpyext_glob_tid_ptr[0] == tid:
-                cpyext_glob_tid_ptr[0] = 0
-                args += (pystate.PyGILState_LOCKED,)
-            else:
-                rgil.acquire()
-                args += (pystate.PyGILState_UNLOCKED,)
+        elif gil_ignore:
+            pass
         else:
             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
@@ -943,8 +924,6 @@
                 else:
                     arg_conv = arg
                 boxed_args += (arg_conv, )
-            if pygilstate_ensure:
-                boxed_args += (args[-1], )
             try:
                 result = callable(space, *boxed_args)
                 if not we_are_translated() and DEBUG_WRAPPER:
@@ -989,14 +968,16 @@
 
         except Exception as e:
             unexpected_exception(pname, e, tb)
-            _restore_gil_state(pygilstate_release, gilstate, gil_release, 
_gil_auto, tid)
+            if not gil_ignore:
+                _restore_gil_state(gil_release, _gil_auto, tid)
             state.check_and_raise_exception(always=True)
             return fatal_value
 
         assert lltype.typeOf(retval) == restype
         rffi.stackcounter.stacks_counter -= 1
 
-        _restore_gil_state(pygilstate_release, gilstate, gil_release, 
_gil_auto, tid)
+        if not gil_ignore:
+            _restore_gil_state(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
@@ -1,10 +1,11 @@
 from pypy.module.cpyext.api import (
-    cpython_api, generic_cpy_call, CANNOT_FAIL, CConfig, cpython_struct)
+    cpython_api, generic_cpy_call, CANNOT_FAIL, CConfig, cpython_struct, 
cpyext_glob_tid_ptr)
 from pypy.module.cpyext.pyobject import PyObject, Py_DecRef, make_ref, from_ref
 from pypy.interpreter.error import OperationError
 from rpython.rtyper.lltypesystem import rffi, lltype
 from rpython.rlib import rthread
 from rpython.rlib.objectmodel import we_are_translated
+from rpython.rlib import rgil
 
 PyInterpreterStateStruct = lltype.ForwardReference()
 PyInterpreterState = lltype.Ptr(PyInterpreterStateStruct)
@@ -232,11 +233,15 @@
     space.threadlocals.get_ec = get_possibly_deleted_ec
 
 
-@cpython_api([], PyGILState_STATE, error=CANNOT_FAIL, gil="pygilstate_ensure")
-def PyGILState_Ensure(space, previous_state):
-    # The argument 'previous_state' is not part of the API; it is inserted
-    # by make_wrapper() and contains PyGILState_LOCKED/UNLOCKED based on
-    # the previous GIL state.
+@cpython_api([], PyGILState_STATE, error=CANNOT_FAIL, gil="ignore")
+def PyGILState_Ensure(space):
+    tid = rthread.get_or_make_ident()
+    if cpyext_glob_tid_ptr[0] == tid:
+        cpyext_glob_tid_ptr[0] = 0
+        previous_state = PyGILState_LOCKED
+    else:
+        rgil.acquire()
+        previous_state = PyGILState_UNLOCKED
     must_leave = space.threadlocals.try_enter_thread(space)
     ec = space.getexecutioncontext()
     if not must_leave:
@@ -254,10 +259,14 @@
         if not we_are_translated():
             _workaround_cpython_untranslated(space)
     #
+    cpyext_glob_tid_ptr[0] = tid
     return rffi.cast(PyGILState_STATE, previous_state)
 
-@cpython_api([PyGILState_STATE], lltype.Void, gil="pygilstate_release")
+@cpython_api([PyGILState_STATE], lltype.Void, gil="ignore")
 def PyGILState_Release(space, oldstate):
+    tid = rthread.get_or_make_ident()
+    assert cpyext_glob_tid_ptr[0] == tid
+    cpyext_glob_tid_ptr[0] = 0
     oldstate = rffi.cast(lltype.Signed, oldstate)
     ec = space.getexecutioncontext()
     if ec.cpyext_gilstate_counter_noleave > 0:
@@ -266,6 +275,10 @@
         assert ec.cpyext_gilstate_counter_noleave == 0
         assert oldstate == PyGILState_UNLOCKED
         space.threadlocals.leave_thread(space)
+    if oldstate == PyGILState_UNLOCKED:
+        rgil.release()
+    else:
+        cpyext_glob_tid_ptr[0] = tid
 
 @cpython_api([], PyInterpreterState, error=CANNOT_FAIL)
 def PyInterpreterState_Head(space):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to