summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorBrett Simmers <swtaarrs@users.noreply.github.com>2024-04-11 22:13:25 (GMT)
committerGitHub <noreply@github.com>2024-04-11 22:13:25 (GMT)
commitf268e328ed5d7b2df5bdad39691f6e4789a2fcde (patch)
tree6bfa86ec050523a36fcbe1fbf624e48bcbad4896 /Objects
parent1b10efad66e9a0b72aae82de23074eafa49ec4db (diff)
downloadcpython-f268e328ed5d7b2df5bdad39691f6e4789a2fcde.zip
cpython-f268e328ed5d7b2df5bdad39691f6e4789a2fcde.tar.gz
cpython-f268e328ed5d7b2df5bdad39691f6e4789a2fcde.tar.bz2
gh-116738: Make _abc module thread-safe (#117488)
A collection of small changes aimed at making the `_abc` module safe to use in a free-threaded build.
Diffstat (limited to 'Objects')
-rw-r--r--Objects/typeobject.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index e9f2d25..3f38abf 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -5117,6 +5117,52 @@ _PyType_LookupId(PyTypeObject *type, _Py_Identifier *name)
return _PyType_Lookup(type, oname);
}
+static void
+set_flags(PyTypeObject *self, unsigned long mask, unsigned long flags)
+{
+ ASSERT_TYPE_LOCK_HELD();
+ self->tp_flags = (self->tp_flags & ~mask) | flags;
+}
+
+void
+_PyType_SetFlags(PyTypeObject *self, unsigned long mask, unsigned long flags)
+{
+ BEGIN_TYPE_LOCK();
+ set_flags(self, mask, flags);
+ END_TYPE_LOCK();
+}
+
+static void
+set_flags_recursive(PyTypeObject *self, unsigned long mask, unsigned long flags)
+{
+ if (PyType_HasFeature(self, Py_TPFLAGS_IMMUTABLETYPE) ||
+ (self->tp_flags & mask) == flags)
+ {
+ return;
+ }
+
+ set_flags(self, mask, flags);
+
+ PyObject *children = _PyType_GetSubclasses(self);
+ if (children == NULL) {
+ return;
+ }
+
+ for (Py_ssize_t i = 0; i < PyList_GET_SIZE(children); i++) {
+ PyObject *child = PyList_GET_ITEM(children, i);
+ set_flags_recursive((PyTypeObject *)child, mask, flags);
+ }
+ Py_DECREF(children);
+}
+
+void
+_PyType_SetFlagsRecursive(PyTypeObject *self, unsigned long mask, unsigned long flags)
+{
+ BEGIN_TYPE_LOCK();
+ set_flags_recursive(self, mask, flags);
+ END_TYPE_LOCK();
+}
+
/* This is similar to PyObject_GenericGetAttr(),
but uses _PyType_Lookup() instead of just looking in type->tp_dict.