]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-111926: Update _PyWeakref_IS_DEAD to be thread-safe (gh-112267)
authorDonghee Na <donghee.na@python.org>
Sun, 19 Nov 2023 22:36:45 +0000 (22:36 +0000)
committerGitHub <noreply@github.com>
Sun, 19 Nov 2023 22:36:45 +0000 (07:36 +0900)
Include/internal/pycore_weakref.h

index 51b2bb6b11ede96422000aae34da045c636329e0..eacbe14c903289017ee49f36cb062365a0838d48 100644 (file)
@@ -8,6 +8,8 @@ extern "C" {
 #  error "this header requires Py_BUILD_CORE define"
 #endif
 
+#include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION()
+
 static inline PyObject* _PyWeakref_GET_REF(PyObject *ref_obj) {
     assert(PyWeakref_Check(ref_obj));
     PyWeakReference *ref = _Py_CAST(PyWeakReference*, ref_obj);
@@ -35,15 +37,20 @@ static inline PyObject* _PyWeakref_GET_REF(PyObject *ref_obj) {
 
 static inline int _PyWeakref_IS_DEAD(PyObject *ref_obj) {
     assert(PyWeakref_Check(ref_obj));
+    int is_dead;
+    Py_BEGIN_CRITICAL_SECTION(ref_obj);
     PyWeakReference *ref = _Py_CAST(PyWeakReference*, ref_obj);
     PyObject *obj = ref->wr_object;
     if (obj == Py_None) {
         // clear_weakref() was called
-        return 1;
+        is_dead = 1;
     }
-
-    // See _PyWeakref_GET_REF() for the rationale of this test
-    return (Py_REFCNT(obj) == 0);
+    else {
+        // See _PyWeakref_GET_REF() for the rationale of this test
+        is_dead = (Py_REFCNT(obj) == 0);
+    }
+    Py_END_CRITICAL_SECTION();
+    return is_dead;
 }
 
 extern Py_ssize_t _PyWeakref_GetWeakrefCount(PyWeakReference *head);