10
10
*
11
11
*
12
12
* IDENTIFICATION
13
- * $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.189 2004/09/16 16:58:26 tgl Exp $
13
+ * $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.190 2004/09/16 20:17:16 tgl Exp $
14
14
*
15
15
*-------------------------------------------------------------------------
16
16
*/
@@ -861,9 +861,6 @@ AtCommit_Memory(void)
861
861
862
862
/*
863
863
* AtSubCommit_Memory
864
- *
865
- * We do not throw away the child's CurTransactionContext, since the data
866
- * it contains will be needed at upper commit.
867
864
*/
868
865
static void
869
866
AtSubCommit_Memory (void )
@@ -875,6 +872,18 @@ AtSubCommit_Memory(void)
875
872
/* Return to parent transaction level's memory context. */
876
873
CurTransactionContext = s -> parent -> curTransactionContext ;
877
874
MemoryContextSwitchTo (CurTransactionContext );
875
+
876
+ /*
877
+ * Ordinarily we cannot throw away the child's CurTransactionContext,
878
+ * since the data it contains will be needed at upper commit. However,
879
+ * if there isn't actually anything in it, we can throw it away. This
880
+ * avoids a small memory leak in the common case of "trivial" subxacts.
881
+ */
882
+ if (MemoryContextIsEmpty (s -> curTransactionContext ))
883
+ {
884
+ MemoryContextDelete (s -> curTransactionContext );
885
+ s -> curTransactionContext = NULL ;
886
+ }
878
887
}
879
888
880
889
/*
@@ -890,13 +899,27 @@ AtSubCommit_childXids(void)
890
899
891
900
Assert (s -> parent != NULL );
892
901
893
- old_cxt = MemoryContextSwitchTo (s -> parent -> curTransactionContext );
902
+ /*
903
+ * We keep the child-XID lists in TopTransactionContext; this avoids
904
+ * setting up child-transaction contexts for what might be just a few
905
+ * bytes of grandchild XIDs.
906
+ */
907
+ old_cxt = MemoryContextSwitchTo (TopTransactionContext );
894
908
895
909
s -> parent -> childXids = lappend_xid (s -> parent -> childXids ,
896
910
s -> transactionId );
897
911
898
- s -> parent -> childXids = list_concat (s -> parent -> childXids , s -> childXids );
899
- s -> childXids = NIL ; /* ensure list not doubly referenced */
912
+ if (s -> childXids != NIL )
913
+ {
914
+ s -> parent -> childXids = list_concat (s -> parent -> childXids ,
915
+ s -> childXids );
916
+ /*
917
+ * list_concat doesn't free the list header for the second list;
918
+ * do so here to avoid memory leakage (kluge)
919
+ */
920
+ pfree (s -> childXids );
921
+ s -> childXids = NIL ;
922
+ }
900
923
901
924
MemoryContextSwitchTo (old_cxt );
902
925
}
@@ -1092,6 +1115,23 @@ AtSubAbort_Memory(void)
1092
1115
MemoryContextSwitchTo (TopTransactionContext );
1093
1116
}
1094
1117
1118
+ /*
1119
+ * AtSubAbort_childXids
1120
+ */
1121
+ static void
1122
+ AtSubAbort_childXids (void )
1123
+ {
1124
+ TransactionState s = CurrentTransactionState ;
1125
+
1126
+ /*
1127
+ * We keep the child-XID lists in TopTransactionContext (see
1128
+ * AtSubCommit_childXids). This means we'd better free the list
1129
+ * explicitly at abort to avoid leakage.
1130
+ */
1131
+ list_free (s -> childXids );
1132
+ s -> childXids = NIL ;
1133
+ }
1134
+
1095
1135
/*
1096
1136
* RecordSubTransactionAbort
1097
1137
*/
@@ -3317,7 +3357,10 @@ AbortSubTransaction(void)
3317
3357
3318
3358
/* Advertise the fact that we aborted in pg_clog. */
3319
3359
if (TransactionIdIsValid (s -> transactionId ))
3360
+ {
3320
3361
RecordSubTransactionAbort ();
3362
+ AtSubAbort_childXids ();
3363
+ }
3321
3364
3322
3365
/* Post-abort cleanup */
3323
3366
CallSubXactCallbacks (SUBXACT_EVENT_ABORT_SUB , s -> subTransactionId ,
0 commit comments