summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Include/internal/pycore_import.h2
-rw-r--r--Python/import.c13
-rw-r--r--Python/pystate.c5
3 files changed, 16 insertions, 4 deletions
diff --git a/Include/internal/pycore_import.h b/Include/internal/pycore_import.h
index 7a78a91..0a9f24e 100644
--- a/Include/internal/pycore_import.h
+++ b/Include/internal/pycore_import.h
@@ -19,6 +19,8 @@ struct _import_runtime_state {
used exclusively for when the extensions dict is access/modified
from an arbitrary thread. */
PyThreadState main_tstate;
+ /* A lock to guard the dict. */
+ PyThread_type_lock mutex;
/* A dict mapping (filename, name) to PyModuleDef for modules.
Only legacy (single-phase init) extension modules are added
and only if they support multiple initialization (m_size >- 0)
diff --git a/Python/import.c b/Python/import.c
index df57780..daec64e 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -413,8 +413,11 @@ remove_module(PyThreadState *tstate, PyObject *name)
Py_ssize_t
_PyImport_GetNextModuleIndex(void)
{
+ PyThread_acquire_lock(EXTENSIONS.mutex, WAIT_LOCK);
LAST_MODULE_INDEX++;
- return LAST_MODULE_INDEX;
+ Py_ssize_t index = LAST_MODULE_INDEX;
+ PyThread_release_lock(EXTENSIONS.mutex);
+ return index;
}
static const char *
@@ -703,6 +706,7 @@ _PyImport_ClearModulesByIndex(PyInterpreterState *interp)
const char *
_PyImport_ResolveNameWithPackageContext(const char *name)
{
+ PyThread_acquire_lock(EXTENSIONS.mutex, WAIT_LOCK);
if (PKGCONTEXT != NULL) {
const char *p = strrchr(PKGCONTEXT, '.');
if (p != NULL && strcmp(name, p+1) == 0) {
@@ -710,14 +714,17 @@ _PyImport_ResolveNameWithPackageContext(const char *name)
PKGCONTEXT = NULL;
}
}
+ PyThread_release_lock(EXTENSIONS.mutex);
return name;
}
const char *
_PyImport_SwapPackageContext(const char *newcontext)
{
+ PyThread_acquire_lock(EXTENSIONS.mutex, WAIT_LOCK);
const char *oldcontext = PKGCONTEXT;
PKGCONTEXT = newcontext;
+ PyThread_release_lock(EXTENSIONS.mutex);
return oldcontext;
}
@@ -865,13 +872,13 @@ gets even messier.
static inline void
extensions_lock_acquire(void)
{
- // XXX For now the GIL is sufficient.
+ PyThread_acquire_lock(_PyRuntime.imports.extensions.mutex, WAIT_LOCK);
}
static inline void
extensions_lock_release(void)
{
- // XXX For now the GIL is sufficient.
+ PyThread_release_lock(_PyRuntime.imports.extensions.mutex);
}
/* Magic for extension modules (built-in as well as dynamically
diff --git a/Python/pystate.c b/Python/pystate.c
index b2ef7e2..ffab301 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -380,7 +380,7 @@ _Py_COMP_DIAG_IGNORE_DEPR_DECLS
static const _PyRuntimeState initial = _PyRuntimeState_INIT(_PyRuntime);
_Py_COMP_DIAG_POP
-#define NUMLOCKS 4
+#define NUMLOCKS 5
static int
alloc_for_runtime(PyThread_type_lock locks[NUMLOCKS])
@@ -434,6 +434,7 @@ init_runtime(_PyRuntimeState *runtime,
&runtime->xidregistry.mutex,
&runtime->getargs.mutex,
&runtime->unicode_state.ids.lock,
+ &runtime->imports.extensions.mutex,
};
for (int i = 0; i < NUMLOCKS; i++) {
assert(locks[i] != NULL);
@@ -518,6 +519,7 @@ _PyRuntimeState_Fini(_PyRuntimeState *runtime)
&runtime->xidregistry.mutex,
&runtime->getargs.mutex,
&runtime->unicode_state.ids.lock,
+ &runtime->imports.extensions.mutex,
};
for (int i = 0; i < NUMLOCKS; i++) {
FREE_LOCK(*lockptrs[i]);
@@ -546,6 +548,7 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime)
&runtime->xidregistry.mutex,
&runtime->getargs.mutex,
&runtime->unicode_state.ids.lock,
+ &runtime->imports.extensions.mutex,
};
int reinit_err = 0;
for (int i = 0; i < NUMLOCKS; i++) {