mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
Fix bug in specialization and make reification atomic
This commit is contained in:
parent
cdec6a6236
commit
c3b4807dac
2 changed files with 17 additions and 3 deletions
|
|
@ -3712,20 +3712,25 @@ _PyImport_LoadLazyImportTstate(PyThreadState *tstate, PyObject *lazy_import)
|
||||||
assert(PyLazyImport_CheckExact(lazy_import));
|
assert(PyLazyImport_CheckExact(lazy_import));
|
||||||
|
|
||||||
PyLazyImportObject *lz = (PyLazyImportObject *)lazy_import;
|
PyLazyImportObject *lz = (PyLazyImportObject *)lazy_import;
|
||||||
|
PyInterpreterState *interp = tstate->interp;
|
||||||
|
|
||||||
|
// Acquire the global import lock to serialize reification
|
||||||
|
_PyImport_AcquireLock(interp);
|
||||||
|
|
||||||
// Check if we are already importing this module, if so, then we want to return an error
|
// Check if we are already importing this module, if so, then we want to return an error
|
||||||
// that indicates we've hit a cycle which will indicate the value isn't yet available.
|
// that indicates we've hit a cycle which will indicate the value isn't yet available.
|
||||||
PyInterpreterState *interp = tstate->interp;
|
|
||||||
PyObject *importing = interp->imports.lazy_importing_modules;
|
PyObject *importing = interp->imports.lazy_importing_modules;
|
||||||
if (importing == NULL) {
|
if (importing == NULL) {
|
||||||
importing = interp->imports.lazy_importing_modules = PySet_New(NULL);
|
importing = interp->imports.lazy_importing_modules = PySet_New(NULL);
|
||||||
if (importing == NULL) {
|
if (importing == NULL) {
|
||||||
|
_PyImport_ReleaseLock(interp);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int is_loading = PySet_Contains(importing, lazy_import);
|
int is_loading = PySet_Contains(importing, lazy_import);
|
||||||
if (is_loading < 0) {
|
if (is_loading < 0) {
|
||||||
|
_PyImport_ReleaseLock(interp);
|
||||||
return NULL;
|
return NULL;
|
||||||
} else if (is_loading == 1) {
|
} else if (is_loading == 1) {
|
||||||
PyObject *name = _PyLazyImport_GetName(lazy_import);
|
PyObject *name = _PyLazyImport_GetName(lazy_import);
|
||||||
|
|
@ -3735,8 +3740,10 @@ _PyImport_LoadLazyImportTstate(PyThreadState *tstate, PyObject *lazy_import)
|
||||||
PyErr_SetImportErrorSubclass(PyExc_ImportCycleError, errmsg, lz->lz_from, NULL);
|
PyErr_SetImportErrorSubclass(PyExc_ImportCycleError, errmsg, lz->lz_from, NULL);
|
||||||
Py_XDECREF(errmsg);
|
Py_XDECREF(errmsg);
|
||||||
Py_XDECREF(name);
|
Py_XDECREF(name);
|
||||||
|
_PyImport_ReleaseLock(interp);
|
||||||
return NULL;
|
return NULL;
|
||||||
} else if (PySet_Add(importing, lazy_import) < 0) {
|
} else if (PySet_Add(importing, lazy_import) < 0) {
|
||||||
|
_PyImport_ReleaseLock(interp);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3889,6 +3896,9 @@ _PyImport_LoadLazyImportTstate(PyThreadState *tstate, PyObject *lazy_import)
|
||||||
obj = NULL;
|
obj = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Release the global import lock
|
||||||
|
_PyImport_ReleaseLock(interp);
|
||||||
|
|
||||||
Py_XDECREF(fromlist);
|
Py_XDECREF(fromlist);
|
||||||
Py_XDECREF(import_func);
|
Py_XDECREF(import_func);
|
||||||
return obj;
|
return obj;
|
||||||
|
|
|
||||||
|
|
@ -1708,10 +1708,14 @@ specialize_load_global_lock_held(
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
PyObject *value = NULL;
|
PyObject *value = NULL;
|
||||||
if (PyDict_GetItemRef(globals, name, &value) < 0 ||
|
if (PyDict_GetItemRef(globals, name, &value) < 0) {
|
||||||
(value != NULL && PyLazyImport_CheckExact(value))) {
|
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_EXPECTED_ERROR);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
if (value != NULL && PyLazyImport_CheckExact(value)) {
|
||||||
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_ATTR_MODULE_LAZY_VALUE);
|
SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_ATTR_MODULE_LAZY_VALUE);
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
Py_XDECREF(value);
|
Py_XDECREF(value);
|
||||||
Py_ssize_t index = _PyDictKeys_StringLookup(globals_keys, name);
|
Py_ssize_t index = _PyDictKeys_StringLookup(globals_keys, name);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue