[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