[pypy-svn] r16363 - in pypy/dist/pypy: interpreter lib module/thread module/thread/test objspace/std
arigo at codespeak.net
arigo at codespeak.net
Wed Aug 24 13:33:06 CEST 2005
Author: arigo
Date: Wed Aug 24 13:33:02 2005
New Revision: 16363
Added:
pypy/dist/pypy/module/thread/test/test_import_lock.py (contents, props changed)
Modified:
pypy/dist/pypy/interpreter/baseobjspace.py
pypy/dist/pypy/interpreter/module.py
pypy/dist/pypy/lib/imp.py
pypy/dist/pypy/module/thread/__init__.py
pypy/dist/pypy/objspace/std/objspace.py
Log:
Implemented the import lock when --usemodules=thread.
The import lock itself is completely done at app-level in imp.py, to provide
the required interface imp.*lock*() to user programs. It's done as an
__import__ hook. There is a minor hack to force imp.py to get imported when
the space is done being initialized.
--This line, and those below, will be ignored--
M pypy/interpreter/baseobjspace.py
M pypy/interpreter/module.py
AM pypy/module/thread/test/test_import_lock.py
M pypy/module/thread/__init__.py
M pypy/objspace/std/objspace.py
M pypy/lib/imp.py
Modified: pypy/dist/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/dist/pypy/interpreter/baseobjspace.py (original)
+++ pypy/dist/pypy/interpreter/baseobjspace.py Wed Aug 24 13:33:02 2005
@@ -219,6 +219,12 @@
#print "setitem: space instance %-20s into builtins" % name
self.setitem(self.builtin.w_dict, self.wrap(name), value)
+ def setup_builtin_modules(self):
+ "NOT_RPYTHON: only for initializing the space."
+ for modname, mixedname in self.get_builtinmodule_list():
+ mod = self.getbuiltinmodule(modname)
+ mod.setup_after_space_initialization()
+
def initialize(self):
"""NOT_RPYTHON: Abstract method that should put some minimal
content into the w_builtins."""
Modified: pypy/dist/pypy/interpreter/module.py
==============================================================================
--- pypy/dist/pypy/interpreter/module.py (original)
+++ pypy/dist/pypy/interpreter/module.py Wed Aug 24 13:33:02 2005
@@ -17,6 +17,10 @@
if w_name is not None:
space.setitem(w_dict, space.wrap('__name__'), w_name)
+ def setup_after_space_initialization(self):
+ """NOT_RPYTHON: to allow built-in modules to do some more setup
+ after the space is fully initialized."""
+
def getdict(self):
return self.w_dict
Modified: pypy/dist/pypy/lib/imp.py
==============================================================================
--- pypy/dist/pypy/lib/imp.py (original)
+++ pypy/dist/pypy/lib/imp.py Wed Aug 24 13:33:02 2005
@@ -7,8 +7,6 @@
# XXX to be reviewed
-import sys, os
-
PY_SOURCE = 1
PY_COMPILED = 2
C_EXTENSION = 3
@@ -24,10 +22,9 @@
def get_suffixes():
return [('.py', 'U', PY_SOURCE)]
-new_module = type(sys)
-
def find_module(name, path=None):
+ import sys, os
if path is None:
if name in sys.builtin_module_names:
return (None, name, ('', '', C_BUILTIN))
@@ -43,6 +40,8 @@
def load_module(name, file, filename, description):
+ import sys, os
+ new_module = type(sys)
suffix, mode, type = description
module = sys.modules.get(name)
@@ -75,10 +74,61 @@
raise ValueError, 'invalid description argument: %r' % (description,)
-# XXX needs to be implemented when we have threads
-def lock_held():
- return False
-def acquire_lock():
- pass
-def release_lock():
- pass
+try:
+ # PyPy-specific interface: hint from the thread module to ask us to
+ # provide an import lock
+ from thread import _please_provide_import_lock
+except ImportError:
+ def lock_held():
+ return False
+ def acquire_lock():
+ pass
+ def release_lock():
+ pass
+else:
+ del _please_provide_import_lock
+ import thread
+
+ class _ImportLock:
+ def __init__(self):
+ self.lock = thread.allocate_lock()
+ self.in_thread = None
+ self.recursions = 0
+
+ def held(self):
+ return self.in_thread is not None
+
+ def acquire(self):
+ myident = thread.get_ident()
+ if self.in_thread == myident:
+ self.recursions += 1
+ else:
+ self.lock.acquire()
+ self.in_thread = myident
+ self.recursions = 1
+
+ def release(self):
+ myident = thread.get_ident()
+ if self.in_thread != myident:
+ raise RuntimeError("not holding the import lock")
+ self.recursions -= 1
+ if self.recursions == 0:
+ self.in_thread = None
+ self.lock.release()
+
+ _importlock = _ImportLock()
+
+ lock_held = _importlock.held
+ acquire_lock = _importlock.acquire
+ release_lock = _importlock.release
+
+ import __builtin__
+ _original_import_hook = __builtin__.__import__
+ def __lockedimport__(modulename, globals=None, locals=None, fromlist=None):
+ acquire_lock()
+ try:
+ return _original_import_hook(modulename, globals, locals, fromlist)
+ finally:
+ release_lock()
+ __builtin__.__import__ = __lockedimport__
+ del __builtin__
Modified: pypy/dist/pypy/module/thread/__init__.py
==============================================================================
--- pypy/dist/pypy/module/thread/__init__.py (original)
+++ pypy/dist/pypy/module/thread/__init__.py Wed Aug 24 13:33:02 2005
@@ -16,6 +16,7 @@
'allocate': 'os_lock.allocate_lock', # obsolete synonym
'LockType': 'os_lock.getlocktype(space)',
'_local': 'os_local.getlocaltype(space)',
+ '_please_provide_import_lock': '(space.w_True)', # for imp.py
}
def __init__(self, space, *args):
@@ -26,3 +27,9 @@
space.threadlocals = gil.GILThreadLocals()
space.threadlocals.setvalue(prev)
space.threadlocals.enter_thread(space) # setup the main thread
+
+ def setup_after_space_initialization(self):
+ # the import lock is in imp.py. Import it after the space is fully
+ # initialized.
+ from pypy.module.__builtin__.importing import importhook
+ importhook(self.space, 'imp')
Added: pypy/dist/pypy/module/thread/test/test_import_lock.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/module/thread/test/test_import_lock.py Wed Aug 24 13:33:02 2005
@@ -0,0 +1,15 @@
+from pypy.module.thread.test.support import GenericTestThread
+
+
+class AppTestThread(GenericTestThread):
+
+ def test_import_lock(self):
+ import thread
+ done = []
+ def f():
+ from imghdr import testall
+ done.append(1)
+ for i in range(5):
+ thread.start_new_thread(f, ())
+ self.waitfor(lambda: len(done) == 5)
+ assert len(done) == 5
Modified: pypy/dist/pypy/objspace/std/objspace.py
==============================================================================
--- pypy/dist/pypy/objspace/std/objspace.py (original)
+++ pypy/dist/pypy/objspace/std/objspace.py Wed Aug 24 13:33:02 2005
@@ -107,6 +107,9 @@
if self.options.oldstyle:
self.enable_old_style_classes_as_default_metaclass()
+ # final setup
+ self.setup_builtin_modules()
+
def enable_old_style_classes_as_default_metaclass(self):
self.setitem(self.builtin.w_dict, self.wrap('__metaclass__'), self.w_classobj)
More information about the Pypy-commit
mailing list