[pypy-svn] r45928 - in pypy/branch/pypy-more-rtti-inprogress: config module/thread

arigo at codespeak.net arigo at codespeak.net
Thu Aug 23 14:25:37 CEST 2007


Author: arigo
Date: Thu Aug 23 14:25:34 2007
New Revision: 45928

Modified:
   pypy/branch/pypy-more-rtti-inprogress/config/translationoption.py
   pypy/branch/pypy-more-rtti-inprogress/module/thread/os_lock.py
   pypy/branch/pypy-more-rtti-inprogress/module/thread/os_thread.py
Log:
Try to clarify the memory allocation situation around
thread.start_new_thread().


Modified: pypy/branch/pypy-more-rtti-inprogress/config/translationoption.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/config/translationoption.py	(original)
+++ pypy/branch/pypy-more-rtti-inprogress/config/translationoption.py	Thu Aug 23 14:25:34 2007
@@ -43,7 +43,9 @@
                  ["boehm", "ref", "framework", "none", "stacklessgc",
                   "exact_boehm"],
                   "ref", requires={
-                     "stacklessgc": [("translation.stackless", True)]},
+                     "stacklessgc": [("translation.stackless", True),
+                                     ("translation.thread", False)],
+                     "framework": [("translation.thread", False)]},
                   cmdline="--gc"),
     BoolOption("thread", "enable use of threading primitives",
                default=False, cmdline="--thread"),

Modified: pypy/branch/pypy-more-rtti-inprogress/module/thread/os_lock.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/module/thread/os_lock.py	(original)
+++ pypy/branch/pypy-more-rtti-inprogress/module/thread/os_lock.py	Thu Aug 23 14:25:34 2007
@@ -42,10 +42,12 @@
         # XXX Usage of threadlocals.GIL in this function is considered hackish.
         #     Ideally, all GIL knowledge should be in gil.py.
         mylock = self.lock
-        GIL = space.threadlocals.GIL
-        GIL.release()
+        GIL = space.threadlocals.getGIL()
+        if GIL is not None:
+            GIL.release()
         result = mylock.acquire(bool(waitflag))
-        GIL.acquire(True)
+        if GIL is not None:
+            GIL.acquire(True)
         return space.newbool(result)
 
     def descr_lock_release(self, space):

Modified: pypy/branch/pypy-more-rtti-inprogress/module/thread/os_thread.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/module/thread/os_thread.py	(original)
+++ pypy/branch/pypy-more-rtti-inprogress/module/thread/os_thread.py	Thu Aug 23 14:25:34 2007
@@ -6,8 +6,15 @@
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.gateway import NoneNotWrapped
 from pypy.interpreter.gateway import ObjSpace, W_Root, Arguments
+from pypy.rlib.objectmodel import free_non_gc_object
 
-class Bootstrapper:
+# This code has subtle memory management issues in order to start
+# a new thread.  It should work correctly with Boehm and refcounting,
+# but the framework GC will not see the references stored in the
+# raw-malloced Bootstrapper instances => crash.
+
+
+class Bootstrapper(object):
     _alloc_flavor_ = 'raw'
     
     def bootstrap(self):
@@ -16,20 +23,17 @@
         try:
             self.run()
         finally:
-            # release ownership of these objects before we release the GIL
+            # release ownership of these objects before we release the GIL.
+            # (for the refcounting gc it is necessary to reset the fields to
+            # None before we use free_non_gc_object(), because the latter
+            # doesn't know that it needs to decref the fields)
             self.args       = None
             self.w_callable = None
-            # at this point the thread should only have a reference to
-            # an empty 'self'.  We hold the last reference to 'self'; indeed,
-            # the parent thread already forgot about it because the above
-            # enter_thread() must have blocked until long after the call to
-            # start_new_thread() below returned.
-            # (be careful of resetting *all* local variables to None here!)
-
+            # we can free the empty 'self' structure now
+            free_non_gc_object(self)
             # clean up space.threadlocals to remove the ExecutionContext
-            # entry corresponding to the current thread
+            # entry corresponding to the current thread and release the GIL
             space.threadlocals.leave_thread(space)
-            # free self here?
 
     def run(self):
         space      = self.space
@@ -76,11 +80,7 @@
     boot.space      = space
     boot.w_callable = w_callable
     boot.args       = args
-
     ident = thread.start_new_thread(Bootstrapper.bootstrap, (boot,))
-
-    # wait until the thread has really started and acquired a reference to
-    # 'boot'.
     return space.wrap(ident)
 
 



More information about the Pypy-commit mailing list