]> granicus.if.org Git - postgresql/commitdiff
Add a mechanism to let dynamically loaded modules register post-commit/
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 28 Sep 2003 23:26:20 +0000 (23:26 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 28 Sep 2003 23:26:20 +0000 (23:26 +0000)
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.

src/backend/access/transam/xact.c
src/include/access/xact.h

index 86fe062030dbed4e0376be75353d952051c6e104..c7251e9207320a0580a1d3130c8966297bf4a746 100644 (file)
@@ -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
  * ----------------------------------------------------------------
index cbd1f3e449a6e8c7263f0283310d34de8a33e550..466249fedadc2872ab22a3a6babea1acb90cb68b 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: xact.h,v 1.55 2003/08/08 21:42:32 momjian Exp $
+ * $Id: xact.h,v 1.56 2003/09/28 23:26:20 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -59,9 +59,13 @@ typedef enum TBlockState
        TBLOCK_ENDABORT
 } TBlockState;
 
-/* ----------------
- *             transaction state structure
- * ----------------
+/*
+ *     end-of-transaction cleanup callbacks for dynamically loaded modules
+ */
+typedef void (*EOXactCallback) (bool isCommit, void *arg);
+
+/*
+ *     transaction state structure
  */
 typedef struct TransactionStateData
 {
@@ -130,6 +134,8 @@ extern void UserAbortTransactionBlock(void);
 extern void AbortOutOfAnyTransaction(void);
 extern void PreventTransactionChain(void *stmtNode, const char *stmtType);
 extern void RequireTransactionChain(void *stmtNode, const char *stmtType);
+extern void RegisterEOXactCallback(EOXactCallback callback, void *arg);
+extern void UnregisterEOXactCallback(EOXactCallback callback, void *arg);
 
 extern void RecordTransactionCommit(void);