From 0566ab9c4d966c7280a1c02fdeea8129ba65de81 Mon Sep 17 00:00:00 2001 From: Donghee Na Date: Sat, 18 Nov 2023 07:09:23 +0000 Subject: [PATCH] gh-111926: Update _weakref to be threadsafe in --disable-gil build (gh-112189) --- Modules/_weakref.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/Modules/_weakref.c b/Modules/_weakref.c index 4e2862e7467c3d..90c7afcc248ff3 100644 --- a/Modules/_weakref.c +++ b/Modules/_weakref.c @@ -1,8 +1,8 @@ #include "Python.h" -#include "pycore_dict.h" // _PyDict_DelItemIf() -#include "pycore_object.h" // _PyObject_GET_WEAKREFS_LISTPTR -#include "pycore_weakref.h" // _PyWeakref_IS_DEAD() - +#include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION() +#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)) @@ -32,9 +32,12 @@ _weakref_getweakrefcount_impl(PyObject *module, PyObject *object) if (!_PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))) return 0; - + Py_ssize_t count; + Py_BEGIN_CRITICAL_SECTION(object); list = GET_WEAKREFS_LISTPTR(object); - return _PyWeakref_GetWeakrefCount(*list); + count = _PyWeakref_GetWeakrefCount(*list); + Py_END_CRITICAL_SECTION(); + return count; } @@ -45,7 +48,11 @@ is_dead_weakref(PyObject *value) PyErr_SetString(PyExc_TypeError, "not a weakref"); return -1; } - return _PyWeakref_IS_DEAD(value); + int is_dead; + Py_BEGIN_CRITICAL_SECTION(value); + is_dead = _PyWeakref_IS_DEAD(value); + Py_END_CRITICAL_SECTION(); + return is_dead; } /*[clinic input] @@ -94,12 +101,14 @@ _weakref_getweakrefs(PyObject *module, PyObject *object) return PyList_New(0); } + PyObject *result; + Py_BEGIN_CRITICAL_SECTION(object); PyWeakReference **list = GET_WEAKREFS_LISTPTR(object); Py_ssize_t count = _PyWeakref_GetWeakrefCount(*list); - PyObject *result = PyList_New(count); + result = PyList_New(count); if (result == NULL) { - return NULL; + goto exit; } PyWeakReference *current = *list; @@ -107,6 +116,8 @@ _weakref_getweakrefs(PyObject *module, PyObject *object) PyList_SET_ITEM(result, i, Py_NewRef(current)); current = current->wr_next; } +exit: + Py_END_CRITICAL_SECTION(); return result; }