diff options
author | Sam Gross <colesbury@gmail.com> | 2024-03-29 17:35:43 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-29 17:35:43 (GMT) |
commit | 19c1dd60c5b53fb0533610ad139ef591294f26e8 (patch) | |
tree | f76436f1512efe26885b65c49585a761a1658e82 /Include/internal | |
parent | 397d88db5e9ab2a43de3fdf5f8b973a949edc405 (diff) | |
download | cpython-19c1dd60c5b53fb0533610ad139ef591294f26e8.zip cpython-19c1dd60c5b53fb0533610ad139ef591294f26e8.tar.gz cpython-19c1dd60c5b53fb0533610ad139ef591294f26e8.tar.bz2 |
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.
Diffstat (limited to 'Include/internal')
-rw-r--r-- | Include/internal/pycore_cell.h | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/Include/internal/pycore_cell.h b/Include/internal/pycore_cell.h new file mode 100644 index 0000000..27f67d5 --- /dev/null +++ b/Include/internal/pycore_cell.h @@ -0,0 +1,48 @@ +#ifndef Py_INTERNAL_CELL_H +#define Py_INTERNAL_CELL_H + +#include "pycore_critical_section.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +// Sets the cell contents to `value` and return previous contents. Steals a +// reference to `value`. +static inline PyObject * +PyCell_SwapTakeRef(PyCellObject *cell, PyObject *value) +{ + PyObject *old_value; + Py_BEGIN_CRITICAL_SECTION(cell); + old_value = cell->ob_ref; + cell->ob_ref = value; + Py_END_CRITICAL_SECTION(); + return old_value; +} + +static inline void +PyCell_SetTakeRef(PyCellObject *cell, PyObject *value) +{ + PyObject *old_value = PyCell_SwapTakeRef(cell, value); + Py_XDECREF(old_value); +} + +// Gets the cell contents. Returns a new reference. +static inline PyObject * +PyCell_GetRef(PyCellObject *cell) +{ + PyObject *res; + Py_BEGIN_CRITICAL_SECTION(cell); + res = Py_XNewRef(cell->ob_ref); + Py_END_CRITICAL_SECTION(); + return res; +} + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_CELL_H */ |