mirror of
https://github.com/python/cpython.git
synced 2025-12-31 04:23:37 +00:00
gh-127582: Make object resurrection thread-safe for free threading. (GH-127612)
Objects may be temporarily "resurrected" in destructors when calling finalizers or watcher callbacks. We previously undid the resurrection by decrementing the reference count using `Py_SET_REFCNT`. This was not thread-safe because other threads might be accessing the object (modifying its reference count) if it was exposed by the finalizer, watcher callback, or temporarily accessed by a racy dictionary or list access. This adds internal-only thread-safe functions for temporary object resurrection during destructors.
This commit is contained in:
parent
657d0e99aa
commit
f4f530804b
6 changed files with 87 additions and 20 deletions
|
|
@ -3162,14 +3162,11 @@ dict_dealloc(PyObject *self)
|
|||
{
|
||||
PyDictObject *mp = (PyDictObject *)self;
|
||||
PyInterpreterState *interp = _PyInterpreterState_GET();
|
||||
assert(Py_REFCNT(mp) == 0);
|
||||
Py_SET_REFCNT(mp, 1);
|
||||
_PyObject_ResurrectStart(self);
|
||||
_PyDict_NotifyEvent(interp, PyDict_EVENT_DEALLOCATED, mp, NULL, NULL);
|
||||
if (Py_REFCNT(mp) > 1) {
|
||||
Py_SET_REFCNT(mp, Py_REFCNT(mp) - 1);
|
||||
if (_PyObject_ResurrectEnd(self)) {
|
||||
return;
|
||||
}
|
||||
Py_SET_REFCNT(mp, 0);
|
||||
PyDictValues *values = mp->ma_values;
|
||||
PyDictKeysObject *keys = mp->ma_keys;
|
||||
Py_ssize_t i, n;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue