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