mirror of
https://github.com/python/cpython.git
synced 2026-06-19 08:02:29 +00:00
[3.14] gh-146270: Fix PyMember_SetOne(..., NULL) not being atomic (gh-148800) (#149460)
Fixes a sequential consistency bug whereby two threads that are deleting a struct member may observe both their deletions to be successful.
(cherry picked from commit 1bdfc0f253)
Co-authored-by: Daniele Parmeggiani <8658291+dpdani@users.noreply.github.com>
This commit is contained in:
parent
5b33e9c176
commit
8a7f0570e6
3 changed files with 41 additions and 21 deletions
|
|
@ -161,19 +161,10 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
|
|||
PyErr_SetString(PyExc_AttributeError, "readonly attribute");
|
||||
return -1;
|
||||
}
|
||||
if (v == NULL) {
|
||||
if (l->type == Py_T_OBJECT_EX) {
|
||||
/* Check if the attribute is set. */
|
||||
if (*(PyObject **)addr == NULL) {
|
||||
PyErr_SetString(PyExc_AttributeError, l->name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (l->type != _Py_T_OBJECT) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"can't delete numeric/char attribute");
|
||||
return -1;
|
||||
}
|
||||
if (v == NULL && l->type != Py_T_OBJECT_EX && l->type != _Py_T_OBJECT) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"can't delete numeric/char attribute");
|
||||
return -1;
|
||||
}
|
||||
switch (l->type) {
|
||||
case Py_T_BOOL:{
|
||||
|
|
@ -324,6 +315,15 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
|
|||
oldv = *(PyObject **)addr;
|
||||
FT_ATOMIC_STORE_PTR_RELEASE(*(PyObject **)addr, Py_XNewRef(v));
|
||||
Py_END_CRITICAL_SECTION();
|
||||
if (v == NULL && oldv == NULL && l->type == Py_T_OBJECT_EX) {
|
||||
// Raise an exception when attempting to delete an already deleted
|
||||
// attribute.
|
||||
// Differently from Py_T_OBJECT_EX, _Py_T_OBJECT does not raise an
|
||||
// exception here (PyMember_GetOne will return Py_None instead of
|
||||
// NULL).
|
||||
PyErr_SetString(PyExc_AttributeError, l->name);
|
||||
return -1;
|
||||
}
|
||||
Py_XDECREF(oldv);
|
||||
break;
|
||||
case Py_T_CHAR: {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue