Mercurial > cpython-lru_cache-weakref
diff Python/import.c @ 27852:4b75a0b76857 legacy-trunk
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.
Should this be backported? The patch requested this, but it's a new
feature.
| author | Guido van Rossum <guido@python.org> |
|---|---|
| date | Wed, 12 Feb 2003 21:46:11 +0000 |
| parents | afd1dc62e354 |
| children | 5620b0786271 |
line wrap: on
line diff
--- a/Python/import.c Wed Feb 12 20:48:22 2003 +0000 +++ b/Python/import.c Wed Feb 12 21:46:11 2003 +0000 @@ -252,7 +252,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); @@ -261,25 +262,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 @@ -295,6 +297,32 @@ #endif } +static PyObject * +imp_acquire_lock(PyObject *self, PyObject *args) +{ + if (!PyArg_ParseTuple(args, ":acquire_lock")) + return NULL; +#ifdef WITH_THREAD + lock_import(); +#endif + 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 + return Py_None; +} + /* Helper for sys */ PyObject * @@ -1970,7 +1998,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; } @@ -2743,6 +2776,17 @@ Return 1 if the import lock is currently held.\n\ On platforms without threads, return 0."); +PyDoc_STRVAR(doc_acquire_lock, +"acquire_lock() -> None\n\ +Acquires the interpreter's import lock for the current thread. This lock +should be used by import hooks to ensure thread-safety when importing modules. +On platforms without threads, this function does nothing."); + +PyDoc_STRVAR(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, METH_VARARGS, doc_find_module}, {"get_magic", imp_get_magic, METH_VARARGS, doc_get_magic}, @@ -2750,6 +2794,8 @@ {"load_module", imp_load_module, METH_VARARGS, doc_load_module}, {"new_module", imp_new_module, METH_VARARGS, doc_new_module}, {"lock_held", imp_lock_held, METH_VARARGS, doc_lock_held}, + {"acquire_lock", imp_acquire_lock, METH_VARARGS, doc_acquire_lock}, + {"release_lock", imp_release_lock, METH_VARARGS, doc_release_lock}, /* The rest are obsolete */ {"get_frozen_object", imp_get_frozen_object, METH_VARARGS}, {"init_builtin", imp_init_builtin, METH_VARARGS},
