8000 gh-111926: Update _weakref to be threadsafe in --disable-gil build (g… · python/cpython@0566ab9 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0566ab9

Browse files
authored
gh-111926: Update _weakref to be threadsafe in --disable-gil build (gh-112189)
1 parent eb3c94e commit 0566ab9

File tree

1 file changed

+20
-9
lines changed

1 file changed

+20
-9
lines changed

Modules/_weakref.c

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#include "Python.h"
2-
#include "pycore_dict.h" // _PyDict_DelItemIf()
3-
#include "pycore_object.h" // _PyObject_GET_WEAKREFS_LISTPTR
4-
#include "pycore_weakref.h" // _PyWeakref_IS_DEAD()
5-
2+
#include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION()
3+
#include "pycore_dict.h" // _PyDict_DelItemIf()
4+
#include "pycore_object.h" // _PyObject_GET_WEAKREFS_LISTPTR()
5+
#include "pycore_weakref.h" // _PyWeakref_IS_DEAD()
66

77
#define GET_WEAKREFS_LISTPTR(o) \
88
((PyWeakReference **) _PyObject_GET_WEAKREFS_LISTPTR(o))
@@ -32,9 +32,12 @@ _weakref_getweakrefcount_impl(PyObject *module, PyObject *object)
3232

3333
if (!_PyType_SUPPORTS_WEAKREFS(Py_TYPE(object)))
3434
return 0;
35-
35+
Py_ssize_t count;
36+
Py_BEGIN_CRITICAL_SECTION(object);
3637
list = GET_WEAKREFS_LISTPTR(object);
37-
return _PyWeakref_GetWeakrefCount(*list);
38+
count = _PyWeakref_GetWeakrefCount(*list);
39+
Py_END_CRITICAL_SECTION();
40+
return count;
3841
}
3942

4043

@@ -45,7 +48,11 @@ is_dead_weakref(PyObject *value)
4548
PyErr_SetString(PyExc_TypeError, "not a weakref");
4649
return -1;
4750
}
48-
return _PyWeakref_IS_DEAD(value);
51+
int is_dead;
52+
Py_BEGIN_CRITICAL_SECTION(value);
53+
is_dead = _PyWeakref_IS_DEAD(value);
54+
Py_END_CRITICAL_SECTION();
55+
return is_dead;
4956
}
5057

5158
/*[clinic input]
@@ -94,19 +101,23 @@ _weakref_getweakrefs(PyObject *module, PyObject *object)
94101
return PyList_New(0);
95102
}
96103

104+
PyObject *result;
105+
Py_BEGIN_CRITICAL_SECTION(object);
97106
PyWeakReference **list = GET_WEAKREFS_LISTPTR(object);
98107
Py_ssize_t count = _PyWeakref_GetWeakrefCount(*list);
99108

100-
PyObject *result = PyList_New(count);
109+
result = PyList_New(count);
101110
if (result == NULL) {
102-
return NULL;
111+
goto exit;
103112
}
104113

105114
PyWeakReference *current = *list;
106115
for (Py_ssize_t i = 0; i < count; ++i) {
107116
PyList_SET_ITEM(result, i, Py_NewRef(current));
108117
current = current->wr_next;
109118
}
119+
exit:
120+
Py_END_CRITICAL_SECTION();
110121
return result;
111122
}
112123

0 commit comments

Comments
 (0)
0