summaryrefslogtreecommitdiffstats
path: root/Include/internal
diff options
context:
space:
mode:
authorDino Viehland <dinoviehland@meta.com>2024-11-21 16:41:19 (GMT)
committerGitHub <noreply@github.com>2024-11-21 16:41:19 (GMT)
commitbf542f8bb9f12f0df9481f2222b21545806dd9e1 (patch)
tree41db15281aa5a0e25e63a46e80cbe50ef80cb7f6 /Include/internal
parent3926842117feffe5d2c9727e1899bea5ae2adb28 (diff)
downloadcpython-bf542f8bb9f12f0df9481f2222b21545806dd9e1.zip
cpython-bf542f8bb9f12f0df9481f2222b21545806dd9e1.tar.gz
cpython-bf542f8bb9f12f0df9481f2222b21545806dd9e1.tar.bz2
gh-124470: Fix crash when reading from object instance dictionary while replacing it (#122489)
Delay free a dictionary when replacing it
Diffstat (limited to 'Include/internal')
-rw-r--r--Include/internal/pycore_gc.h18
-rw-r--r--Include/internal/pycore_pymem.h16
2 files changed, 15 insertions, 19 deletions
diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h
index 38a1c56..479fe10 100644
--- a/Include/internal/pycore_gc.h
+++ b/Include/internal/pycore_gc.h
@@ -50,7 +50,6 @@ static inline PyObject* _Py_FROM_GC(PyGC_Head *gc) {
# define _PyGC_BITS_UNREACHABLE (4)
# define _PyGC_BITS_FROZEN (8)
# define _PyGC_BITS_SHARED (16)
-# define _PyGC_BITS_SHARED_INLINE (32)
# define _PyGC_BITS_DEFERRED (64) // Use deferred reference counting
#endif
@@ -119,23 +118,6 @@ static inline void _PyObject_GC_SET_SHARED(PyObject *op) {
}
#define _PyObject_GC_SET_SHARED(op) _PyObject_GC_SET_SHARED(_Py_CAST(PyObject*, op))
-/* True if the memory of the object is shared between multiple
- * threads and needs special purpose when freeing due to
- * the possibility of in-flight lock-free reads occurring.
- * Objects with this bit that are GC objects will automatically
- * delay-freed by PyObject_GC_Del. */
-static inline int _PyObject_GC_IS_SHARED_INLINE(PyObject *op) {
- return _PyObject_HAS_GC_BITS(op, _PyGC_BITS_SHARED_INLINE);
-}
-#define _PyObject_GC_IS_SHARED_INLINE(op) \
- _PyObject_GC_IS_SHARED_INLINE(_Py_CAST(PyObject*, op))
-
-static inline void _PyObject_GC_SET_SHARED_INLINE(PyObject *op) {
- _PyObject_SET_GC_BITS(op, _PyGC_BITS_SHARED_INLINE);
-}
-#define _PyObject_GC_SET_SHARED_INLINE(op) \
- _PyObject_GC_SET_SHARED_INLINE(_Py_CAST(PyObject*, op))
-
#endif
/* Bit flags for _gc_prev */
diff --git a/Include/internal/pycore_pymem.h b/Include/internal/pycore_pymem.h
index dd6b076..5bb3400 100644
--- a/Include/internal/pycore_pymem.h
+++ b/Include/internal/pycore_pymem.h
@@ -120,11 +120,25 @@ extern int _PyMem_DebugEnabled(void);
extern void _PyMem_FreeDelayed(void *ptr);
// Enqueue an object to be freed possibly after some delay
-extern void _PyObject_FreeDelayed(void *ptr);
+#ifdef Py_GIL_DISABLED
+extern void _PyObject_XDecRefDelayed(PyObject *obj);
+#else
+static inline void _PyObject_XDecRefDelayed(PyObject *obj)
+{
+ Py_XDECREF(obj);
+}
+#endif
// Periodically process delayed free requests.
extern void _PyMem_ProcessDelayed(PyThreadState *tstate);
+
+// Periodically process delayed free requests when the world is stopped.
+// Notify of any objects whic should be freeed.
+typedef void (*delayed_dealloc_cb)(PyObject *, void *);
+extern void _PyMem_ProcessDelayedNoDealloc(PyThreadState *tstate,
+ delayed_dealloc_cb cb, void *state);
+
// Abandon all thread-local delayed free requests and push them to the
// interpreter's queue.
extern void _PyMem_AbandonDelayed(PyThreadState *tstate);