mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	Modified PyImport_Import and PyImport_ImportModule to always use absolute imports by calling __import__ with an explicit level of 0
Added a new API function PyImport_ImportModuleNoBlock. It solves the problem with dead locks when mixing threads and imports
This commit is contained in:
		
							parent
							
								
									0a83d79268
								
							
						
					
					
						commit
						000a074c95
					
				
					 19 changed files with 135 additions and 63 deletions
				
			
		|  | @ -1985,6 +1985,53 @@ PyImport_ImportModule(const char *name) | |||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| /* Import a module without blocking
 | ||||
|  * | ||||
|  * At first it tries to fetch the module from sys.modules. If the module was | ||||
|  * never loaded before it loads it with PyImport_ImportModule() unless another | ||||
|  * thread holds the import lock. In the latter case the function raises an | ||||
|  * ImportError instead of blocking. | ||||
|  * | ||||
|  * Returns the module object with incremented ref count. | ||||
|  */ | ||||
| PyObject * | ||||
| PyImport_ImportModuleNoBlock(const char *name) | ||||
| { | ||||
| 	PyObject *result; | ||||
| 	PyObject *modules; | ||||
| 	long me; | ||||
| 
 | ||||
| 	/* Try to get the module from sys.modules[name] */ | ||||
| 	modules = PyImport_GetModuleDict(); | ||||
| 	if (modules == NULL) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	result = PyDict_GetItemString(modules, name); | ||||
| 	if (result != NULL) { | ||||
| 		Py_INCREF(result); | ||||
| 		return result; | ||||
| 	} | ||||
| 	else { | ||||
| 		PyErr_Clear(); | ||||
| 	} | ||||
| 
 | ||||
| 	/* check the import lock
 | ||||
| 	 * me might be -1 but I ignore the error here, the lock function | ||||
| 	 * takes care of the problem */ | ||||
| 	me = PyThread_get_thread_ident(); | ||||
| 	if (import_lock_thread == -1 || import_lock_thread == me) { | ||||
| 		/* no thread or me is holding the lock */ | ||||
| 		return PyImport_ImportModule(name); | ||||
| 	} | ||||
| 	else { | ||||
| 		PyErr_Format(PyExc_ImportError, | ||||
| 			     "Failed to import %.200s because the import lock" | ||||
| 			     "is held by another thread.", | ||||
| 			     name); | ||||
| 		return NULL; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /* Forward declarations for helper routines */ | ||||
| static PyObject *get_parent(PyObject *globals, char *buf, | ||||
| 			    Py_ssize_t *p_buflen, int level); | ||||
|  | @ -2054,26 +2101,6 @@ import_module_level(char *name, PyObject *globals, PyObject *locals, | |||
| 	return tail; | ||||
| } | ||||
| 
 | ||||
| /* For DLL compatibility */ | ||||
| #undef PyImport_ImportModuleEx | ||||
| PyObject * | ||||
| PyImport_ImportModuleEx(char *name, PyObject *globals, PyObject *locals, | ||||
| 			PyObject *fromlist) | ||||
| { | ||||
| 	PyObject *result; | ||||
| 	lock_import(); | ||||
| 	result = import_module_level(name, globals, locals, fromlist, -1); | ||||
| 	if (unlock_import() < 0) { | ||||
| 		Py_XDECREF(result); | ||||
| 		PyErr_SetString(PyExc_RuntimeError, | ||||
| 				"not holding the import lock"); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	return result; | ||||
| } | ||||
| #define PyImport_ImportModuleEx(n, g, l, f) \ | ||||
| 	PyImport_ImportModuleLevel(n, g, l, f, -1); | ||||
| 
 | ||||
| PyObject * | ||||
| PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals, | ||||
| 			 PyObject *fromlist, int level) | ||||
|  | @ -2646,9 +2673,10 @@ PyImport_Import(PyObject *module_name) | |||
| 	if (import == NULL) | ||||
| 		goto err; | ||||
| 
 | ||||
| 	/* Call the __import__ function with the proper argument list */ | ||||
| 	r = PyObject_CallFunctionObjArgs(import, module_name, globals, | ||||
| 					 globals, silly_list, NULL); | ||||
| 	/* Call the __import__ function with the proper argument list
 | ||||
| 	 * Always use absolute import here. */ | ||||
| 	r = PyObject_CallFunction(import, "OOOOi", module_name, globals, | ||||
| 				  globals, silly_list, 0, NULL); | ||||
| 
 | ||||
|   err: | ||||
| 	Py_XDECREF(globals); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Christian Heimes
						Christian Heimes