mirror of
https://github.com/python/cpython.git
synced 2025-07-19 09:15:34 +00:00
Issue #15781: Fix two small race conditions in import's module locking.
This commit is contained in:
parent
30147710e8
commit
0398985920
5 changed files with 3679 additions and 3655 deletions
|
@ -268,8 +268,10 @@ def _get_module_lock(name):
|
||||||
|
|
||||||
Should only be called with the import lock taken."""
|
Should only be called with the import lock taken."""
|
||||||
lock = None
|
lock = None
|
||||||
if name in _module_locks:
|
try:
|
||||||
lock = _module_locks[name]()
|
lock = _module_locks[name]()
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
if lock is None:
|
if lock is None:
|
||||||
if _thread is None:
|
if _thread is None:
|
||||||
lock = _DummyModuleLock(name)
|
lock = _DummyModuleLock(name)
|
||||||
|
@ -543,6 +545,9 @@ def module_for_loader(fxn):
|
||||||
# implicitly imports 'locale' and would otherwise trigger an
|
# implicitly imports 'locale' and would otherwise trigger an
|
||||||
# infinite loop.
|
# infinite loop.
|
||||||
module = new_module(fullname)
|
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
|
sys.modules[fullname] = module
|
||||||
module.__loader__ = self
|
module.__loader__ = self
|
||||||
try:
|
try:
|
||||||
|
@ -554,8 +559,9 @@ def module_for_loader(fxn):
|
||||||
module.__package__ = fullname
|
module.__package__ = fullname
|
||||||
else:
|
else:
|
||||||
module.__package__ = fullname.rpartition('.')[0]
|
module.__package__ = fullname.rpartition('.')[0]
|
||||||
try:
|
else:
|
||||||
module.__initializing__ = True
|
module.__initializing__ = True
|
||||||
|
try:
|
||||||
# If __package__ was not set above, __import__() will do it later.
|
# If __package__ was not set above, __import__() will do it later.
|
||||||
return fxn(self, module, *args, **kwargs)
|
return fxn(self, module, *args, **kwargs)
|
||||||
except:
|
except:
|
||||||
|
|
|
@ -224,7 +224,17 @@ class ThreadedImportTests(unittest.TestCase):
|
||||||
|
|
||||||
@reap_threads
|
@reap_threads
|
||||||
def test_main():
|
def test_main():
|
||||||
|
old_switchinterval = None
|
||||||
|
try:
|
||||||
|
old_switchinterval = sys.getswitchinterval()
|
||||||
|
sys.setswitchinterval(0.00000001)
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
run_unittest(ThreadedImportTests)
|
run_unittest(ThreadedImportTests)
|
||||||
|
finally:
|
||||||
|
if old_switchinterval is not None:
|
||||||
|
sys.setswitchinterval(old_switchinterval)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
test_main()
|
test_main()
|
||||||
|
|
|
@ -13,6 +13,8 @@ Core and Builtins
|
||||||
- Issue #15784: Modify OSError.__str__() to better distinguish between
|
- Issue #15784: Modify OSError.__str__() to better distinguish between
|
||||||
errno error numbers and Windows error numbers.
|
errno error numbers and Windows error numbers.
|
||||||
|
|
||||||
|
- Issue #15781: Fix two small race conditions in import's module locking.
|
||||||
|
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
|
|
@ -1408,7 +1408,11 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals,
|
||||||
int initializing = 0;
|
int initializing = 0;
|
||||||
|
|
||||||
Py_INCREF(mod);
|
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__);
|
value = _PyObject_GetAttrId(mod, &PyId___initializing__);
|
||||||
if (value == NULL)
|
if (value == NULL)
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
|
|
7304
Python/importlib.h
7304
Python/importlib.h
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue