Index: Python/errors.c =================================================================== --- Python/errors.c (Revision 59405) +++ Python/errors.c (Arbeitskopie) @@ -711,7 +711,7 @@ { PyObject *mod, *dict, *func = NULL; - mod = PyImport_ImportModule("warnings"); + mod = _PyImport_ImportModuleNoLock("warnings"); if (mod != NULL) { dict = PyModule_GetDict(mod); func = PyDict_GetItemString(dict, "warn_explicit"); Index: Python/mactoolboxglue.c =================================================================== --- Python/mactoolboxglue.c (Revision 59405) +++ Python/mactoolboxglue.c (Arbeitskopie) @@ -36,7 +36,7 @@ PyObject *m; PyObject *rv; - m = PyImport_ImportModule("MacOS"); + m = _PyImport_ImportModuleNoLock("MacOS"); if (!m) { if (Py_VerboseFlag) PyErr_Print(); Index: Python/ast.c =================================================================== --- Python/ast.c (Revision 59405) +++ Python/ast.c (Arbeitskopie) @@ -56,7 +56,7 @@ identifier; if so, normalize to NFKC. */ for (; *u; u++) { if (*u >= 128) { - PyObject *m = PyImport_ImportModule("unicodedata"); + PyObject *m = _PyImport_ImportModuleNoLock("unicodedata"); PyObject *id2; if (!m) return NULL; Index: Python/import.c =================================================================== --- Python/import.c (Revision 59405) +++ Python/import.c (Arbeitskopie) @@ -1895,6 +1895,53 @@ return result; } +/* Import a module without blocking + * + * It tries to fetch the module from sys.modules. If the module was never + * loaded before it loads it with PyImport_ImportModule(), When the import + * lock is held by another thread it fails with an import error instead of + * blocking. + * + * Returns the module object with incremented ref count. + */ +PyObject * +_PyImport_ImportModuleNoLock(const char *name) +{ + PyObject *result; + PyObject *modules; + long me; + + /* Try to get the module from sys.modules[name] */ + modules = PySys_GetObject("modules"); + 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); Index: Python/bltinmodule.c =================================================================== --- Python/bltinmodule.c (Revision 59405) +++ Python/bltinmodule.c (Arbeitskopie) @@ -261,7 +261,7 @@ builtin_filter(PyObject *self, PyObject *args) { PyObject *itertools, *ifilter, *result; - itertools = PyImport_ImportModule("itertools"); + itertools = _PyImport_ImportModuleNoLock("itertools"); if (itertools == NULL) return NULL; ifilter = PyObject_GetAttrString(itertools, "ifilter"); @@ -776,7 +776,7 @@ builtin_map(PyObject *self, PyObject *args) { PyObject *itertools, *imap, *result; - itertools = PyImport_ImportModule("itertools"); + itertools = _PyImport_ImportModuleNoLock("itertools"); if (itertools == NULL) return NULL; imap = PyObject_GetAttrString(itertools, "imap"); Index: Include/py_curses.h =================================================================== --- Include/py_curses.h (Revision 59405) +++ Include/py_curses.h (Arbeitskopie) @@ -90,7 +90,7 @@ #define import_curses() \ { \ - PyObject *module = PyImport_ImportModule("_curses"); \ + PyObject *module = _PyImport_ImportModuleNoLock("_curses"); \ if (module != NULL) { \ PyObject *module_dict = PyModule_GetDict(module); \ PyObject *c_api_object = PyDict_GetItemString(module_dict, "_C_API"); \ Index: Include/import.h =================================================================== --- Include/import.h (Revision 59405) +++ Include/import.h (Arbeitskopie) @@ -14,6 +14,7 @@ PyAPI_FUNC(PyObject *) PyImport_GetModuleDict(void); PyAPI_FUNC(PyObject *) PyImport_AddModule(const char *name); PyAPI_FUNC(PyObject *) PyImport_ImportModule(const char *name); +PyAPI_FUNC(PyObject *) _PyImport_ImportModuleNoLock(const char *); PyAPI_FUNC(PyObject *) PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist, int level); Index: Objects/unicodeobject.c =================================================================== --- Objects/unicodeobject.c (Revision 59405) +++ Objects/unicodeobject.c (Arbeitskopie) @@ -2800,7 +2800,7 @@ if (ucnhash_CAPI == NULL) { /* load the unicode data module */ PyObject *m, *api; - m = PyImport_ImportModule("unicodedata"); + m = _PyImport_ImportModuleNoLock("unicodedata"); if (m == NULL) goto ucnhashError; api = PyObject_GetAttrString(m, "ucnhash_CAPI"); Index: Objects/fileobject.c =================================================================== --- Objects/fileobject.c (Revision 59405) +++ Objects/fileobject.c (Arbeitskopie) @@ -31,7 +31,7 @@ { PyObject *io, *stream, *nameobj = NULL; - io = PyImport_ImportModule("io"); + io = _PyImport_ImportModuleNoLock("io"); if (io == NULL) return NULL; stream = PyObject_CallMethod(io, "open", "isisssi", fd, mode, Index: Parser/tokenizer.c =================================================================== --- Parser/tokenizer.c (Revision 59405) +++ Parser/tokenizer.c (Arbeitskopie) @@ -452,7 +452,7 @@ { PyObject *readline = NULL, *stream = NULL, *io = NULL; - io = PyImport_ImportModule("io"); + io = _PyImport_ImportModuleNoLock("io"); if (io == NULL) goto cleanup; Index: Mac/Modules/MacOS.c =================================================================== --- Mac/Modules/MacOS.c (Revision 59405) +++ Mac/Modules/MacOS.c (Arbeitskopie) @@ -356,7 +356,7 @@ PyObject *m, *rv; errors_loaded = 1; - m = PyImport_ImportModule("macresource"); + m = _PyImport_ImportModuleNoLock("macresource"); if (!m) { if (Py_VerboseFlag) PyErr_Print(); Index: PC/bdist_wininst/install.c =================================================================== --- PC/bdist_wininst/install.c (Revision 59405) +++ PC/bdist_wininst/install.c (Arbeitskopie) @@ -654,7 +654,7 @@ if (!Py_BuildValue || !PyArg_ParseTuple || !PyErr_Format) return 1; - mod = PyImport_ImportModule("builtins"); + mod = _PyImport_ImportModuleNoLock("builtins"); if (mod) { int i; g_PyExc_ValueError = PyObject_GetAttrString(mod, "ValueError"); Index: Modules/_ctypes/callbacks.c =================================================================== --- Modules/_ctypes/callbacks.c (Revision 59405) +++ Modules/_ctypes/callbacks.c (Arbeitskopie) @@ -367,7 +367,7 @@ if (context == NULL) context = PyUnicode_FromString("_ctypes.DllGetClassObject"); - mod = PyImport_ImportModule("ctypes"); + mod = _PyImport_ImportModuleNoLock("ctypes"); if (!mod) { PyErr_WriteUnraisable(context ? context : Py_None); /* There has been a warning before about this already */ @@ -446,7 +446,7 @@ if (context == NULL) context = PyUnicode_FromString("_ctypes.DllCanUnloadNow"); - mod = PyImport_ImportModule("ctypes"); + mod = _PyImport_ImportModuleNoLock("ctypes"); if (!mod) { /* OutputDebugString("Could not import ctypes"); */ /* We assume that this error can only occur when shutting Index: Modules/datetimemodule.c =================================================================== --- Modules/datetimemodule.c (Revision 59405) +++ Modules/datetimemodule.c (Arbeitskopie) @@ -1329,7 +1329,7 @@ goto Done; { PyObject *format; - PyObject *time = PyImport_ImportModule("time"); + PyObject *time = _PyImport_ImportModuleNoLock("time"); if (time == NULL) goto Done; format = PyUnicode_FromString(PyString_AS_STRING(newfmt)); @@ -1357,7 +1357,7 @@ time_time(void) { PyObject *result = NULL; - PyObject *time = PyImport_ImportModule("time"); + PyObject *time = _PyImport_ImportModuleNoLock("time"); if (time != NULL) { result = PyObject_CallMethod(time, "time", "()"); @@ -1375,7 +1375,7 @@ PyObject *time; PyObject *result = NULL; - time = PyImport_ImportModule("time"); + time = _PyImport_ImportModuleNoLock("time"); if (time != NULL) { result = PyObject_CallMethod(time, "struct_time", "((iiiiiiiii))", @@ -3821,7 +3821,7 @@ if (!PyArg_ParseTuple(args, "uu:strptime", &string, &format)) return NULL; - if ((module = PyImport_ImportModule("time")) == NULL) + if ((module = _PyImport_ImportModuleNoLock("time")) == NULL) return NULL; obj = PyObject_CallMethod(module, "strptime", "uu", string, format); Py_DECREF(module); Index: Modules/socketmodule.h =================================================================== --- Modules/socketmodule.h (Revision 59405) +++ Modules/socketmodule.h (Arbeitskopie) @@ -222,7 +222,7 @@ void *api; DPRINTF("Importing the %s C API...\n", apimodule); - mod = PyImport_ImportModule(apimodule); + mod = _PyImport_ImportModuleNoLock(apimodule); if (mod == NULL) goto onError; DPRINTF(" %s package found\n", apimodule); Index: Modules/cjkcodecs/cjkcodecs.h =================================================================== --- Modules/cjkcodecs/cjkcodecs.h (Revision 59405) +++ Modules/cjkcodecs/cjkcodecs.h (Arbeitskopie) @@ -245,7 +245,7 @@ static PyObject *cofunc = NULL; if (cofunc == NULL) { - PyObject *mod = PyImport_ImportModule("_multibytecodec"); + PyObject *mod = _PyImport_ImportModuleNoLock("_multibytecodec"); if (mod == NULL) return NULL; cofunc = PyObject_GetAttrString(mod, "__create_codec"); Index: Modules/_bsddb.c =================================================================== --- Modules/_bsddb.c (Revision 59405) +++ Modules/_bsddb.c (Arbeitskopie) @@ -6002,7 +6002,7 @@ * using one base class. */ PyDict_SetItemString(d, "KeyError", PyExc_KeyError); { - PyObject *builtin_mod = PyImport_ImportModule("builtins"); + PyObject *builtin_mod = _PyImport_ImportModuleNoLock("builtins"); PyDict_SetItemString(d, "__builtins__", builtin_mod); } PyRun_String("class DBNotFoundError(DBError, KeyError): pass\n" Index: Modules/zipimport.c =================================================================== --- Modules/zipimport.c (Revision 59405) +++ Modules/zipimport.c (Arbeitskopie) @@ -766,7 +766,7 @@ let's avoid a stack overflow. */ return NULL; importing_zlib = 1; - zlib = PyImport_ImportModule("zlib"); /* import zlib */ + zlib = _PyImport_ImportModuleNoLock("zlib"); importing_zlib = 0; if (zlib != NULL) { decompress = PyObject_GetAttrString(zlib, Index: Modules/timemodule.c =================================================================== --- Modules/timemodule.c (Revision 59405) +++ Modules/timemodule.c (Arbeitskopie) @@ -555,7 +555,7 @@ static PyObject * time_strptime(PyObject *self, PyObject *args) { - PyObject *strptime_module = PyImport_ImportModule("_strptime"); + PyObject *strptime_module = _PyImport_ImportModuleNoLock("_strptime"); PyObject *strptime_result; if (!strptime_module) @@ -667,7 +667,7 @@ { PyObject* m; - m = PyImport_ImportModule("time"); + m = _PyImport_ImportModuleNoLock("time"); if (m == NULL) { return NULL; } Index: Modules/gcmodule.c =================================================================== --- Modules/gcmodule.c (Revision 59405) +++ Modules/gcmodule.c (Arbeitskopie) @@ -1210,7 +1210,7 @@ * the import and triggers an assertion. */ if (tmod == NULL) { - tmod = PyImport_ImportModule("time"); + tmod = _PyImport_ImportModuleNoLock("time"); if (tmod == NULL) PyErr_Clear(); } Index: Modules/parsermodule.c =================================================================== --- Modules/parsermodule.c (Revision 59405) +++ Modules/parsermodule.c (Arbeitskopie) @@ -3093,7 +3093,7 @@ * If this fails, the import of this module will fail because an * exception will be raised here; should we clear the exception? */ - copyreg = PyImport_ImportModule("copy_reg"); + copyreg = _PyImport_ImportModuleNoLock("copy_reg"); if (copyreg != NULL) { PyObject *func, *pickler; Index: Modules/posixmodule.c =================================================================== --- Modules/posixmodule.c (Revision 59405) +++ Modules/posixmodule.c (Arbeitskopie) @@ -4217,7 +4217,7 @@ return posix_error(); if (struct_rusage == NULL) { - PyObject *m = PyImport_ImportModule("resource"); + PyObject *m = _PyImport_ImportModuleNoLock("resource"); if (m == NULL) return NULL; struct_rusage = PyObject_GetAttrString(m, "struct_rusage"); Index: Modules/_cursesmodule.c =================================================================== --- Modules/_cursesmodule.c (Revision 59405) +++ Modules/_cursesmodule.c (Arbeitskopie) @@ -2316,7 +2316,7 @@ update_lines_cols(void) { PyObject *o; - PyObject *m = PyImport_ImportModule("curses"); + PyObject *m = _PyImport_ImportModuleNoLock("curses"); if (!m) return 0;