summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2024-06-18 14:54:51 (GMT)
committerGitHub <noreply@github.com>2024-06-18 14:54:51 (GMT)
commit1ce59849610fe03beebcddfacb3d055a7074ef16 (patch)
tree1000c3c2e89c99a3a77dd19fa640f2ebc4998cc1 /Objects
parent4f4973d740839757e888c854a1994a64cb900d7b (diff)
downloadcpython-1ce59849610fe03beebcddfacb3d055a7074ef16.zip
cpython-1ce59849610fe03beebcddfacb3d055a7074ef16.tar.gz
cpython-1ce59849610fe03beebcddfacb3d055a7074ef16.tar.bz2
[3.13] gh-118789: Add `PyUnstable_Object_ClearWeakRefsNoCallbacks` (GH-118807) (#120695)
This exposes `PyUnstable_Object_ClearWeakRefsNoCallbacks` as an unstable C-API function to provide a thread-safe mechanism for clearing weakrefs without executing callbacks. Some C-API extensions need to clear weakrefs without calling callbacks, such as after running finalizers like we do in subtype_dealloc. Previously they could use `_PyWeakref_ClearRef` on each weakref, but that's not thread-safe in the free-threaded build. (cherry picked from commit e8752d7b80775ec2a348cd4bf38cbe26a4a07615) Co-authored-by: Sam Gross <colesbury@gmail.com> Co-authored-by: Petr Viktorin <encukou@gmail.com>
Diffstat (limited to 'Objects')
-rw-r--r--Objects/typeobject.c2
-rw-r--r--Objects/weakrefobject.c12
2 files changed, 11 insertions, 3 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 5c490e8..5bf2bc2 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -2369,7 +2369,7 @@ subtype_dealloc(PyObject *self)
finalizers since they might rely on part of the object
being finalized that has already been destroyed. */
if (type->tp_weaklistoffset && !base->tp_weaklistoffset) {
- _PyWeakref_ClearWeakRefsExceptCallbacks(self);
+ _PyWeakref_ClearWeakRefsNoCallbacks(self);
}
}
diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c
index 3b027e1..0fcd37d 100644
--- a/Objects/weakrefobject.c
+++ b/Objects/weakrefobject.c
@@ -1016,7 +1016,7 @@ PyObject_ClearWeakRefs(PyObject *object)
PyObject *exc = PyErr_GetRaisedException();
PyObject *tuple = PyTuple_New(num_weakrefs * 2);
if (tuple == NULL) {
- _PyWeakref_ClearWeakRefsExceptCallbacks(object);
+ _PyWeakref_ClearWeakRefsNoCallbacks(object);
PyErr_WriteUnraisable(NULL);
PyErr_SetRaisedException(exc);
return;
@@ -1057,6 +1057,14 @@ PyObject_ClearWeakRefs(PyObject *object)
PyErr_SetRaisedException(exc);
}
+void
+PyUnstable_Object_ClearWeakRefsNoCallbacks(PyObject *obj)
+{
+ if (_PyType_SUPPORTS_WEAKREFS(Py_TYPE(obj))) {
+ _PyWeakref_ClearWeakRefsNoCallbacks(obj);
+ }
+}
+
/* This function is called by _PyStaticType_Dealloc() to clear weak references.
*
* This is called at the end of runtime finalization, so we can just
@@ -1076,7 +1084,7 @@ _PyStaticType_ClearWeakRefs(PyInterpreterState *interp, PyTypeObject *type)
}
void
-_PyWeakref_ClearWeakRefsExceptCallbacks(PyObject *obj)
+_PyWeakref_ClearWeakRefsNoCallbacks(PyObject *obj)
{
/* Modeled after GET_WEAKREFS_LISTPTR().