Mercurial > cpython-lru_cache-weakref
diff Python/import.c @ 27867:e6cf9557de42 2.2
Backport 2.217 and 2.218:
Provide access to the import lock, fixing SF bug #580952. This is
mostly from SF patch #683257, but I had to change unlock_import() to
return an error value to avoid fatal error.
| author | Guido van Rossum <guido@python.org> |
|---|---|
| date | Thu, 13 Feb 2003 17:06:02 +0000 |
| parents | c00febbe0929 |
| children | bc9076b01694 |
line wrap: on
line diff
--- a/Python/import.c Wed Feb 12 19:09:45 2003 +0000 +++ b/Python/import.c Thu Feb 13 17:06:02 2003 +0000 @@ -161,7 +161,8 @@ import_lock_level++; return; } - if (import_lock_thread != -1 || !PyThread_acquire_lock(import_lock, 0)) { + if (import_lock_thread != -1 || !PyThread_acquire_lock(import_lock, 0)) + { PyThreadState *tstate = PyEval_SaveThread(); PyThread_acquire_lock(import_lock, 1); PyEval_RestoreThread(tstate); @@ -170,25 +171,26 @@ import_lock_level = 1; } -static void +static int unlock_import(void) { long me = PyThread_get_thread_ident(); if (me == -1) - return; /* Too bad */ + return 0; /* Too bad */ if (import_lock_thread != me) - Py_FatalError("unlock_import: not holding the import lock"); + return -1; import_lock_level--; if (import_lock_level == 0) { import_lock_thread = -1; PyThread_release_lock(import_lock); } + return 1; } #else #define lock_import() -#define unlock_import() +#define unlock_import() 0 #endif @@ -204,6 +206,34 @@ #endif } +static PyObject * +imp_acquire_lock(PyObject *self, PyObject *args) +{ + if (!PyArg_ParseTuple(args, ":acquire_lock")) + return NULL; +#ifdef WITH_THREAD + lock_import(); +#endif + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +imp_release_lock(PyObject *self, PyObject *args) +{ + if (!PyArg_ParseTuple(args, ":release_lock")) + return NULL; +#ifdef WITH_THREAD + if (unlock_import() < 0) { + PyErr_SetString(PyExc_RuntimeError, + "not holding the import lock"); + return NULL; + } +#endif + Py_INCREF(Py_None); + return Py_None; +} + /* Helper for sys */ PyObject * @@ -1656,7 +1686,12 @@ PyObject *result; lock_import(); result = import_module_ex(name, globals, locals, fromlist); - unlock_import(); + if (unlock_import() < 0) { + Py_XDECREF(result); + PyErr_SetString(PyExc_RuntimeError, + "not holding the import lock"); + return NULL; + } return result; } @@ -2426,6 +2461,18 @@ On platforms without threads, return 0.\ "; +static char doc_acquire_lock[] = "\ +acquire_lock() -> None\n\ +Acquires the interpreter's import lock for the current thread.\n\ +This lock should be used by import hooks to ensure thread-safety\n\ +when importing modules.\n\ +On platforms without threads, this function does nothing."; + +static char doc_release_lock[] = "\ +release_lock() -> None\n\ +Release the interpreter's import lock.\n\ +On platforms without threads, this function does nothing."; + static PyMethodDef imp_methods[] = { {"find_module", imp_find_module, 1, doc_find_module}, {"get_magic", imp_get_magic, 1, doc_get_magic}, @@ -2433,6 +2480,8 @@ {"load_module", imp_load_module, 1, doc_load_module}, {"new_module", imp_new_module, 1, doc_new_module}, {"lock_held", imp_lock_held, 1, doc_lock_held}, + {"acquire_lock", imp_acquire_lock, 1, doc_acquire_lock}, + {"release_lock", imp_release_lock, 1, doc_release_lock}, /* The rest are obsolete */ {"get_frozen_object", imp_get_frozen_object, 1}, {"init_builtin", imp_init_builtin, 1},
