aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/async.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2004-09-06 23:33:48 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2004-09-06 23:33:48 +0000
commit083258e535c58c97e52ade7b0b68b5ed1879a678 (patch)
tree23730c5d5c8a2c10d1496cb7e06010628aad5a0e /src/backend/commands/async.c
parentd55588ea7a8a0203d27779263b1098688ee85bb2 (diff)
downloadpostgresql-083258e535c58c97e52ade7b0b68b5ed1879a678.tar.gz
postgresql-083258e535c58c97e52ade7b0b68b5ed1879a678.zip
Fix a number of places where brittle data structures or overly strong
Asserts would lead to a server core dump if an error occurred while trying to abort a failed subtransaction (thereby leading to re-execution of whatever parts of AbortSubTransaction had already run). This of course does not prevent such an error from creating an infinite loop, but at least we don't make the situation worse. Responds to an open item on the subtransactions to-do list.
Diffstat (limited to 'src/backend/commands/async.c')
-rw-r--r--src/backend/commands/async.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index f9d257d1a11..f25b8570455 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/async.c,v 1.115 2004/08/29 05:06:41 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/async.c,v 1.116 2004/09/06 23:32:54 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -630,6 +630,9 @@ AtSubStart_Notify(void)
upperPendingNotifies = lcons(pendingNotifies, upperPendingNotifies);
+ Assert(list_length(upperPendingNotifies) ==
+ GetCurrentTransactionNestLevel() - 1);
+
pendingNotifies = NIL;
MemoryContextSwitchTo(old_cxt);
@@ -648,6 +651,9 @@ AtSubCommit_Notify(void)
parentPendingNotifies = (List *) linitial(upperPendingNotifies);
upperPendingNotifies = list_delete_first(upperPendingNotifies);
+ Assert(list_length(upperPendingNotifies) ==
+ GetCurrentTransactionNestLevel() - 2);
+
/*
* We could try to eliminate duplicates here, but it seems not
* worthwhile.
@@ -661,13 +667,23 @@ AtSubCommit_Notify(void)
void
AtSubAbort_Notify(void)
{
+ int my_level = GetCurrentTransactionNestLevel();
+
/*
* All we have to do is pop the stack --- the notifies made in this
* subxact are no longer interesting, and the space will be freed when
* CurTransactionContext is recycled.
+ *
+ * This routine could be called more than once at a given nesting level
+ * if there is trouble during subxact abort. Avoid dumping core by
+ * using GetCurrentTransactionNestLevel as the indicator of how far
+ * we need to prune the list.
*/
- pendingNotifies = (List *) linitial(upperPendingNotifies);
- upperPendingNotifies = list_delete_first(upperPendingNotifies);
+ while (list_length(upperPendingNotifies) > my_level - 2)
+ {
+ pendingNotifies = (List *) linitial(upperPendingNotifies);
+ upperPendingNotifies = list_delete_first(upperPendingNotifies);
+ }
}
/*