[pypy-svn] r16534 - in pypy/dist/pypy/module/thread: . test
arigo at codespeak.net
arigo at codespeak.net
Thu Aug 25 19:30:18 CEST 2005
Author: arigo
Date: Thu Aug 25 19:30:16 2005
New Revision: 16534
Modified:
pypy/dist/pypy/module/thread/gil.py
pypy/dist/pypy/module/thread/os_thread.py
pypy/dist/pypy/module/thread/test/support.py
pypy/dist/pypy/module/thread/test/test_thread.py
Log:
(pedronis, arigo)
For the translated PyPy, we need to be extra super careful about making
thread.start_new_thread() thread-safe (argh).
Modified: pypy/dist/pypy/module/thread/gil.py
==============================================================================
--- pypy/dist/pypy/module/thread/gil.py (original)
+++ pypy/dist/pypy/module/thread/gil.py Thu Aug 25 19:30:16 2005
@@ -31,6 +31,7 @@
def yield_thread(self):
"""Notification that the current thread is between two bytecodes:
release the GIL for a little while."""
- self.GIL.release()
+ GIL = self.GIL
+ GIL.release()
# Other threads can run here
- self.GIL.acquire(True)
+ GIL.acquire(True)
Modified: pypy/dist/pypy/module/thread/os_thread.py
==============================================================================
--- pypy/dist/pypy/module/thread/os_thread.py (original)
+++ pypy/dist/pypy/module/thread/os_thread.py Thu Aug 25 19:30:16 2005
@@ -11,26 +11,45 @@
import pypy.module.thread.rpython.exttable
+THREAD_STARTUP_LOCK = thread.allocate_lock()
+
+
class Bootstrapper:
def bootstrap(self):
- space = self.space
- w_callable = self.w_callable
- args = self.args
+ space = self.space
+ THREAD_STARTUP_LOCK.release()
space.threadlocals.enter_thread(space)
try:
- try:
- space.call_args(w_callable, args)
- except OperationError, e:
- if not e.match(space, space.w_SystemExit):
- ident = thread.get_ident()
- where = 'thread %d started by' % ident
- e.write_unraisable(space, where, w_callable)
- e.clear(space)
+ self.run()
finally:
+ # release ownership of these objects before we release the GIL
+ self.args = None
+ self.w_callable = None
+ self.space = 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!)
+
# clean up space.threadlocals to remove the ExecutionContext
# entry corresponding to the current thread
space.threadlocals.leave_thread(space)
+ def run(self):
+ space = self.space
+ w_callable = self.w_callable
+ args = self.args
+ try:
+ space.call_args(w_callable, args)
+ except OperationError, e:
+ if not e.match(space, space.w_SystemExit):
+ ident = thread.get_ident()
+ where = 'thread %d started by' % ident
+ e.write_unraisable(space, where, w_callable)
+ e.clear(space)
+
def start_new_thread(space, w_callable, w_args, w_kwargs=NoneNotWrapped):
"""Start a new thread and return its identifier. The thread will call the
@@ -47,7 +66,16 @@
boot.space = space
boot.w_callable = w_callable
boot.args = args
+
+ THREAD_STARTUP_LOCK.acquire(True)
+
ident = thread.start_new_thread(Bootstrapper.bootstrap, (boot,))
+
+ # wait until the thread has really started and acquired a reference to
+ # 'boot'.
+ THREAD_STARTUP_LOCK.acquire(True)
+ THREAD_STARTUP_LOCK.release()
+
return space.wrap(ident)
Modified: pypy/dist/pypy/module/thread/test/support.py
==============================================================================
--- pypy/dist/pypy/module/thread/test/support.py (original)
+++ pypy/dist/pypy/module/thread/test/support.py Thu Aug 25 19:30:16 2005
@@ -12,7 +12,7 @@
def waitfor(expr, timeout=10.0):
limit = time.time() + timeout
while time.time() <= limit:
- time.sleep(0.005)
+ time.sleep(0.002)
if expr():
return
print '*** timed out ***'
@@ -23,6 +23,6 @@
def busywait(t):
limit = time.time() + t
while time.time() <= limit:
- time.sleep(0.005)
+ time.sleep(0.002)
return busywait
""")
Modified: pypy/dist/pypy/module/thread/test/test_thread.py
==============================================================================
--- pypy/dist/pypy/module/thread/test/test_thread.py (original)
+++ pypy/dist/pypy/module/thread/test/test_thread.py Thu Aug 25 19:30:16 2005
@@ -123,6 +123,6 @@
thread.start_new_thread(f, (i, done))
done_marker.append(done)
for done in done_marker:
- self.waitfor(lambda: done, timeout=20.0)
+ self.waitfor(lambda: done, timeout=30.0)
assert done # see stderr for failures in threads
assert sorted(lst) == range(120)
More information about the Pypy-commit
mailing list