https://github.com/python/cpython/commit/5468d219df65d4fe3335e2bcc09d2f6032a32c70
commit: 5468d219df65d4fe3335e2bcc09d2f6032a32c70
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: colesbury <[email protected]>
date: 2024-11-22T14:51:40Z
summary:

[3.13] gh-127065: Make `methodcaller` thread-safe in free threading build 
(GH-127109) (GH-127150)

The `methodcaller` C vectorcall implementation uses an arguments array
that is shared across calls. The first argument is modified on every
invocation. This isn't thread-safe in the free threading build. I think
it's also not safe in general, but for now just disable it in the free
threading build.
(cherry picked from commit f83ca6962af973fff6a3124f4bd3d45fea4dd5b8)

Co-authored-by: Sam Gross <[email protected]>

files:
A Misc/NEWS.d/next/Library/2024-11-21-16-23-16.gh-issue-127065.cfL1zd.rst
M Modules/_operator.c

diff --git 
a/Misc/NEWS.d/next/Library/2024-11-21-16-23-16.gh-issue-127065.cfL1zd.rst 
b/Misc/NEWS.d/next/Library/2024-11-21-16-23-16.gh-issue-127065.cfL1zd.rst
new file mode 100644
index 00000000000000..83457da467ffa9
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-11-21-16-23-16.gh-issue-127065.cfL1zd.rst
@@ -0,0 +1,2 @@
+Fix crash when calling a :func:`operator.methodcaller` instance from
+multiple threads in the free threading build.
diff --git a/Modules/_operator.c b/Modules/_operator.c
index 793a2d0dfc6443..261b5cf64a4a03 100644
--- a/Modules/_operator.c
+++ b/Modules/_operator.c
@@ -1572,6 +1572,7 @@ typedef struct {
     vectorcallfunc vectorcall;
 } methodcallerobject;
 
+#ifndef Py_GIL_DISABLED
 static int _methodcaller_initialize_vectorcall(methodcallerobject* mc)
 {
     PyObject* args = mc->xargs;
@@ -1634,6 +1635,7 @@ methodcaller_vectorcall(
             (PyTuple_GET_SIZE(mc->xargs)) | PY_VECTORCALL_ARGUMENTS_OFFSET,
             mc->vectorcall_kwnames);
 }
+#endif
 
 
 /* AC 3.5: variable number of arguments, not currently support by AC */
@@ -1673,7 +1675,14 @@ methodcaller_new(PyTypeObject *type, PyObject *args, 
PyObject *kwds)
     mc->vectorcall_args = 0;
 
 
+#ifdef Py_GIL_DISABLED
+    // gh-127065: The current implementation of methodcaller_vectorcall
+    // is not thread-safe because it modifies the `vectorcall_args` array,
+    // which is shared across calls.
+    mc->vectorcall = NULL;
+#else
     mc->vectorcall = (vectorcallfunc)methodcaller_vectorcall;
+#endif
 
     PyObject_GC_Track(mc);
     return (PyObject *)mc;

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to