Skip to content

Commit 8934790

Browse files
committed
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.
1 parent a15207f commit 8934790

File tree

2 files changed

+82
-5
lines changed

2 files changed

+82
-5
lines changed

src/backend/access/transam/xact.c

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.154 2003/09/25 06:57:57 petere Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.155 2003/09/28 23:26:20 tgl Exp $
1212
*
1313
* NOTES
1414
* Transaction aborts can now occur two ways:
@@ -183,6 +183,7 @@ static void AtCommit_Memory(void);
183183
static void AtStart_Cache(void);
184184
static void AtStart_Locks(void);
185185
static void AtStart_Memory(void);
186+
static void CallEOXactCallbacks(bool isCommit);
186187
static void CleanupTransaction(void);
187188
static void CommitTransaction(void);
188189
static void RecordTransactionAbort(void);
@@ -217,6 +218,18 @@ int CommitSiblings = 5; /* number of concurrent xacts needed to
217218
* sleep */
218219

219220

221+
/*
222+
* List of add-on end-of-xact callbacks
223+
*/
224+
typedef struct EOXactCallbackItem
225+
{
226+
struct EOXactCallbackItem *next;
227+
EOXactCallback callback;
228+
void *arg;
229+
} EOXactCallbackItem;
230+
231+
static EOXactCallbackItem *EOXact_callbacks = NULL;
232+
220233
static void (*_RollbackFunc) (void *) = NULL;
221234
static void *_RollbackData = NULL;
222235

@@ -964,6 +977,7 @@ CommitTransaction(void)
964977

965978
AtCommit_Locks();
966979

980+
CallEOXactCallbacks(true);
967981
AtEOXact_GUC(true);
968982
AtEOXact_SPI();
969983
AtEOXact_gist();
@@ -1073,6 +1087,7 @@ AbortTransaction(void)
10731087

10741088
AtAbort_Locks();
10751089

1090+
CallEOXactCallbacks(false);
10761091
AtEOXact_GUC(false);
10771092
AtEOXact_SPI();
10781093
AtEOXact_gist();
@@ -1430,6 +1445,62 @@ RequireTransactionChain(void *stmtNode, const char *stmtType)
14301445
}
14311446

14321447

1448+
/*
1449+
* Register or deregister callback functions for end-of-xact cleanup
1450+
*
1451+
* These functions are intended for use by dynamically loaded modules.
1452+
* For built-in modules we generally just hardwire the appropriate calls
1453+
* (mainly because it's easier to control the order that way, where needed).
1454+
*
1455+
* Note that the callback occurs post-commit or post-abort, so the callback
1456+
* functions can only do noncritical cleanup.
1457+
*/
1458+
void
1459+
RegisterEOXactCallback(EOXactCallback callback, void *arg)
1460+
{
1461+
EOXactCallbackItem *item;
1462+
1463+
item = (EOXactCallbackItem *)
1464+
MemoryContextAlloc(TopMemoryContext, sizeof(EOXactCallbackItem));
1465+
item->callback = callback;
1466+
item->arg = arg;
1467+
item->next = EOXact_callbacks;
1468+
EOXact_callbacks = item;
1469+
}
1470+
1471+
void
1472+
UnregisterEOXactCallback(EOXactCallback callback, void *arg)
1473+
{
1474+
EOXactCallbackItem *item;
1475+
EOXactCallbackItem *prev;
1476+
1477+
prev = NULL;
1478+
for (item = EOXact_callbacks; item; prev = item, item = item->next)
1479+
{
1480+
if (item->callback == callback && item->arg == arg)
1481+
{
1482+
if (prev)
1483+
prev->next = item->next;
1484+
else
1485+
EOXact_callbacks = item->next;
1486+
pfree(item);
1487+
break;
1488+
}
1489+
}
1490+
}
1491+
1492+
static void
1493+
CallEOXactCallbacks(bool isCommit)
1494+
{
1495+
EOXactCallbackItem *item;
1496+
1497+
for (item = EOXact_callbacks; item; item = item->next)
1498+
{
1499+
(*item->callback) (isCommit, item->arg);
1500+
}
1501+
}
1502+
1503+
14331504
/* ----------------------------------------------------------------
14341505
* transaction block support
14351506
* ----------------------------------------------------------------

src/include/access/xact.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: xact.h,v 1.55 2003/08/08 21:42:32 momjian Exp $
10+
* $Id: xact.h,v 1.56 2003/09/28 23:26:20 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -59,9 +59,13 @@ typedef enum TBlockState
5959
TBLOCK_ENDABORT
6060
} TBlockState;
6161

62-
/* ----------------
63-
* transaction state structure
64-
* ----------------
62+
/*
63+
* end-of-transaction cleanup callbacks for dynamically loaded modules
64+
*/
65+
typedef void (*EOXactCallback) (bool isCommit, void *arg);
66+
67+
/*
68+
* transaction state structure
6569
*/
6670
typedef struct TransactionStateData
6771
{
@@ -130,6 +134,8 @@ extern void UserAbortTransactionBlock(void);
130134
extern void AbortOutOfAnyTransaction(void);
131135
extern void PreventTransactionChain(void *stmtNode, const char *stmtType);
132136
extern void RequireTransactionChain(void *stmtNode, const char *stmtType);
137+
extern void RegisterEOXactCallback(EOXactCallback callback, void *arg);
138+
extern void UnregisterEOXactCallback(EOXactCallback callback, void *arg);
133139

134140
extern void RecordTransactionCommit(void);
135141

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy