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