@@ -462,30 +462,34 @@ passed as second argument to Py_TRASHCAN_BEGIN().
462
462
PyAPI_FUNC (int ) _PyTrash_begin (PyThreadState * tstate , PyObject * op );
463
463
PyAPI_FUNC (void ) _PyTrash_end (PyThreadState * tstate );
464
464
465
- PyAPI_FUNC (void ) PyTrash_thread_deposit_object (PyThreadState * tstate , PyObject * op );
466
- PyAPI_FUNC (void ) PyTrash_thread_destroy_chain (PyThreadState * tstate );
465
+ PyAPI_FUNC (void ) _PyTrash_thread_deposit_object (PyThreadState * tstate , PyObject * op );
466
+ PyAPI_FUNC (void ) _PyTrash_thread_destroy_chain (PyThreadState * tstate );
467
467
468
468
469
469
/* Python 3.10 private API, invoked by the Py_TRASHCAN_BEGIN(). */
470
470
471
+ /* To avoid raising recursion errors during dealloc trigger trashcan before we reach
472
+ * recursion limit. To avoid trashing, we don't attempt to empty the trashcan until
473
+ * we have headroom above the trigger limit */
474
+ #define Py_TRASHCAN_HEADROOM 50
475
+
471
476
#define Py_TRASHCAN_BEGIN (op , dealloc ) \
472
477
do { \
473
478
PyThreadState *tstate = PyThreadState_Get(); \
474
- if (tstate->c_recursion_remaining <= 50 && Py_TYPE(op)->tp_dealloc == (destructor)dealloc) { \
475
- PyTrash_thread_deposit_object (tstate, (PyObject *)op); \
479
+ if (tstate->c_recursion_remaining <= Py_TRASHCAN_HEADROOM && Py_TYPE(op)->tp_dealloc == (destructor)dealloc) { \
480
+ _PyTrash_thread_deposit_object (tstate, (PyObject *)op); \
476
481
break; \
477
482
} \
478
483
tstate->c_recursion_remaining--;
479
484
/* The body of the deallocator is here. */
480
485
#define Py_TRASHCAN_END \
481
486
tstate->c_recursion_remaining++; \
482
- if (tstate->delete_later && tstate->c_recursion_remaining > 100 ) { \
483
- PyTrash_thread_destroy_chain (tstate); \
487
+ if (tstate->delete_later && tstate->c_recursion_remaining > (Py_TRASHCAN_HEADROOM*2) ) { \
488
+ _PyTrash_thread_destroy_chain (tstate); \
484
489
} \
485
490
} while (0);
486
491
487
492
488
-
489
493
PyAPI_FUNC (void * ) PyObject_GetItemData (PyObject * obj );
490
494
491
495
PyAPI_FUNC (int ) PyObject_VisitManagedDict (PyObject * obj , visitproc visit , void * arg );
0 commit comments