summaryrefslogtreecommitdiff
path: root/src/backend/utils/resowner/resowner.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2004-07-31 00:45:57 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2004-07-31 00:45:57 +0000
commita393fbf93763709f90ba1f968e50a35bd4cabcfb (patch)
tree955d74e7181214688b575f31c243005fe470dfe1 /src/backend/utils/resowner/resowner.c
parent94f8f63fdbcf61a56a23b8052d68fd78bec86a3b (diff)
Restructure error handling as recently discussed. It is now really
possible to trap an error inside a function rather than letting it propagate out to PostgresMain. You still have to use AbortCurrentTransaction to clean up, but at least the error handling itself will cooperate.
Diffstat (limited to 'src/backend/utils/resowner/resowner.c')
-rw-r--r--src/backend/utils/resowner/resowner.c37
1 files changed, 34 insertions, 3 deletions
diff --git a/src/backend/utils/resowner/resowner.c b/src/backend/utils/resowner/resowner.c
index e2eb1183ef4..e3835971d91 100644
--- a/src/backend/utils/resowner/resowner.c
+++ b/src/backend/utils/resowner/resowner.c
@@ -14,7 +14,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/resowner/resowner.c,v 1.1 2004/07/17 03:30:10 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/resowner/resowner.c,v 1.2 2004/07/31 00:45:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -99,6 +99,13 @@ typedef struct ResourceReleaseCallbackItem
static ResourceReleaseCallbackItem *ResourceRelease_callbacks = NULL;
+/* Internal routines */
+static void ResourceOwnerReleaseInternal(ResourceOwner owner,
+ ResourceReleasePhase phase,
+ bool isCommit,
+ bool isTopLevel);
+
+
/*****************************************************************************
* EXPORTED ROUTINES *
*****************************************************************************/
@@ -162,17 +169,41 @@ ResourceOwnerRelease(ResourceOwner owner,
bool isCommit,
bool isTopLevel)
{
+ /* Rather than PG_TRY at every level of recursion, set it up once */
+ ResourceOwner save;
+
+ save = CurrentResourceOwner;
+ PG_TRY();
+ {
+ ResourceOwnerReleaseInternal(owner, phase, isCommit, isTopLevel);
+ }
+ PG_CATCH();
+ {
+ CurrentResourceOwner = save;
+ PG_RE_THROW();
+ }
+ PG_END_TRY();
+ CurrentResourceOwner = save;
+}
+
+static void
+ResourceOwnerReleaseInternal(ResourceOwner owner,
+ ResourceReleasePhase phase,
+ bool isCommit,
+ bool isTopLevel)
+{
ResourceOwner child;
ResourceOwner save;
ResourceReleaseCallbackItem *item;
/* Recurse to handle descendants */
for (child = owner->firstchild; child != NULL; child = child->nextchild)
- ResourceOwnerRelease(child, phase, isCommit, isTopLevel);
+ ResourceOwnerReleaseInternal(child, phase, isCommit, isTopLevel);
/*
* Make CurrentResourceOwner point to me, so that ReleaseBuffer etc
- * don't get confused.
+ * don't get confused. We needn't PG_TRY here because the outermost
+ * level will fix it on error abort.
*/
save = CurrentResourceOwner;
CurrentResourceOwner = owner;