Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r54931:2a9e8bea6f75
Date: 2012-05-07 13:16 +0200
http://bitbucket.org/pypy/pypy/changeset/2a9e8bea6f75/

Log:    Fix for the previous test.

diff --git a/pypy/module/thread/__init__.py b/pypy/module/thread/__init__.py
--- a/pypy/module/thread/__init__.py
+++ b/pypy/module/thread/__init__.py
@@ -18,7 +18,7 @@
         'allocate_lock':          'os_lock.allocate_lock',
         'allocate':               'os_lock.allocate_lock',  # obsolete synonym
         'LockType':               'os_lock.Lock',
-        '_local':                 'os_local.Local',
+        #'_local':                'os_local.Local',   # only if 'rweakref'
         'error':                  'space.fromcache(error.Cache).w_error',
     }
 
@@ -35,3 +35,7 @@
         from pypy.module.thread.os_thread import reinit_threads
         add_fork_hook('child', reinit_threads)
 
+    def setup_after_space_initialization(self):
+        """NOT_RPYTHON"""
+        if self.space.config.translation.rweakref:
+            self.extra_interpdef('_local', 'os_local.Local')
diff --git a/pypy/module/thread/gil.py b/pypy/module/thread/gil.py
--- a/pypy/module/thread/gil.py
+++ b/pypy/module/thread/gil.py
@@ -30,7 +30,6 @@
             if not thread.gil_allocate():
                 raise wrap_thread_error(space, "can't allocate GIL")
             self.gil_ready = True
-            self.enter_thread(space)   # setup the main thread
             result = True
         else:
             result = False      # already set up
diff --git a/pypy/module/thread/os_local.py b/pypy/module/thread/os_local.py
--- a/pypy/module/thread/os_local.py
+++ b/pypy/module/thread/os_local.py
@@ -1,5 +1,6 @@
-from pypy.module.thread import ll_thread as thread
-from pypy.interpreter.baseobjspace import Wrappable
+from pypy.rlib.rweakref import RWeakKeyDictionary
+from pypy.interpreter.baseobjspace import Wrappable, W_Root
+from pypy.interpreter.executioncontext import ExecutionContext
 from pypy.interpreter.typedef import (TypeDef, interp2app, GetSetProperty,
     descr_get_dict)
 
@@ -9,16 +10,23 @@
 
     def __init__(self, space, initargs):
         self.initargs = initargs
-        ident = thread.get_ident()
-        self.dicts = {ident: space.newdict(instance=True)}
+        self.dicts = RWeakKeyDictionary(ExecutionContext, W_Root)
+        # The app-level __init__() will be called by the general
+        # instance-creation logic.  It causes getdict() to be
+        # immediately called.  If we don't prepare and set a w_dict
+        # for the current thread, then this would in cause getdict()
+        # to call __init__() a second time.
+        ec = space.getexecutioncontext()
+        w_dict = space.newdict(instance=True)
+        self.dicts.set(ec, w_dict)
 
     def getdict(self, space):
-        ident = thread.get_ident()
-        try:
-            w_dict = self.dicts[ident]
-        except KeyError:
+        ec = space.getexecutioncontext()
+        w_dict = self.dicts.get(ec)
+        if w_dict is None:
             # create a new dict for this thread
-            w_dict = self.dicts[ident] = space.newdict(instance=True)
+            w_dict = space.newdict(instance=True)
+            self.dicts.set(ec, w_dict)
             # call __init__
             try:
                 w_self = space.wrap(self)
@@ -27,10 +35,9 @@
                 space.call_obj_args(w_init, w_self, self.initargs)
             except:
                 # failed, forget w_dict and propagate the exception
-                del self.dicts[ident]
+                self.dicts.set(ec, None)
                 raise
             # ready
-            space.threadlocals.atthreadexit(space, finish_thread, self)
         return w_dict
 
     def descr_local__new__(space, w_subtype, __args__):
@@ -48,8 +55,3 @@
                         __init__ = interp2app(Local.descr_local__init__),
                         __dict__ = GetSetProperty(descr_get_dict, cls=Local),
                         )
-
-def finish_thread(w_obj):
-    assert isinstance(w_obj, Local)
-    ident = thread.get_ident()
-    del w_obj.dicts[ident]
diff --git a/pypy/module/thread/os_thread.py b/pypy/module/thread/os_thread.py
--- a/pypy/module/thread/os_thread.py
+++ b/pypy/module/thread/os_thread.py
@@ -90,7 +90,6 @@
         bootstrapper.nbthreads += 1
         bootstrapper.release()
         # run!
-        space.threadlocals.enter_thread(space)
         try:
             bootstrapper.run(space, w_callable, args)
         finally:
diff --git a/pypy/module/thread/test/test_local.py 
b/pypy/module/thread/test/test_local.py
--- a/pypy/module/thread/test/test_local.py
+++ b/pypy/module/thread/test/test_local.py
@@ -48,7 +48,7 @@
 
     def test_local_init(self):
         import thread
-        tags = [1, 2, 3, 4, 5, 54321]
+        tags = ['???', 1, 2, 3, 4, 5, 54321]
         seen = []
 
         raises(TypeError, thread._local, a=1)
@@ -61,6 +61,7 @@
 
         x = X(42)
         assert x.tag == 54321
+        assert x.tag == 54321
         def f():
             seen.append(x.tag)
         for i in range(5):
@@ -69,7 +70,7 @@
         seen1 = seen[:]
         seen1.sort()
         assert seen1 == [1, 2, 3, 4, 5]
-        assert tags == []
+        assert tags == ['???']
 
     def test_local_setdict(self):
         import thread
diff --git a/pypy/module/thread/threadlocals.py 
b/pypy/module/thread/threadlocals.py
--- a/pypy/module/thread/threadlocals.py
+++ b/pypy/module/thread/threadlocals.py
@@ -1,5 +1,6 @@
 from pypy.module.thread import ll_thread as thread
 
+
 class OSThreadLocals:
     """Thread-local storage for OS-level threads.
     For memory management, this version depends on explicit notification when
@@ -51,21 +52,6 @@
     def getallvalues(self):
         return self._valuedict
 
-    def enter_thread(self, space):
-        "Notification that the current thread is just starting."
-        ec = space.getexecutioncontext()
-        ec.thread_exit_funcs = []
-
     def leave_thread(self, space):
         "Notification that the current thread is about to stop."
-        try:
-            ec = space.getexecutioncontext()
-            while ec.thread_exit_funcs:
-                exit_func, w_obj = ec.thread_exit_funcs.pop()
-                exit_func(w_obj)
-        finally:
-            self.setvalue(None)
-
-    def atthreadexit(self, space, exit_func, w_obj):
-        ec = space.getexecutioncontext()
-        ec.thread_exit_funcs.append((exit_func, w_obj))
+        self.setvalue(None)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to