]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-111926: Update _weakref to be threadsafe in --disable-gil build (gh-112189)
authorDonghee Na <donghee.na@python.org>
Sat, 18 Nov 2023 07:09:23 +0000 (07:09 +0000)
committerGitHub <noreply@github.com>
Sat, 18 Nov 2023 07:09:23 +0000 (16:09 +0900)
Modules/_weakref.c

index 4e2862e7467c3d3cefe2933e3bb3c9dc235201f9..90c7afcc248ff35efaea87e8ebdcf8a65dec4f8d 100644 (file)
@@ -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;
 }