diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2012-08-27 22:24:52 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2012-08-27 22:24:52 (GMT) |
commit | 0398985920dcad1fcff0859e18a5911a6c685ff1 (patch) | |
tree | de0d47e15582579bb02517e08759d9bba3619890 /Lib | |
parent | 30147710e8d6b2b5aebcf6f774fe289a4918958c (diff) | |
download | cpython-0398985920dcad1fcff0859e18a5911a6c685ff1.zip cpython-0398985920dcad1fcff0859e18a5911a6c685ff1.tar.gz cpython-0398985920dcad1fcff0859e18a5911a6c685ff1.tar.bz2 |
Issue #15781: Fix two small race conditions in import's module locking.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/importlib/_bootstrap.py | 10 | ||||
-rw-r--r-- | Lib/test/test_threaded_import.py | 12 |
2 files changed, 19 insertions, 3 deletions
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py index 171adc5..6697b2b 100644 --- a/Lib/importlib/_bootstrap.py +++ b/Lib/importlib/_bootstrap.py @@ -268,8 +268,10 @@ def _get_module_lock(name): Should only be called with the import lock taken.""" lock = None - if name in _module_locks: + try: lock = _module_locks[name]() + except KeyError: + pass if lock is None: if _thread is None: lock = _DummyModuleLock(name) @@ -543,6 +545,9 @@ def module_for_loader(fxn): # implicitly imports 'locale' and would otherwise trigger an # infinite loop. module = new_module(fullname) + # This must be done before putting the module in sys.modules + # (otherwise an optimization shortcut in import.c becomes wrong) + module.__initializing__ = True sys.modules[fullname] = module module.__loader__ = self try: @@ -554,8 +559,9 @@ def module_for_loader(fxn): module.__package__ = fullname else: module.__package__ = fullname.rpartition('.')[0] - try: + else: module.__initializing__ = True + try: # If __package__ was not set above, __import__() will do it later. return fxn(self, module, *args, **kwargs) except: diff --git a/Lib/test/test_threaded_import.py b/Lib/test/test_threaded_import.py index f540bdc..cfc6842 100644 --- a/Lib/test/test_threaded_import.py +++ b/Lib/test/test_threaded_import.py @@ -224,7 +224,17 @@ class ThreadedImportTests(unittest.TestCase): @reap_threads def test_main(): - run_unittest(ThreadedImportTests) + old_switchinterval = None + try: + old_switchinterval = sys.getswitchinterval() + sys.setswitchinterval(0.00000001) + except AttributeError: + pass + try: + run_unittest(ThreadedImportTests) + finally: + if old_switchinterval is not None: + sys.setswitchinterval(old_switchinterval) if __name__ == "__main__": test_main() |