mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +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.""" | ||||
|     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_wrapper(self, fullname, *args, **kwargs): | |||
|             # 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_wrapper(self, fullname, *args, **kwargs): | |||
|                     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: | ||||
|  |  | |||
|  | @ -224,7 +224,17 @@ def target(): | |||
| 
 | ||||
| @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() | ||||
|  |  | |||
|  | @ -13,6 +13,8 @@ Core and Builtins | |||
| - 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 | ||||
| ------- | ||||
| 
 | ||||
|  |  | |||
|  | @ -1408,7 +1408,11 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *given_globals, | |||
|         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(); | ||||
|  |  | |||
							
								
								
									
										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
	
	 Antoine Pitrou
						Antoine Pitrou