diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2003-09-28 23:26:20 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2003-09-28 23:26:20 +0000 |
commit | 89347900527af6881efbf681b4e330d8074d35dd (patch) | |
tree | 28e5ea22ba95ec0afb9d6e046f01c085cc090d73 /src/backend/access/transam/xact.c | |
parent | a15207f8d69cd7650e1a6fd962f7e3e8c543ce78 (diff) | |
download | postgresql-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.c | 73 |
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 * ---------------------------------------------------------------- |