summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2023-06-21 13:44:25 (GMT)
committerGitHub <noreply@github.com>2023-06-21 13:44:25 (GMT)
commitfb1e691e4bc7757c11bf9e51dda675f15537db8c (patch)
tree6bc8c40a35e6ccbc6c0f97f628a771b8df73f97a /Modules
parenteaa670228066220f08c8d73f80365c50058d40b8 (diff)
downloadcpython-fb1e691e4bc7757c11bf9e51dda675f15537db8c.zip
cpython-fb1e691e4bc7757c11bf9e51dda675f15537db8c.tar.gz
cpython-fb1e691e4bc7757c11bf9e51dda675f15537db8c.tar.bz2
gh-105927: _abc and _thread use PyWeakref_GetRef() (#105961)
Hold a strong reference on the object, rather than using a borrowed reference: replace PyWeakref_GET_OBJECT() with PyWeakref_GetRef() and _PyWeakref_GET_REF(). Remove assert(PyWeakref_CheckRef(localweakref)) since it's already tested by _PyWeakref_GET_REF().
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_abc.c15
-rw-r--r--Modules/_threadmodule.c26
2 files changed, 20 insertions, 21 deletions
diff --git a/Modules/_abc.c b/Modules/_abc.c
index d3e405d..93c0a93 100644
--- a/Modules/_abc.c
+++ b/Modules/_abc.c
@@ -8,6 +8,7 @@
#include "pycore_object.h" // _PyType_GetSubclasses()
#include "pycore_runtime.h" // _Py_ID()
#include "pycore_typeobject.h" // _PyType_GetMRO()
+#include "pycore_weakref.h" // _PyWeakref_GET_REF()
#include "clinic/_abc.c.h"
/*[clinic input]
@@ -150,12 +151,10 @@ _in_weak_set(PyObject *set, PyObject *obj)
static PyObject *
_destroy(PyObject *setweakref, PyObject *objweakref)
{
- PyObject *set;
- set = PyWeakref_GET_OBJECT(setweakref);
- if (set == Py_None) {
+ PyObject *set = _PyWeakref_GET_REF(setweakref);
+ if (set == NULL) {
Py_RETURN_NONE;
}
- Py_INCREF(set);
if (PySet_Discard(set, objweakref) < 0) {
Py_DECREF(set);
return NULL;
@@ -843,16 +842,16 @@ subclasscheck_check_registry(_abc_data *impl, PyObject *subclass,
assert(i == registry_size);
for (i = 0; i < registry_size; i++) {
- PyObject *rkey = PyWeakref_GetObject(copy[i]);
- if (rkey == NULL) {
+ PyObject *rkey;
+ if (PyWeakref_GetRef(copy[i], &rkey) < 0) {
// Someone inject non-weakref type in the registry.
ret = -1;
break;
}
- if (rkey == Py_None) {
+
+ if (rkey == NULL) {
continue;
}
- Py_INCREF(rkey);
int r = PyObject_IsSubclass(subclass, rkey);
Py_DECREF(rkey);
if (r < 0) {
diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c
index c553d03..7f8b3cb 100644
--- a/Modules/_threadmodule.c
+++ b/Modules/_threadmodule.c
@@ -7,6 +7,7 @@
#include "pycore_moduleobject.h" // _PyModule_GetState()
#include "pycore_pylifecycle.h"
#include "pycore_pystate.h" // _PyThreadState_SetCurrent()
+#include "pycore_weakref.h" // _PyWeakref_GET_REF()
#include <stddef.h> // offsetof()
#include "structmember.h" // PyMemberDef
@@ -1024,15 +1025,13 @@ local_getattro(localobject *self, PyObject *name)
static PyObject *
_localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref)
{
- assert(PyWeakref_CheckRef(localweakref));
- PyObject *obj = PyWeakref_GET_OBJECT(localweakref);
- if (obj == Py_None) {
+ localobject *self = (localobject *)_PyWeakref_GET_REF(localweakref);
+ if (self == NULL) {
Py_RETURN_NONE;
}
/* If the thread-local object is still alive and not being cleared,
remove the corresponding local dict */
- localobject *self = (localobject *)Py_NewRef(obj);
if (self->dummies != NULL) {
PyObject *ldict;
ldict = PyDict_GetItemWithError(self->dummies, dummyweakref);
@@ -1040,9 +1039,9 @@ _localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref)
PyDict_DelItem(self->dummies, dummyweakref);
}
if (PyErr_Occurred())
- PyErr_WriteUnraisable(obj);
+ PyErr_WriteUnraisable((PyObject*)self);
}
- Py_DECREF(obj);
+ Py_DECREF(self);
Py_RETURN_NONE;
}
@@ -1314,24 +1313,25 @@ This function is meant for internal and specialized purposes only.\n\
In most applications `threading.enumerate()` should be used instead.");
static void
-release_sentinel(void *wr_raw)
+release_sentinel(void *weakref_raw)
{
- PyObject *wr = _PyObject_CAST(wr_raw);
+ PyObject *weakref = _PyObject_CAST(weakref_raw);
+
/* Tricky: this function is called when the current thread state
is being deleted. Therefore, only simple C code can safely
execute here. */
- PyObject *obj = PyWeakref_GET_OBJECT(wr);
- lockobject *lock;
- if (obj != Py_None) {
- lock = (lockobject *) obj;
+ lockobject *lock = (lockobject *)_PyWeakref_GET_REF(weakref);
+ if (lock != NULL) {
if (lock->locked) {
PyThread_release_lock(lock->lock_lock);
lock->locked = 0;
}
+ Py_DECREF(lock);
}
+
/* Deallocating a weakref with a NULL callback only calls
PyObject_GC_Del(), which can't call any Python code. */
- Py_DECREF(wr);
+ Py_DECREF(weakref);
}
static PyObject *