summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDonghee Na <donghee.na@python.org>2023-11-19 22:36:45 (GMT)
committerGitHub <noreply@github.com>2023-11-19 22:36:45 (GMT)
commit7c9f2677fbb8805f7d531fb96731339727e8ea20 (patch)
tree4dbe6760bb21bc81ca872c9079285c3fbb127c65
parentf8129146ef9e1b71609ef4becc5d508061970733 (diff)
downloadcpython-7c9f2677fbb8805f7d531fb96731339727e8ea20.zip
cpython-7c9f2677fbb8805f7d531fb96731339727e8ea20.tar.gz
cpython-7c9f2677fbb8805f7d531fb96731339727e8ea20.tar.bz2
gh-111926: Update _PyWeakref_IS_DEAD to be thread-safe (gh-112267)
-rw-r--r--Include/internal/pycore_weakref.h15
1 files changed, 11 insertions, 4 deletions
diff --git a/Include/internal/pycore_weakref.h b/Include/internal/pycore_weakref.h
index 51b2bb6..eacbe14 100644
--- a/Include/internal/pycore_weakref.h
+++ b/Include/internal/pycore_weakref.h
@@ -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);