summaryrefslogtreecommitdiffstats
path: root/Include/internal
diff options
context:
space:
mode:
authorSam Gross <colesbury@gmail.com>2024-03-29 17:35:43 (GMT)
committerGitHub <noreply@github.com>2024-03-29 17:35:43 (GMT)
commit19c1dd60c5b53fb0533610ad139ef591294f26e8 (patch)
treef76436f1512efe26885b65c49585a761a1658e82 /Include/internal
parent397d88db5e9ab2a43de3fdf5f8b973a949edc405 (diff)
downloadcpython-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.h48
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 */