@@ -462,30 +462,34 @@ passed as second argument to Py_TRASHCAN_BEGIN().
462462PyAPI_FUNC (int ) _PyTrash_begin (PyThreadState * tstate , PyObject * op );
463463PyAPI_FUNC (void ) _PyTrash_end (PyThreadState * tstate );
464464
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 );
467467
468468
469469/* Python 3.10 private API, invoked by the Py_TRASHCAN_BEGIN(). */
470470
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+
471476#define Py_TRASHCAN_BEGIN (op , dealloc ) \
472477do { \
473478 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); \
476481 break; \
477482 } \
478483 tstate->c_recursion_remaining--;
479484 /* The body of the deallocator is here. */
480485#define Py_TRASHCAN_END \
481486 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); \
484489 } \
485490} while (0);
486491
487492
488-
489493PyAPI_FUNC (void * ) PyObject_GetItemData (PyObject * obj );
490494
491495PyAPI_FUNC (int ) PyObject_VisitManagedDict (PyObject * obj , visitproc visit , void * arg );
0 commit comments