|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * 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 $ |
12 | 12 | *
|
13 | 13 | * NOTES
|
14 | 14 | *Transaction aborts can now occur two ways:
|
@@ -183,6 +183,7 @@ static void AtCommit_Memory(void);
|
183 | 183 | staticvoidAtStart_Cache(void);
|
184 | 184 | staticvoidAtStart_Locks(void);
|
185 | 185 | staticvoidAtStart_Memory(void);
|
| 186 | +staticvoidCallEOXactCallbacks(boolisCommit); |
186 | 187 | staticvoidCleanupTransaction(void);
|
187 | 188 | staticvoidCommitTransaction(void);
|
188 | 189 | staticvoidRecordTransactionAbort(void);
|
@@ -217,6 +218,18 @@ intCommitSiblings = 5; /* number of concurrent xacts needed to
|
217 | 218 | * sleep */
|
218 | 219 |
|
219 | 220 |
|
| 221 | +/* |
| 222 | + * List of add-on end-of-xact callbacks |
| 223 | + */ |
| 224 | +typedefstructEOXactCallbackItem |
| 225 | +{ |
| 226 | +structEOXactCallbackItem*next; |
| 227 | +EOXactCallbackcallback; |
| 228 | +void*arg; |
| 229 | +}EOXactCallbackItem; |
| 230 | + |
| 231 | +staticEOXactCallbackItem*EOXact_callbacks=NULL; |
| 232 | + |
220 | 233 | staticvoid (*_RollbackFunc) (void*)=NULL;
|
221 | 234 | staticvoid*_RollbackData=NULL;
|
222 | 235 |
|
@@ -964,6 +977,7 @@ CommitTransaction(void)
|
964 | 977 |
|
965 | 978 | AtCommit_Locks();
|
966 | 979 |
|
| 980 | +CallEOXactCallbacks(true); |
967 | 981 | AtEOXact_GUC(true);
|
968 | 982 | AtEOXact_SPI();
|
969 | 983 | AtEOXact_gist();
|
@@ -1073,6 +1087,7 @@ AbortTransaction(void)
|
1073 | 1087 |
|
1074 | 1088 | AtAbort_Locks();
|
1075 | 1089 |
|
| 1090 | +CallEOXactCallbacks(false); |
1076 | 1091 | AtEOXact_GUC(false);
|
1077 | 1092 | AtEOXact_SPI();
|
1078 | 1093 | AtEOXact_gist();
|
@@ -1430,6 +1445,62 @@ RequireTransactionChain(void *stmtNode, const char *stmtType)
|
1430 | 1445 | }
|
1431 | 1446 |
|
1432 | 1447 |
|
| 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(EOXactCallbackcallback,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(EOXactCallbackcallback,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 | +staticvoid |
| 1493 | +CallEOXactCallbacks(boolisCommit) |
| 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 | + |
1433 | 1504 | /* ----------------------------------------------------------------
|
1434 | 1505 | * transaction block support
|
1435 | 1506 | * ----------------------------------------------------------------
|
|