@@ -531,6 +531,20 @@ tracemalloc_alloc(int need_gil, int use_calloc,
531531{
532532 assert (elsize == 0 || nelem <= SIZE_MAX / elsize );
533533
534+ int reentrant = get_reentrant ();
535+
536+ // Ignore reentrant call.
537+ //
538+ // For example, PyObjet_Malloc() calls
539+ // PyMem_Malloc() for allocations larger than 512 bytes: don't trace the
540+ // same memory allocation twice.
541+ //
542+ // If reentrant calls are not ignored, PyGILState_Ensure() can call
543+ // PyMem_RawMalloc() which would call PyGILState_Ensure() again in a loop.
544+ if (!reentrant ) {
545+ set_reentrant (1 );
546+ }
547+
534548 PyMemAllocatorEx * alloc = (PyMemAllocatorEx * )ctx ;
535549 void * ptr ;
536550 if (use_calloc ) {
@@ -541,22 +555,12 @@ tracemalloc_alloc(int need_gil, int use_calloc,
541555 }
542556
543557 if (ptr == NULL ) {
544- return NULL ;
558+ goto done ;
545559 }
546- if (get_reentrant () ) {
547- return ptr ;
560+ if (reentrant ) {
561+ goto done ;
548562 }
549563
550- // Ignore reentrant call.
551- //
552- // For example, PyObjet_Malloc() calls
553- // PyMem_Malloc() for allocations larger than 512 bytes: don't trace the
554- // same memory allocation twice.
555- //
556- // If reentrant calls are not ignored, PyGILState_Ensure() can call
557- // PyMem_RawMalloc() which would call PyGILState_Ensure() again in a loop.
558- set_reentrant (1 );
559-
560564 PyGILState_STATE gil_state ;
561565 if (need_gil ) {
562566 gil_state = PyGILState_Ensure ();
@@ -573,29 +577,37 @@ tracemalloc_alloc(int need_gil, int use_calloc,
573577 if (need_gil ) {
574578 PyGILState_Release (gil_state );
575579 }
576- set_reentrant (0 );
580+
581+ done :
582+ if (!reentrant ) {
583+ set_reentrant (0 );
584+ }
577585 return ptr ;
578586}
579587
580588
581589static void *
582590tracemalloc_realloc (int need_gil , void * ctx , void * ptr , size_t new_size )
583591{
592+ int reentrant = get_reentrant ();
593+
594+ // Ignore reentrant call. PyObjet_Realloc() calls PyMem_Realloc() for
595+ // allocations larger than 512 bytes: don't trace the same memory block
596+ // twice.
597+ if (!reentrant ) {
598+ set_reentrant (1 );
599+ }
600+
584601 PyMemAllocatorEx * alloc = (PyMemAllocatorEx * )ctx ;
585602 void * ptr2 = alloc -> realloc (alloc -> ctx , ptr , new_size );
586603
587604 if (ptr2 == NULL ) {
588- return NULL ;
605+ goto done ;
589606 }
590- if (get_reentrant () ) {
591- return ptr2 ;
607+ if (reentrant ) {
608+ goto done ;
592609 }
593610
594- // Ignore reentrant call. PyObjet_Realloc() calls PyMem_Realloc() for
595- // allocations larger than 512 bytes: don't trace the same memory block
596- // twice.
597- set_reentrant (1 );
598-
599611 PyGILState_STATE gil_state ;
600612 if (need_gil ) {
601613 gil_state = PyGILState_Ensure ();
@@ -638,7 +650,11 @@ tracemalloc_realloc(int need_gil, void *ctx, void *ptr, size_t new_size)
638650 if (need_gil ) {
639651 PyGILState_Release (gil_state );
640652 }
641- set_reentrant (0 );
653+
654+ done :
655+ if (!reentrant ) {
656+ set_reentrant (0 );
657+ }
642658 return ptr2 ;
643659}
644660
0 commit comments