24
24
25
25
#include "postgres.h"
26
26
27
+ #include "miscadmin.h"
27
28
#include "utils/memdebug.h"
28
29
#include "utils/memutils.h"
29
30
@@ -55,6 +56,19 @@ MemoryContext PortalContext = NULL;
55
56
56
57
static void MemoryContextStatsInternal (MemoryContext context , int level );
57
58
59
+ /*
60
+ * You should not do memory allocations within a critical section, because
61
+ * an out-of-memory error will be escalated to a PANIC. To enforce that
62
+ * rule, the allocation functions Assert that.
63
+ *
64
+ * There are a two exceptions: 1) error recovery uses ErrorContext, which
65
+ * has some memory set aside so that you don't run out. And 2) checkpointer
66
+ * currently just hopes for the best, which is wrong and ought to be fixed,
67
+ * but it's a known issue so let's not complain about in the meanwhile.
68
+ */
69
+ #define AssertNotInCriticalSection (context ) \
70
+ Assert(CritSectionCount == 0 || (context) == ErrorContext || \
71
+ AmCheckpointerProcess())
58
72
59
73
/*****************************************************************************
60
74
* EXPORTED ROUTINES *
@@ -519,6 +533,8 @@ MemoryContextCreate(NodeTag tag, Size size,
519
533
MemoryContext node ;
520
534
Size needed = size + strlen (name ) + 1 ;
521
535
536
+ Assert (CritSectionCount == 0 );
537
+
522
538
/* Get space for node and name */
523
539
if (TopMemoryContext != NULL )
524
540
{
@@ -575,6 +591,7 @@ MemoryContextAlloc(MemoryContext context, Size size)
575
591
void * ret ;
576
592
577
593
AssertArg (MemoryContextIsValid (context ));
594
+ AssertNotInCriticalSection (context );
578
595
579
596
if (!AllocSizeIsValid (size ))
580
597
elog (ERROR , "invalid memory alloc request size %zu" , size );
@@ -600,6 +617,7 @@ MemoryContextAllocZero(MemoryContext context, Size size)
600
617
void * ret ;
601
618
602
619
AssertArg (MemoryContextIsValid (context ));
620
+ AssertNotInCriticalSection (context );
603
621
604
622
if (!AllocSizeIsValid (size ))
605
623
elog (ERROR , "invalid memory alloc request size %zu" , size );
@@ -627,6 +645,7 @@ MemoryContextAllocZeroAligned(MemoryContext context, Size size)
627
645
void * ret ;
628
646
629
647
AssertArg (MemoryContextIsValid (context ));
648
+ AssertNotInCriticalSection (context );
630
649
631
650
if (!AllocSizeIsValid (size ))
632
651
elog (ERROR , "invalid memory alloc request size %zu" , size );
@@ -648,6 +667,7 @@ palloc(Size size)
648
667
void * ret ;
649
668
650
669
AssertArg (MemoryContextIsValid (CurrentMemoryContext ));
670
+ AssertNotInCriticalSection (CurrentMemoryContext );
651
671
652
672
if (!AllocSizeIsValid (size ))
653
673
elog (ERROR , "invalid memory alloc request size %zu" , size );
@@ -667,6 +687,7 @@ palloc0(Size size)
667
687
void * ret ;
668
688
669
689
AssertArg (MemoryContextIsValid (CurrentMemoryContext ));
690
+ AssertNotInCriticalSection (CurrentMemoryContext );
670
691
671
692
if (!AllocSizeIsValid (size ))
672
693
elog (ERROR , "invalid memory alloc request size %zu" , size );
@@ -738,6 +759,7 @@ repalloc(void *pointer, Size size)
738
759
((char * ) pointer - STANDARDCHUNKHEADERSIZE ))-> context ;
739
760
740
761
AssertArg (MemoryContextIsValid (context ));
762
+ AssertNotInCriticalSection (context );
741
763
742
764
/* isReset must be false already */
743
765
Assert (!context -> isReset );
@@ -760,6 +782,7 @@ MemoryContextAllocHuge(MemoryContext context, Size size)
760
782
void * ret ;
761
783
762
784
AssertArg (MemoryContextIsValid (context ));
785
+ AssertNotInCriticalSection (context );
763
786
764
787
if (!AllocHugeSizeIsValid (size ))
765
788
elog (ERROR , "invalid memory alloc request size %zu" , size );
@@ -801,6 +824,7 @@ repalloc_huge(void *pointer, Size size)
801
824
((char * ) pointer - STANDARDCHUNKHEADERSIZE ))-> context ;
802
825
803
826
AssertArg (MemoryContextIsValid (context ));
827
+ AssertNotInCriticalSection (context );
804
828
805
829
/* isReset must be false already */
806
830
Assert (!context -> isReset );
0 commit comments