summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2023-06-14 01:34:26 (GMT)
committerGitHub <noreply@github.com>2023-06-14 01:34:26 (GMT)
commitbc997b38b66cd61ab2ba9697546c39472cb93ee3 (patch)
tree1d315d7dd3738c81570791b2f3026ff4cdd2e779
parent26bc2cc06128890ac89492eca20e83abe0789c1c (diff)
downloadcpython-bc997b38b66cd61ab2ba9697546c39472cb93ee3.zip
cpython-bc997b38b66cd61ab2ba9697546c39472cb93ee3.tar.gz
cpython-bc997b38b66cd61ab2ba9697546c39472cb93ee3.tar.bz2
[3.12] gh-105699: Use a Thread-Local Variable for PKGCONTEXT (gh-105740) (gh-105765)
This fixes a race during import. The existing _PyRuntimeState.imports.pkgcontext is shared between interpreters, and occasionally this would cause a crash when multiple interpreters were importing extensions modules at the same time. To solve this we add a thread-local variable for the value. We also leave the existing state (and infrequent race) in place for platforms that do not support thread-local variables. (cherry picked from commit b87d2882754a7c273e2695c33384383eba380d7d) Co-authored-by: Eric Snow <ericsnowcurrently@gmail.com>
-rw-r--r--Python/import.c15
-rw-r--r--Tools/c-analyzer/c_parser/parser/_regexes.py3
-rw-r--r--Tools/c-analyzer/c_parser/preprocessor/gcc.py1
-rw-r--r--Tools/c-analyzer/cpython/ignored.tsv6
4 files changed, 24 insertions, 1 deletions
diff --git a/Python/import.c b/Python/import.c
index 9e1857d..24723d6 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -703,10 +703,19 @@ _PyImport_ClearModulesByIndex(PyInterpreterState *interp)
_PyRuntime.imports.pkgcontext, and PyModule_Create*() will
substitute this (if the name actually matches).
*/
+
+#ifdef HAVE_THREAD_LOCAL
+_Py_thread_local const char *pkgcontext = NULL;
+# undef PKGCONTEXT
+# define PKGCONTEXT pkgcontext
+#endif
+
const char *
_PyImport_ResolveNameWithPackageContext(const char *name)
{
+#ifndef HAVE_THREAD_LOCAL
PyThread_acquire_lock(EXTENSIONS.mutex, WAIT_LOCK);
+#endif
if (PKGCONTEXT != NULL) {
const char *p = strrchr(PKGCONTEXT, '.');
if (p != NULL && strcmp(name, p+1) == 0) {
@@ -714,17 +723,23 @@ _PyImport_ResolveNameWithPackageContext(const char *name)
PKGCONTEXT = NULL;
}
}
+#ifndef HAVE_THREAD_LOCAL
PyThread_release_lock(EXTENSIONS.mutex);
+#endif
return name;
}
const char *
_PyImport_SwapPackageContext(const char *newcontext)
{
+#ifndef HAVE_THREAD_LOCAL
PyThread_acquire_lock(EXTENSIONS.mutex, WAIT_LOCK);
+#endif
const char *oldcontext = PKGCONTEXT;
PKGCONTEXT = newcontext;
+#ifndef HAVE_THREAD_LOCAL
PyThread_release_lock(EXTENSIONS.mutex);
+#endif
return oldcontext;
}
diff --git a/Tools/c-analyzer/c_parser/parser/_regexes.py b/Tools/c-analyzer/c_parser/parser/_regexes.py
index b7f22b1..5695daf 100644
--- a/Tools/c-analyzer/c_parser/parser/_regexes.py
+++ b/Tools/c-analyzer/c_parser/parser/_regexes.py
@@ -58,6 +58,7 @@ _KEYWORD = textwrap.dedent(r'''
extern |
register |
static |
+ _Thread_local |
typedef |
const |
@@ -137,7 +138,7 @@ COMPOUND_TYPE_KIND = r'(?: \b (?: struct | union | enum ) \b )'
#######################################
# variable declarations
-_STORAGE = 'auto register static extern'.split()
+_STORAGE = 'auto register static extern _Thread_local'.split()
STORAGE_CLASS = rf'(?: \b (?: {" | ".join(_STORAGE)} ) \b )'
TYPE_QUALIFIER = r'(?: \b (?: const | volatile ) \b )'
PTR_QUALIFIER = rf'(?: [*] (?: \s* {TYPE_QUALIFIER} )? )'
diff --git a/Tools/c-analyzer/c_parser/preprocessor/gcc.py b/Tools/c-analyzer/c_parser/preprocessor/gcc.py
index c680f35..1476157 100644
--- a/Tools/c-analyzer/c_parser/preprocessor/gcc.py
+++ b/Tools/c-analyzer/c_parser/preprocessor/gcc.py
@@ -219,6 +219,7 @@ def _strip_directives(line, partial=0):
line = line[m.end():]
line = re.sub(r'__extension__', '', line)
+ line = re.sub(r'__thread\b', '_Thread_local', line)
while (m := COMPILER_DIRECTIVE_RE.match(line)):
before, _, _, closed = m.groups()
diff --git a/Tools/c-analyzer/cpython/ignored.tsv b/Tools/c-analyzer/cpython/ignored.tsv
index b6745b6..afc28e5 100644
--- a/Tools/c-analyzer/cpython/ignored.tsv
+++ b/Tools/c-analyzer/cpython/ignored.tsv
@@ -169,6 +169,12 @@ Modules/_xxinterpchannelsmodule.c - _globals -
Python/pyfpe.c - PyFPE_counter -
##-----------------------
+## thread-local variables
+
+Python/import.c - pkgcontext -
+Python/pystate.c - _Py_tss_tstate -
+
+##-----------------------
## should be const
# XXX Make them const.