[pypy-svn] pypy default: Importing changes to pystate.

ademan commits-noreply at bitbucket.org
Thu Jan 27 10:37:47 CET 2011


Author: Daniel Roberts <Ademan555 at gmail.com>
Branch: 
Changeset: r41383:a828a97357a5
Date: 2011-01-26 23:35 -0800
http://bitbucket.org/pypy/pypy/changeset/a828a97357a5/

Log:	Importing changes to pystate.

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
@@ -2,9 +2,8 @@
         cpython_struct
 from pypy.rpython.lltypesystem import rffi, lltype
 
-
-PyThreadState = lltype.Ptr(cpython_struct("PyThreadState", ()))
 PyInterpreterState = lltype.Ptr(cpython_struct("PyInterpreterState", ()))
+PyThreadState = lltype.Ptr(cpython_struct("PyThreadState", [('interp', PyInterpreterState)]))
 
 @cpython_api([], PyThreadState, error=CANNOT_FAIL)
 def PyEval_SaveThread(space):
@@ -35,4 +34,58 @@
 def PyEval_ThreadsInitialized(space):
     return 1
 
+# XXX: might be generally useful
+def encapsulator(T, flavor='raw'):
+    class MemoryCapsule(object):
+        def __init__(self, alloc=True):
+            if alloc:
+                self.memory = lltype.malloc(T, flavor=flavor)
+            else:
+                self.memory = lltype.nullptr(T)
+        def __del__(self):
+            if self.memory:
+                lltype.free(self.memory, flavor=flavor)
+    return MemoryCapsule
 
+ThreadStateCapsule = encapsulator(PyThreadState.TO)
+
+from pypy.interpreter.executioncontext import ExecutionContext
+ExecutionContext.cpyext_threadstate = ThreadStateCapsule(alloc=False)
+
+class InterpreterState(object):
+    def __init__(self, space):
+        self.interpreter_state = lltype.malloc(PyInterpreterState.TO, flavor='raw', immortal=True)
+
+    def new_thread_state(self):
+        capsule = ThreadStateCapsule()
+        ts = capsule.memory
+        ts.c_interp = self.interpreter_state
+        return capsule
+
+    def get_thread_state(self, space):
+        ec = space.getexecutioncontext()
+        return self._get_thread_state(ec).memory
+
+    def _get_thread_state(self, ec):
+        if ec.cpyext_threadstate.memory == lltype.nullptr(PyThreadState.TO):
+            ec.cpyext_threadstate = self.new_thread_state()
+
+        return ec.cpyext_threadstate
+
+ at cpython_api([], PyThreadState, error=CANNOT_FAIL)
+def PyThreadState_Get(space, ):
+    state = space.fromcache(InterpreterState)
+    return state.get_thread_state(space)
+
+ at cpython_api([], PyInterpreterState, error=CANNOT_FAIL)
+def PyInterpreterState_Head(space, ):
+    """Return the interpreter state object at the head of the list of all such objects.
+    """
+    return space.fromcache(InterpreterState).interpreter_state
+
+ at cpython_api([PyInterpreterState], PyInterpreterState, error=CANNOT_FAIL)
+def PyInterpreterState_Next(space, interp):
+    """Return the next interpreter state object after interp from the list of all
+    such objects.
+    """
+    return lltype.nullptr(PyInterpreterState.TO)

diff --git a/pypy/module/cpyext/test/test_pystate.py b/pypy/module/cpyext/test/test_pystate.py
--- a/pypy/module/cpyext/test/test_pystate.py
+++ b/pypy/module/cpyext/test/test_pystate.py
@@ -1,4 +1,7 @@
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
+from pypy.module.cpyext.test.test_api import BaseApiTest
+from pypy.rpython.lltypesystem.lltype import nullptr
+from pypy.module.cpyext.pystate import PyInterpreterState, PyThreadState
 
 class AppTestThreads(AppTestCpythonExtensionBase):
     def test_allow_threads(self):
@@ -17,3 +20,26 @@
         # Should compile at least
         module.test()
 
+class TestInterpreterState(BaseApiTest):
+    def test_interpreter_head(self, space, api):
+        state = api.PyInterpreterState_Head()
+        assert state != nullptr(PyInterpreterState.TO)
+
+    def test_interpreter_next(self, space, api):
+        state = api.PyInterpreterState_Head()
+        assert nullptr(PyInterpreterState.TO) == api.PyInterpreterState_Next(state)
+
+def clear_threadstate(space):
+    # XXX: this should collect the ThreadState memory
+    del space.getexecutioncontext().cpyext_threadstate
+
+class TestThreadState(BaseApiTest):
+    def test_thread_state_get(self, space, api):
+        ts = api.PyThreadState_Get()
+        assert ts != nullptr(PyThreadState.TO)
+        clear_threadstate(space)
+
+    def test_thread_state_interp(self, space, api):
+        ts = api.PyThreadState_Get()
+        assert ts.c_interp == api.PyInterpreterState_Head()
+        clear_threadstate(space)


More information about the Pypy-commit mailing list