[pypy-commit] pypy stacklet: Ah, found the cause of the issue.

arigo noreply at buildbot.pypy.org
Thu Aug 18 11:35:34 CEST 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: stacklet
Changeset: r46596:53c3ad204b8c
Date: 2011-08-18 11:39 +0200
http://bitbucket.org/pypy/pypy/changeset/53c3ad204b8c/

Log:	Ah, found the cause of the issue.

diff --git a/pypy/module/_continuation/interp_continuation.py b/pypy/module/_continuation/interp_continuation.py
--- a/pypy/module/_continuation/interp_continuation.py
+++ b/pypy/module/_continuation/interp_continuation.py
@@ -1,4 +1,4 @@
-from pypy.rlib.rstacklet import StackletThread, get_null_handle
+from pypy.rlib.rstacklet import StackletThread
 from pypy.rlib import jit
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.executioncontext import ExecutionContext
@@ -12,7 +12,10 @@
 
     def __init__(self, space):
         self.space = space
-        self.h = get_null_handle(space.config)
+        # states:
+        #  - not init'ed: self.sthread == None
+        #  - normal:      self.sthread != None, not is_empty_handle(self.h)
+        #  - finished:    self.sthread != None, is_empty_handle(self.h)
 
     def build_sthread(self):
         space = self.space
@@ -21,7 +24,6 @@
         if not sthread:
             sthread = ec.stacklet_thread = SThread(space, ec)
         self.sthread = sthread
-        return sthread
 
     def check_sthread(self):
         ec = self.space.getexecutioncontext()
@@ -30,22 +32,23 @@
         return ec
 
     def descr_init(self, w_callable, __args__):
-        if self.h != get_null_handle(self.space.config):
+        if self.sthread is not None:
             raise geterror(self.space, "continuation already __init__ialized")
-        sthread = self.build_sthread()
         start_state.origin = self
         start_state.w_callable = w_callable
         start_state.args = __args__
+        self.build_sthread()
         try:
-            self.h = sthread.new(new_stacklet_callback)
-            if sthread.is_empty_handle(self.h):    # early return
+            self.h = self.sthread.new(new_stacklet_callback)
+            if self.sthread.is_empty_handle(self.h):    # early return
                 raise MemoryError
         except MemoryError:
+            self.sthread = None
             start_state.clear()
             raise getmemoryerror(self.space)
 
     def descr_switch(self, w_value=None):
-        if self.h == get_null_handle(self.space.config):
+        if self.sthread is None:
             raise geterror(self.space, "continuation not initialized yet")
         if self.sthread.is_empty_handle(self.h):
             raise geterror(self.space, "continuation already finished")
@@ -68,7 +71,7 @@
         return w_value
 
     def descr_is_pending(self):
-        valid = (self.h != get_null_handle(self.space.config)
+        valid = (self.sthread is not None
                  and not self.sthread.is_empty_handle(self.h))
         return self.space.newbool(valid)
 
diff --git a/pypy/rlib/rstacklet.py b/pypy/rlib/rstacklet.py
--- a/pypy/rlib/rstacklet.py
+++ b/pypy/rlib/rstacklet.py
@@ -22,14 +22,13 @@
         self._gcrootfinder.destroy(self, stacklet)
 
     def is_empty_handle(self, stacklet):
+        # note that "being an empty handle" and being equal to
+        # "get_null_handle()" may be the same, or not; don't rely on it
         return self._gcrootfinder.is_empty_handle(stacklet)
 
     def get_null_handle(self):
         return self._gcrootfinder.get_null_handle()
 
-def get_null_handle(config):
-    return _getgcrootfinder(config).get_null_handle()
-
 
 class StackletThreadDeleter(object):
     # quick hack: the __del__ is on another object, so that


More information about the pypy-commit mailing list