[pypy-svn] r46640 - in pypy/dist/pypy/module: __builtin__ thread/test
arigo at codespeak.net
arigo at codespeak.net
Sat Sep 15 16:46:19 CEST 2007
Author: arigo
Date: Sat Sep 15 16:46:18 2007
New Revision: 46640
Modified:
pypy/dist/pypy/module/__builtin__/importing.py
pypy/dist/pypy/module/thread/test/test_import_lock.py
Log:
Make the import lock really more fine-grained (the previous attempt
didn't achieve that). Add a test, which is really an implementation
test as CPython fails it.
Modified: pypy/dist/pypy/module/__builtin__/importing.py
==============================================================================
--- pypy/dist/pypy/module/__builtin__/importing.py (original)
+++ pypy/dist/pypy/module/__builtin__/importing.py Sat Sep 15 16:46:18 2007
@@ -196,16 +196,6 @@
importhook.unwrap_spec = [ObjSpace,str,W_Root,W_Root,W_Root]
def absolute_import(space, modulename, baselevel, w_fromlist, tentative):
- lock = getimportlock(space)
- acquired = lock.try_acquire_lock()
- try:
- return _absolute_import(space, modulename, baselevel,
- w_fromlist, tentative)
- finally:
- if acquired:
- lock.release_lock()
-
-def _absolute_import(space, modulename, baselevel, w_fromlist, tentative):
w = space.wrap
w_mod = None
@@ -258,34 +248,42 @@
w_mod = space.sys.getmodule(modulename)
if w_mod is not None:
return w_mod
- # Examin importhooks (PEP302) before doing the import
- if w_path is not None:
- w_loader = find_module(space, w_modulename, w_path)
- else:
- w_loader = find_module(space, w_modulename, space.w_None)
- if not space.is_w(w_loader, space.w_None):
- w_mod = space.call_method(w_loader, "load_module", w_modulename)
- #w_mod_ = check_sys_modules(space, w_modulename)
- if w_mod is not None and w_parent is not None:
- space.setattr(w_parent, w(partname), w_mod)
- return w_mod
-
-
- if w_path is not None:
- for path in space.unpackiterable(w_path):
- dir = os.path.join(space.str_w(path), partname)
- if os.path.isdir(dir):
- fn = os.path.join(dir, '__init__')
+ lock = getimportlock(space)
+ acquired = lock.try_acquire_lock()
+ try:
+ # Examin importhooks (PEP302) before doing the import
+ if w_path is not None:
+ w_loader = find_module(space, w_modulename, w_path)
+ else:
+ w_loader = find_module(space, w_modulename, space.w_None)
+ if not space.is_w(w_loader, space.w_None):
+ w_mod = space.call_method(w_loader, "load_module", w_modulename)
+ #w_mod_ = check_sys_modules(space, w_modulename)
+ if w_mod is not None and w_parent is not None:
+ space.setattr(w_parent, w(partname), w_mod)
+
+ return w_mod
+
+
+ if w_path is not None:
+ for path in space.unpackiterable(w_path):
+ dir = os.path.join(space.str_w(path), partname)
+ if os.path.isdir(dir):
+ fn = os.path.join(dir, '__init__')
+ w_mod = try_import_mod(space, w_modulename, fn,
+ w_parent, w(partname),
+ pkgdir=dir)
+ if w_mod is not None:
+ return w_mod
+ fn = os.path.join(space.str_w(path), partname)
w_mod = try_import_mod(space, w_modulename, fn, w_parent,
- w(partname), pkgdir=dir)
+ w(partname))
if w_mod is not None:
return w_mod
- fn = os.path.join(space.str_w(path), partname)
- w_mod = try_import_mod(space, w_modulename, fn, w_parent,
- w(partname))
- if w_mod is not None:
- return w_mod
+ finally:
+ if acquired:
+ lock.release_lock()
if tentative:
return None
@@ -302,6 +300,8 @@
# still being executed in another thread.
class ImportRLock:
+ _ann_seen = False
+
def __init__(self, space):
self.space = space
self.lock = None
@@ -312,12 +312,14 @@
# run-time.
self.lock = None
assert self.lockowner is None
+ self._ann_seen = True
return False
def try_acquire_lock(self):
# this function runs with the GIL acquired so there is no race
# condition in the creation of the lock
if self.lock is None:
+ assert not self._ann_seen
self.lock = self.space.allocate_lock()
me = self.space.getexecutioncontext() # used as thread ident
if self.lockowner is me:
Modified: pypy/dist/pypy/module/thread/test/test_import_lock.py
==============================================================================
--- pypy/dist/pypy/module/thread/test/test_import_lock.py (original)
+++ pypy/dist/pypy/module/thread/test/test_import_lock.py Sat Sep 15 16:46:18 2007
@@ -1,8 +1,14 @@
+from pypy.tool.udir import udir
from pypy.module.thread.test.support import GenericTestThread
class AppTestThread(GenericTestThread):
+ def setup_class(cls):
+ GenericTestThread.setup_class.im_func(cls)
+ tmpdir = str(udir.ensure('test_import_lock', dir=1))
+ cls.w_tmpdir = cls.space.wrap(tmpdir)
+
def test_import_lock(self):
import thread
done = []
@@ -17,3 +23,24 @@
def test_with_many_dependencies(self):
import thread
import re # -> causes nested imports
+
+ def test_no_lock_for_reimporting(self):
+ # CPython deadlocks in this situation; in our case the property
+ # of not requiring the import lock for already-imported modules
+ # is useful for translation, to avoid needing a prebuilt import
+ # lock object.
+ import os, sys
+ f = open(os.path.join(self.tmpdir, 'foobaz1.py'), 'w')
+ print >> f, """if 1:
+ import thread
+ lock = thread.allocate_lock()
+ lock.acquire()
+ def f():
+ import sys
+ lock.release()
+ thread.start_new_thread(f, ())
+ lock.acquire()
+ """
+ f.close()
+ sys.path.insert(0, self.tmpdir)
+ import foobaz1
More information about the Pypy-commit
mailing list