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.
This commit is contained in:
parent
a15207f8d6
commit
8934790052
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* NOTES
|
||||||
* Transaction aborts can now occur two ways:
|
* Transaction aborts can now occur two ways:
|
||||||
@ -183,6 +183,7 @@ static void AtCommit_Memory(void);
|
|||||||
static void AtStart_Cache(void);
|
static void AtStart_Cache(void);
|
||||||
static void AtStart_Locks(void);
|
static void AtStart_Locks(void);
|
||||||
static void AtStart_Memory(void);
|
static void AtStart_Memory(void);
|
||||||
|
static void CallEOXactCallbacks(bool isCommit);
|
||||||
static void CleanupTransaction(void);
|
static void CleanupTransaction(void);
|
||||||
static void CommitTransaction(void);
|
static void CommitTransaction(void);
|
||||||
static void RecordTransactionAbort(void);
|
static void RecordTransactionAbort(void);
|
||||||
@ -217,6 +218,18 @@ int CommitSiblings = 5; /* number of concurrent xacts needed to
|
|||||||
* sleep */
|
* 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 (*_RollbackFunc) (void *) = NULL;
|
||||||
static void *_RollbackData = NULL;
|
static void *_RollbackData = NULL;
|
||||||
|
|
||||||
@ -964,6 +977,7 @@ CommitTransaction(void)
|
|||||||
|
|
||||||
AtCommit_Locks();
|
AtCommit_Locks();
|
||||||
|
|
||||||
|
CallEOXactCallbacks(true);
|
||||||
AtEOXact_GUC(true);
|
AtEOXact_GUC(true);
|
||||||
AtEOXact_SPI();
|
AtEOXact_SPI();
|
||||||
AtEOXact_gist();
|
AtEOXact_gist();
|
||||||
@ -1073,6 +1087,7 @@ AbortTransaction(void)
|
|||||||
|
|
||||||
AtAbort_Locks();
|
AtAbort_Locks();
|
||||||
|
|
||||||
|
CallEOXactCallbacks(false);
|
||||||
AtEOXact_GUC(false);
|
AtEOXact_GUC(false);
|
||||||
AtEOXact_SPI();
|
AtEOXact_SPI();
|
||||||
AtEOXact_gist();
|
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
|
* transaction block support
|
||||||
* ----------------------------------------------------------------
|
* ----------------------------------------------------------------
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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
|
TBLOCK_ENDABORT
|
||||||
} TBlockState;
|
} 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
|
typedef struct TransactionStateData
|
||||||
{
|
{
|
||||||
@ -130,6 +134,8 @@ extern void UserAbortTransactionBlock(void);
|
|||||||
extern void AbortOutOfAnyTransaction(void);
|
extern void AbortOutOfAnyTransaction(void);
|
||||||
extern void PreventTransactionChain(void *stmtNode, const char *stmtType);
|
extern void PreventTransactionChain(void *stmtNode, const char *stmtType);
|
||||||
extern void RequireTransactionChain(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);
|
extern void RecordTransactionCommit(void);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user