with the call stack never exceeding a depth of PyTrash_UNWIND_LEVEL.
*/
- Kept for binary compatibility of extensions. */
+ /* This is the old private API, invoked by the macros before 3.2.4.
++ Kept for binary compatibility of extensions using the stable ABI. */
PyAPI_FUNC(void) _PyTrash_deposit_object(PyObject*);
PyAPI_FUNC(void) _PyTrash_destroy_chain(void);
PyAPI_DATA(int) _PyTrash_delete_nesting;
#define PyTrash_UNWIND_LEVEL 50
#define Py_TRASHCAN_SAFE_BEGIN(op) \
- if (_PyTrash_delete_nesting < PyTrash_UNWIND_LEVEL) { \
- ++_PyTrash_delete_nesting;
- /* The body of the deallocator is here. */
+ do { \
+ PyThreadState *_tstate = PyThreadState_GET(); \
+ if (_tstate->trash_delete_nesting < PyTrash_UNWIND_LEVEL) { \
+ ++_tstate->trash_delete_nesting;
+ /* The body of the deallocator is here. */
#define Py_TRASHCAN_SAFE_END(op) \
- --_PyTrash_delete_nesting; \
- if (_PyTrash_delete_later && _PyTrash_delete_nesting <= 0) \
- _PyTrash_destroy_chain(); \
- } \
- else \
- _PyTrash_deposit_object((PyObject*)op);
+ --_tstate->trash_delete_nesting; \
+ if (_tstate->trash_delete_later && _tstate->trash_delete_nesting <= 0) \
+ _PyTrash_thread_destroy_chain(); \
+ } \
+ else \
+ _PyTrash_thread_deposit_object((PyObject*)op); \
+ } while (0);
+#ifndef Py_LIMITED_API
+PyAPI_FUNC(void)
+_PyDebugAllocatorStats(FILE *out, const char *block_name, int num_blocks,
+ size_t sizeof_block);
+PyAPI_FUNC(void)
+_PyObject_DebugTypeStats(FILE *out);
+#endif /* ifndef Py_LIMITED_API */
+
#ifdef __cplusplus
}
#endif
Core and Builtins
-----------------
+ - Issue #13992: The trashcan mechanism is now thread-safe. This eliminates
+ sporadic crashes in multi-thread programs when several long deallocator
+ chains ran concurrently and involved subclasses of built-in container
+ types.
+
+- Issue #15839: Convert SystemErrors in super() to RuntimeErrors.
+
- Issue #15846: Fix SystemError which happened when using ast.parse in an
exception handler on code with syntax errors.