/* * We keep some resources across transactions, so we attach everything to a * long-lived ResourceOwner, which prevents the below commit from thinking that * there are reference leaks */ static void start_executor(QueryDesc *queryDesc, MemoryContext context, ResourceOwner owner) { MemoryContext old; ResourceOwner save; StartTransactionCommand(); old = MemoryContextSwitchTo(context); save = CurrentResourceOwner; CurrentResourceOwner = owner; queryDesc->snapshot = GetTransactionSnapshot(); queryDesc->snapshot->copied = true; RegisterSnapshotOnOwner(queryDesc->snapshot, owner); ExecutorStart(queryDesc, 0); queryDesc->snapshot->active_count++; UnregisterSnapshotFromOwner(queryDesc->snapshot, owner); UnregisterSnapshotFromOwner(queryDesc->estate->es_snapshot, owner); CurrentResourceOwner = TopTransactionResourceOwner; MemoryContextSwitchTo(old); CommitTransactionCommand(); CurrentResourceOwner = save; }
/* * UnregisterSnapshot * * Decrement the reference count of a snapshot, remove the corresponding * reference from CurrentResourceOwner, and free the snapshot if no more * references remain. */ void UnregisterSnapshot(Snapshot snapshot) { if (snapshot == NULL) return; UnregisterSnapshotFromOwner(snapshot, CurrentResourceOwner); }
/* * Closes a large object descriptor previously made by inv_open(), and * releases the long-term memory used by it. */ void inv_close(LargeObjectDesc *obj_desc) { Assert(PointerIsValid(obj_desc)); UnregisterSnapshotFromOwner(obj_desc->snapshot, TopTransactionResourceOwner); pfree(obj_desc); }
/* * AtEarlyCommit_Snapshot * * Snapshot manager's cleanup function, to be called on commit, before * doing resowner.c resource release. */ void AtEarlyCommit_Snapshot(void) { /* * In transaction-snapshot mode we must unregister our private refcount to * the transaction-snapshot. */ if (registered_xact_snapshot) UnregisterSnapshotFromOwner(CurrentSnapshot, TopTransactionResourceOwner); registered_xact_snapshot = false; }
/* * AtEarlyCommit_Snapshot * * Snapshot manager's cleanup function, to be called on commit, before * doing resowner.c resource release. */ void AtEarlyCommit_Snapshot(void) { /* * On a serializable transaction we must unregister our private refcount * to the serializable snapshot. */ if (registered_serializable) UnregisterSnapshotFromOwner(CurrentSnapshot, TopTransactionResourceOwner); registered_serializable = false; }
static void unset_snapshot(EState *estate, ResourceOwner owner) { PopActiveSnapshot(); UnregisterSnapshotFromOwner(estate->es_snapshot, owner); }