gh-117323: Make cell thread-safe in free-threaded builds (#117330)

Use critical sections to lock around accesses to cell contents. The critical sections are no-ops in the default (with GIL) build.
This commit is contained in:
Sam Gross 2024-03-29 13:35:43 -04:00 committed by GitHub
parent 397d88db5e
commit 19c1dd60c5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 83 additions and 43 deletions

View file

@ -2320,14 +2320,13 @@
next_instr += 1;
INSTRUCTION_STATS(DELETE_DEREF);
PyObject *cell = GETLOCAL(oparg);
PyObject *oldobj = PyCell_GET(cell);
// Can't use ERROR_IF here.
// Fortunately we don't need its superpower.
PyObject *oldobj = PyCell_SwapTakeRef((PyCellObject *)cell, NULL);
if (oldobj == NULL) {
_PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg);
goto error;
}
PyCell_SET(cell, NULL);
Py_DECREF(oldobj);
DISPATCH();
}
@ -4096,13 +4095,12 @@
next_instr += 1;
INSTRUCTION_STATS(LOAD_DEREF);
PyObject *value;
PyObject *cell = GETLOCAL(oparg);
value = PyCell_GET(cell);
PyCellObject *cell = (PyCellObject *)GETLOCAL(oparg);
value = PyCell_GetRef(cell);
if (value == NULL) {
_PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg);
if (true) goto error;
}
Py_INCREF(value);
stack_pointer[0] = value;
stack_pointer += 1;
DISPATCH();
@ -4186,13 +4184,12 @@
goto error;
}
if (!value) {
PyObject *cell = GETLOCAL(oparg);
value = PyCell_GET(cell);
PyCellObject *cell = (PyCellObject *)GETLOCAL(oparg);
value = PyCell_GetRef(cell);
if (value == NULL) {
_PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg);
goto error;
}
Py_INCREF(value);
}
Py_DECREF(class_dict);
stack_pointer[-1] = value;
@ -5436,10 +5433,8 @@
INSTRUCTION_STATS(STORE_DEREF);
PyObject *v;
v = stack_pointer[-1];
PyObject *cell = GETLOCAL(oparg);
PyObject *oldobj = PyCell_GET(cell);
PyCell_SET(cell, v);
Py_XDECREF(oldobj);
PyCellObject *cell = (PyCellObject *)GETLOCAL(oparg);
PyCell_SetTakeRef(cell, v);
stack_pointer += -1;
DISPATCH();
}