mirror of https://github.com/python/cpython.git
76 lines
1.7 KiB
C
76 lines
1.7 KiB
C
#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 */
|