]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-114271: Make `PyInterpreterState.threads.count` thread-safe in free-threaded build...
authormpage <mpage@meta.com>
Mon, 12 Feb 2024 17:44:00 +0000 (09:44 -0800)
committerGitHub <noreply@github.com>
Mon, 12 Feb 2024 17:44:00 +0000 (10:44 -0700)
Use atomics to mutate PyInterpreterState.threads.count.

Include/internal/pycore_interp.h
Modules/_threadmodule.c

index 31d88071e19d0cf22ab28940040bae85c9bf3598..485b1914a448854d36429c60b313b64f37332f4d 100644 (file)
@@ -112,7 +112,7 @@ struct _is {
         /* The thread currently executing in the __main__ module, if any. */
         PyThreadState *main;
         /* Used in Modules/_threadmodule.c. */
-        long count;
+        Py_ssize_t count;
         /* Support for runtime thread stack size tuning.
            A value of 0 means using the platform's default stack size
            or the size specified by the THREAD_STACK_SIZE macro. */
index df02b023012fbde3e63d983a704dc3a290d78a2c..d7840eaf45e8d69445bce94b5d59370063e94c65 100644 (file)
@@ -1244,7 +1244,7 @@ thread_run(void *boot_raw)
 
     _PyThreadState_Bind(tstate);
     PyEval_AcquireThread(tstate);
-    tstate->interp->threads.count++;
+    _Py_atomic_add_ssize(&tstate->interp->threads.count, 1);
 
     PyObject *res = PyObject_Call(boot->func, boot->args, boot->kwargs);
     if (res == NULL) {
@@ -1262,7 +1262,7 @@ thread_run(void *boot_raw)
 
     thread_bootstate_free(boot, 1);
 
-    tstate->interp->threads.count--;
+    _Py_atomic_add_ssize(&tstate->interp->threads.count, -1);
     PyThreadState_Clear(tstate);
     _PyThreadState_DeleteCurrent(tstate);
 
@@ -1539,7 +1539,7 @@ static PyObject *
 thread__count(PyObject *self, PyObject *Py_UNUSED(ignored))
 {
     PyInterpreterState *interp = _PyInterpreterState_GET();
-    return PyLong_FromLong(interp->threads.count);
+    return PyLong_FromSsize_t(_Py_atomic_load_ssize(&interp->threads.count));
 }
 
 PyDoc_STRVAR(_count_doc,