aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/transam/xact.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2003-09-28 23:26:20 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2003-09-28 23:26:20 +0000
commit89347900527af6881efbf681b4e330d8074d35dd (patch)
tree28e5ea22ba95ec0afb9d6e046f01c085cc090d73 /src/backend/access/transam/xact.c
parenta15207f8d69cd7650e1a6fd962f7e3e8c543ce78 (diff)
downloadpostgresql-89347900527af6881efbf681b4e330d8074d35dd.tar.gz
postgresql-89347900527af6881efbf681b4e330d8074d35dd.zip
Add a mechanism to let dynamically loaded modules register post-commit/
post-abort cleanup hooks. I'm surprised that we have not needed this already, but I need it now to fix a plpgsql problem, and the usefulness for other dynamically loaded modules seems obvious.
Diffstat (limited to 'src/backend/access/transam/xact.c')
-rw-r--r--src/backend/access/transam/xact.c73
1 files changed, 72 insertions, 1 deletions
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index 86fe062030d..c7251e92073 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.154 2003/09/25 06:57:57 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.155 2003/09/28 23:26:20 tgl Exp $
*
* NOTES
* Transaction aborts can now occur two ways:
@@ -183,6 +183,7 @@ static void AtCommit_Memory(void);
static void AtStart_Cache(void);
static void AtStart_Locks(void);
static void AtStart_Memory(void);
+static void CallEOXactCallbacks(bool isCommit);
static void CleanupTransaction(void);
static void CommitTransaction(void);
static void RecordTransactionAbort(void);
@@ -217,6 +218,18 @@ int CommitSiblings = 5; /* number of concurrent xacts needed to
* sleep */
+/*
+ * List of add-on end-of-xact callbacks
+ */
+typedef struct EOXactCallbackItem
+{
+ struct EOXactCallbackItem *next;
+ EOXactCallback callback;
+ void *arg;
+} EOXactCallbackItem;
+
+static EOXactCallbackItem *EOXact_callbacks = NULL;
+
static void (*_RollbackFunc) (void *) = NULL;
static void *_RollbackData = NULL;
@@ -964,6 +977,7 @@ CommitTransaction(void)
AtCommit_Locks();
+ CallEOXactCallbacks(true);
AtEOXact_GUC(true);
AtEOXact_SPI();
AtEOXact_gist();
@@ -1073,6 +1087,7 @@ AbortTransaction(void)
AtAbort_Locks();
+ CallEOXactCallbacks(false);
AtEOXact_GUC(false);
AtEOXact_SPI();
AtEOXact_gist();
@@ -1430,6 +1445,62 @@ RequireTransactionChain(void *stmtNode, const char *stmtType)
}
+/*
+ * Register or deregister callback functions for end-of-xact cleanup
+ *
+ * These functions are intended for use by dynamically loaded modules.
+ * For built-in modules we generally just hardwire the appropriate calls
+ * (mainly because it's easier to control the order that way, where needed).
+ *
+ * Note that the callback occurs post-commit or post-abort, so the callback
+ * functions can only do noncritical cleanup.
+ */
+void
+RegisterEOXactCallback(EOXactCallback callback, void *arg)
+{
+ EOXactCallbackItem *item;
+
+ item = (EOXactCallbackItem *)
+ MemoryContextAlloc(TopMemoryContext, sizeof(EOXactCallbackItem));
+ item->callback = callback;
+ item->arg = arg;
+ item->next = EOXact_callbacks;
+ EOXact_callbacks = item;
+}
+
+void
+UnregisterEOXactCallback(EOXactCallback callback, void *arg)
+{
+ EOXactCallbackItem *item;
+ EOXactCallbackItem *prev;
+
+ prev = NULL;
+ for (item = EOXact_callbacks; item; prev = item, item = item->next)
+ {
+ if (item->callback == callback && item->arg == arg)
+ {
+ if (prev)
+ prev->next = item->next;
+ else
+ EOXact_callbacks = item->next;
+ pfree(item);
+ break;
+ }
+ }
+}
+
+static void
+CallEOXactCallbacks(bool isCommit)
+{
+ EOXactCallbackItem *item;
+
+ for (item = EOXact_callbacks; item; item = item->next)
+ {
+ (*item->callback) (isCommit, item->arg);
+ }
+}
+
+
/* ----------------------------------------------------------------
* transaction block support
* ----------------------------------------------------------------