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
Lines changed: 2 additions & 0 deletions
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

Lines changed: 9 additions & 0 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy