Skip to content

Commit 5468d21

Browse files
[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 f83ca69) Co-authored-by: Sam Gross <colesbury@gmail.com>
1 parent 1b58c0f commit 5468d21

File tree

2 files changed

+11
-0
lines changed

2 files changed

+11
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix crash when calling a :func:`operator.methodcaller` instance from
2+
multiple threads in the free threading build.

Modules/_operator.c

+9
Original file line numberDiff line numberDiff line change
@@ -1572,6 +1572,7 @@ typedef struct {
15721572
vectorcallfunc vectorcall;
15731573
} methodcallerobject;
15741574

1575+
#ifndef Py_GIL_DISABLED
15751576
static int _methodcaller_initialize_vectorcall(methodcallerobject* mc)
15761577
{
15771578
PyObject* args = mc->xargs;
@@ -1634,6 +1635,7 @@ methodcaller_vectorcall(
16341635
(PyTuple_GET_SIZE(mc->xargs)) | PY_VECTORCALL_ARGUMENTS_OFFSET,
16351636
mc->vectorcall_kwnames);
16361637
}
1638+
#endif
16371639

16381640

16391641
/* AC 3.5: variable number of arguments, not currently support by AC */
@@ -1673,7 +1675,14 @@ methodcaller_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
16731675
mc->vectorcall_args = 0;
16741676

16751677

1678+
#ifdef Py_GIL_DISABLED
1679+
// gh-127065: The current implementation of methodcaller_vectorcall
1680+
// is not thread-safe because it modifies the `vectorcall_args` array,
1681+
// which is shared across calls.
1682+
mc->vectorcall = NULL;
1683+
#else
16761684
mc->vectorcall = (vectorcallfunc)methodcaller_vectorcall;
1685+
#endif
16771686

16781687
PyObject_GC_Track(mc);
16791688
return (PyObject *)mc;

0 commit comments

Comments
 (0)