Hi hackers, It's a natural requirement to unregister the callback for transaction or subtransaction when the callback is invoked, so we don't have to unregister the callback somewhere. If it's not allowed to do it in CallXactCallback() or CallSubXactCallback(), we must find the right place and handle it carefully.
Luckily, we just need a few lines of code to support this feature,
by saving the next pointer before calling the callback.
The usage looks like:
```
static void
AtEOXact_cleanup_state(SubXactEvent event, SubTransactionId mySubid,
SubTransactionId parentSubid, void *arg)
{
SubXactCleanupItem *item = (SubXactCleanupItem *)arg;
Assert(FullTransactionIdEquals(item->fullXid,
GetTopFullTransactionIdIfAny()));
if (item->mySubid == mySubid &&
(event == SUBXACT_EVENT_COMMIT_SUB || event ==
SUBXACT_EVENT_ABORT_SUB))
{
/* to do some cleanup for subtransaction */
...
UnregisterSubXactCallback(AtEOXact_cleanup_state, arg);
}
}
```
Regards,
Hao Wu
safely-delete-callback.diff
Description: Binary data
