| #ifndef Py_INTERNAL_CELL_H |
| #define Py_INTERNAL_CELL_H |
| |
| #include "pycore_critical_section.h" |
| #include "pycore_object.h" |
| #include "pycore_stackref.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; |
| FT_ATOMIC_STORE_PTR_RELEASE(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); |
| #ifdef Py_GIL_DISABLED |
| res = _Py_XNewRefWithLock(cell->ob_ref); |
| #else |
| res = Py_XNewRef(cell->ob_ref); |
| #endif |
| Py_END_CRITICAL_SECTION(); |
| return res; |
| } |
| |
| static inline _PyStackRef |
| _PyCell_GetStackRef(PyCellObject *cell) |
| { |
| PyObject *value; |
| #ifdef Py_GIL_DISABLED |
| value = _Py_atomic_load_ptr(&cell->ob_ref); |
| if (value == NULL) { |
| return PyStackRef_NULL; |
| } |
| _PyStackRef ref; |
| if (_Py_TryIncrefCompareStackRef(&cell->ob_ref, value, &ref)) { |
| return ref; |
| } |
| #endif |
| value = PyCell_GetRef(cell); |
| if (value == NULL) { |
| return PyStackRef_NULL; |
| } |
| return PyStackRef_FromPyObjectSteal(value); |
| } |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| #endif /* !Py_INTERNAL_CELL_H */ |