summaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/Modules/_weakref.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/tools/python3/Modules/_weakref.c')
-rw-r--r--contrib/tools/python3/Modules/_weakref.c88
1 files changed, 39 insertions, 49 deletions
diff --git a/contrib/tools/python3/Modules/_weakref.c b/contrib/tools/python3/Modules/_weakref.c
index 387b8fa9d0a..ecaa08ff60f 100644
--- a/contrib/tools/python3/Modules/_weakref.c
+++ b/contrib/tools/python3/Modules/_weakref.c
@@ -1,6 +1,7 @@
#include "Python.h"
-#include "pycore_object.h" // _PyObject_GET_WEAKREFS_LISTPTR
-
+#include "pycore_dict.h" // _PyDict_DelItemIf()
+#include "pycore_object.h" // _PyObject_GET_WEAKREFS_LISTPTR()
+#include "pycore_weakref.h" // _PyWeakref_IS_DEAD()
#define GET_WEAKREFS_LISTPTR(o) \
((PyWeakReference **) _PyObject_GET_WEAKREFS_LISTPTR(o))
@@ -13,7 +14,6 @@ module _weakref
#include "clinic/_weakref.c.h"
/*[clinic input]
-
_weakref.getweakrefcount -> Py_ssize_t
object: object
@@ -24,26 +24,20 @@ Return the number of weak references to 'object'.
static Py_ssize_t
_weakref_getweakrefcount_impl(PyObject *module, PyObject *object)
-/*[clinic end generated code: output=301806d59558ff3e input=cedb69711b6a2507]*/
+/*[clinic end generated code: output=301806d59558ff3e input=7d4d04fcaccf64d5]*/
{
- PyWeakReference **list;
-
- if (!_PyType_SUPPORTS_WEAKREFS(Py_TYPE(object)))
- return 0;
-
- list = GET_WEAKREFS_LISTPTR(object);
- return _PyWeakref_GetWeakrefCount(*list);
+ return _PyWeakref_GetWeakrefCount(object);
}
static int
-is_dead_weakref(PyObject *value)
+is_dead_weakref(PyObject *value, void *unused)
{
if (!PyWeakref_Check(value)) {
PyErr_SetString(PyExc_TypeError, "not a weakref");
return -1;
}
- return PyWeakref_GET_OBJECT(value) == Py_None;
+ return _PyWeakref_IS_DEAD(value);
}
/*[clinic input]
@@ -62,15 +56,8 @@ _weakref__remove_dead_weakref_impl(PyObject *module, PyObject *dct,
PyObject *key)
/*[clinic end generated code: output=d9ff53061fcb875c input=19fc91f257f96a1d]*/
{
- if (_PyDict_DelItemIf(dct, key, is_dead_weakref) < 0) {
- if (PyErr_ExceptionMatches(PyExc_KeyError))
- /* This function is meant to allow safe weak-value dicts
- with GC in another thread (see issue #28427), so it's
- ok if the key doesn't exist anymore.
- */
- PyErr_Clear();
- else
- return NULL;
+ if (_PyDict_DelItemIf(dct, key, is_dead_weakref, NULL) < 0) {
+ return NULL;
}
Py_RETURN_NONE;
}
@@ -88,26 +75,36 @@ static PyObject *
_weakref_getweakrefs(PyObject *module, PyObject *object)
/*[clinic end generated code: output=25c7731d8e011824 input=00c6d0e5d3206693]*/
{
- PyObject *result = NULL;
+ if (!_PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))) {
+ return PyList_New(0);
+ }
- if (_PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))) {
- PyWeakReference **list = GET_WEAKREFS_LISTPTR(object);
- Py_ssize_t count = _PyWeakref_GetWeakrefCount(*list);
+ PyObject *result = PyList_New(0);
+ if (result == NULL) {
+ return NULL;
+ }
- result = PyList_New(count);
- if (result != NULL) {
- PyWeakReference *current = *list;
- Py_ssize_t i;
- for (i = 0; i < count; ++i) {
- PyList_SET_ITEM(result, i, (PyObject *) current);
- Py_INCREF(current);
- current = current->wr_next;
+ LOCK_WEAKREFS(object);
+ PyWeakReference *current = *GET_WEAKREFS_LISTPTR(object);
+ while (current != NULL) {
+ PyObject *curobj = (PyObject *) current;
+ if (_Py_TryIncref(curobj)) {
+ if (PyList_Append(result, curobj)) {
+ UNLOCK_WEAKREFS(object);
+ Py_DECREF(curobj);
+ Py_DECREF(result);
+ return NULL;
+ }
+ else {
+ // Undo our _Py_TryIncref. This is safe to do with the lock
+ // held in free-threaded builds; the list holds a reference to
+ // curobj so we're guaranteed not to invoke the destructor.
+ Py_DECREF(curobj);
}
}
+ current = current->wr_next;
}
- else {
- result = PyList_New(0);
- }
+ UNLOCK_WEAKREFS(object);
return result;
}
@@ -145,27 +142,19 @@ weakref_functions[] = {
static int
weakref_exec(PyObject *module)
{
- Py_INCREF(&_PyWeakref_RefType);
- if (PyModule_AddObject(module, "ref", (PyObject *) &_PyWeakref_RefType) < 0) {
- Py_DECREF(&_PyWeakref_RefType);
+ if (PyModule_AddObjectRef(module, "ref", (PyObject *) &_PyWeakref_RefType) < 0) {
return -1;
}
- Py_INCREF(&_PyWeakref_RefType);
- if (PyModule_AddObject(module, "ReferenceType",
+ if (PyModule_AddObjectRef(module, "ReferenceType",
(PyObject *) &_PyWeakref_RefType) < 0) {
- Py_DECREF(&_PyWeakref_RefType);
return -1;
}
- Py_INCREF(&_PyWeakref_ProxyType);
- if (PyModule_AddObject(module, "ProxyType",
+ if (PyModule_AddObjectRef(module, "ProxyType",
(PyObject *) &_PyWeakref_ProxyType) < 0) {
- Py_DECREF(&_PyWeakref_ProxyType);
return -1;
}
- Py_INCREF(&_PyWeakref_CallableProxyType);
- if (PyModule_AddObject(module, "CallableProxyType",
+ if (PyModule_AddObjectRef(module, "CallableProxyType",
(PyObject *) &_PyWeakref_CallableProxyType) < 0) {
- Py_DECREF(&_PyWeakref_CallableProxyType);
return -1;
}
@@ -175,6 +164,7 @@ weakref_exec(PyObject *module)
static struct PyModuleDef_Slot weakref_slots[] = {
{Py_mod_exec, weakref_exec},
{Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
+ {Py_mod_gil, Py_MOD_GIL_NOT_USED},
{0, NULL}
};