[Python-checkins] cpython: Issue #15781: Fix two small race conditions in import's module locking.

georg.brandl python-checkins at python.org
Sun Sep 9 11:19:03 CEST 2012


http://hg.python.org/cpython/rev/85070f284fd2
changeset: 78900:85070f284fd2
user: Antoine Pitrou <solipsis at pitrou.net>
date: Tue Aug 28 00:24:52 2012 +0200
summary:
 Issue #15781: Fix two small race conditions in import's module locking.
files:
 Lib/importlib/_bootstrap.py | 10 +-
 Lib/test/test_threaded_import.py | 12 +-
 Misc/NEWS | 2 +
 Python/import.c | 6 +-
 Python/importlib.h | 7302 +++++++++--------
 5 files changed, 3678 insertions(+), 3654 deletions(-)
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -268,8 +268,10 @@
 
 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 @@
 # 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 @@
 module.__package__ = fullname
 else:
 module.__package__ = fullname.rpartition('.')[0]
+ else:
+ module.__initializing__ = True
 try:
- module.__initializing__ = True
 # 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
--- a/Lib/test/test_threaded_import.py
+++ b/Lib/test/test_threaded_import.py
@@ -224,7 +224,17 @@
 
 @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()
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -13,6 +13,8 @@
 - Issue #15784: Modify OSError.__str__() to better distinguish between
 errno error numbers and Windows error numbers.
 
+- Issue #15781: Fix two small race conditions in import's module locking.
+
 Library
 -------
 
diff --git a/Python/import.c b/Python/import.c
--- a/Python/import.c
+++ b/Python/import.c
@@ -1408,7 +1408,11 @@
 int initializing = 0;
 
 Py_INCREF(mod);
- /* Only call _bootstrap._lock_unlock_module() if __initializing__ is true. */
+ /* Optimization: only call _bootstrap._lock_unlock_module() if
+ __initializing__ is true.
+ NOTE: because of this, __initializing__ must be set *before*
+ stuffing the new module in sys.modules.
+ */
 value = _PyObject_GetAttrId(mod, &PyId___initializing__);
 if (value == NULL)
 PyErr_Clear();
diff --git a/Python/importlib.h b/Python/importlib.h
--- a/Python/importlib.h
+++ b/Python/importlib.h
[stripped]
-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /