#include "postgres.h"
#include "access/hash.h"
#include "storage/predicate.h"
#include "storage/proc.h"
#include "utils/memutils.h"
#include "utils/rel.h"
#include "utils/resowner_private.h"
#include "utils/snapmgr.h"
Go to the source code of this file.
#define MAX_RESOWNER_LOCKS 15 |
Definition at line 47 of file resowner.c.
Referenced by ResourceOwnerDelete(), ResourceOwnerForgetLock(), ResourceOwnerReleaseInternal(), and ResourceOwnerRememberLock().
typedef struct ResourceOwnerData ResourceOwnerData |
typedef struct ResourceReleaseCallbackItem ResourceReleaseCallbackItem |
static void PrintFileLeakWarning | ( | File | file | ) | [static] |
Definition at line 1227 of file resowner.c.
Referenced by ResourceOwnerReleaseInternal().
static void PrintPlanCacheLeakWarning | ( | CachedPlan * | plan | ) | [static] |
Definition at line 981 of file resowner.c.
Referenced by ResourceOwnerReleaseInternal().
static void PrintRelCacheLeakWarning | ( | Relation | rel | ) | [static] |
Definition at line 900 of file resowner.c.
References elog, RelationGetRelationName, and WARNING.
Referenced by ResourceOwnerReleaseInternal().
{ elog(WARNING, "relcache reference leak: relation \"%s\" not closed", RelationGetRelationName(rel)); }
static void PrintSnapshotLeakWarning | ( | Snapshot | snapshot | ) | [static] |
Definition at line 1143 of file resowner.c.
Referenced by ResourceOwnerReleaseInternal().
static void PrintTupleDescLeakWarning | ( | TupleDesc | tupdesc | ) | [static] |
Definition at line 1061 of file resowner.c.
References elog, tupleDesc::tdtypeid, tupleDesc::tdtypmod, and WARNING.
Referenced by ResourceOwnerReleaseInternal().
void RegisterResourceReleaseCallback | ( | ResourceReleaseCallback | callback, | |
void * | arg | |||
) |
Definition at line 506 of file resowner.c.
References ResourceReleaseCallbackItem::arg, ResourceReleaseCallbackItem::callback, MemoryContextAlloc(), ResourceReleaseCallbackItem::next, and TopMemoryContext.
{ ResourceReleaseCallbackItem *item; item = (ResourceReleaseCallbackItem *) MemoryContextAlloc(TopMemoryContext, sizeof(ResourceReleaseCallbackItem)); item->callback = callback; item->arg = arg; item->next = ResourceRelease_callbacks; ResourceRelease_callbacks = item; }
ResourceOwner ResourceOwnerCreate | ( | ResourceOwner | parent, | |
const char * | name | |||
) |
Definition at line 150 of file resowner.c.
References ResourceOwnerData::firstchild, MemoryContextAllocZero(), ResourceOwnerData::name, ResourceOwnerData::nextchild, ResourceOwnerData::parent, and TopMemoryContext.
Referenced by AtStart_ResourceOwner(), AtSubStart_ResourceOwner(), BackgroundWriterMain(), CheckpointerMain(), CreatePortal(), InitWalSender(), WalReceiverMain(), and WalWriterMain().
{ ResourceOwner owner; owner = (ResourceOwner) MemoryContextAllocZero(TopMemoryContext, sizeof(ResourceOwnerData)); owner->name = name; if (parent) { owner->parent = parent; owner->nextchild = parent->firstchild; parent->firstchild = owner; } return owner; }
void ResourceOwnerDelete | ( | ResourceOwner | owner | ) |
Definition at line 394 of file resowner.c.
References Assert, ResourceOwnerData::buffers, ResourceOwnerData::catlistrefs, ResourceOwnerData::catrefs, ResourceOwnerData::files, ResourceOwnerData::firstchild, MAX_RESOWNER_LOCKS, ResourceOwnerData::nbuffers, ResourceOwnerData::ncatlistrefs, ResourceOwnerData::ncatrefs, ResourceOwnerData::nfiles, ResourceOwnerData::nlocks, ResourceOwnerData::nplanrefs, ResourceOwnerData::nrelrefs, ResourceOwnerData::nsnapshots, ResourceOwnerData::ntupdescs, NULL, pfree(), ResourceOwnerData::planrefs, ResourceOwnerData::relrefs, ResourceOwnerDelete(), ResourceOwnerNewParent(), ResourceOwnerData::snapshots, and ResourceOwnerData::tupdescs.
Referenced by CleanupSubTransaction(), CleanupTransaction(), CommitSubTransaction(), CommitTransaction(), PortalDrop(), PrepareTransaction(), and ResourceOwnerDelete().
{ /* We had better not be deleting CurrentResourceOwner ... */ Assert(owner != CurrentResourceOwner); /* And it better not own any resources, either */ Assert(owner->nbuffers == 0); Assert(owner->nlocks == 0 || owner->nlocks == MAX_RESOWNER_LOCKS + 1); Assert(owner->ncatrefs == 0); Assert(owner->ncatlistrefs == 0); Assert(owner->nrelrefs == 0); Assert(owner->nplanrefs == 0); Assert(owner->ntupdescs == 0); Assert(owner->nsnapshots == 0); Assert(owner->nfiles == 0); /* * Delete children. The recursive call will delink the child from me, so * just iterate as long as there is a child. */ while (owner->firstchild != NULL) ResourceOwnerDelete(owner->firstchild); /* * We delink the owner from its parent before deleting it, so that if * there's an error we won't have deleted/busted owners still attached to * the owner tree. Better a leak than a crash. */ ResourceOwnerNewParent(owner, NULL); /* And free the object. */ if (owner->buffers) pfree(owner->buffers); if (owner->catrefs) pfree(owner->catrefs); if (owner->catlistrefs) pfree(owner->catlistrefs); if (owner->relrefs) pfree(owner->relrefs); if (owner->planrefs) pfree(owner->planrefs); if (owner->tupdescs) pfree(owner->tupdescs); if (owner->snapshots) pfree(owner->snapshots); if (owner->files) pfree(owner->files); pfree(owner); }
void ResourceOwnerEnlargeBuffers | ( | ResourceOwner | owner | ) |
Definition at line 552 of file resowner.c.
References ResourceOwnerData::buffers, ResourceOwnerData::maxbuffers, MemoryContextAlloc(), ResourceOwnerData::nbuffers, NULL, repalloc(), and TopMemoryContext.
Referenced by BgBufferSync(), BufferSync(), FlushDatabaseBuffers(), FlushRelationBuffers(), IncrBufferRefCount(), and ReadBuffer_common().
{ int newmax; if (owner == NULL || owner->nbuffers < owner->maxbuffers) return; /* nothing to do */ if (owner->buffers == NULL) { newmax = 16; owner->buffers = (Buffer *) MemoryContextAlloc(TopMemoryContext, newmax * sizeof(Buffer)); owner->maxbuffers = newmax; } else { newmax = owner->maxbuffers * 2; owner->buffers = (Buffer *) repalloc(owner->buffers, newmax * sizeof(Buffer)); owner->maxbuffers = newmax; } }
void ResourceOwnerEnlargeCatCacheListRefs | ( | ResourceOwner | owner | ) |
Definition at line 762 of file resowner.c.
References ResourceOwnerData::catlistrefs, ResourceOwnerData::maxcatlistrefs, MemoryContextAlloc(), ResourceOwnerData::ncatlistrefs, NULL, repalloc(), and TopMemoryContext.
Referenced by SearchCatCacheList().
{ int newmax; if (owner->ncatlistrefs < owner->maxcatlistrefs) return; /* nothing to do */ if (owner->catlistrefs == NULL) { newmax = 16; owner->catlistrefs = (CatCList **) MemoryContextAlloc(TopMemoryContext, newmax * sizeof(CatCList *)); owner->maxcatlistrefs = newmax; } else { newmax = owner->maxcatlistrefs * 2; owner->catlistrefs = (CatCList **) repalloc(owner->catlistrefs, newmax * sizeof(CatCList *)); owner->maxcatlistrefs = newmax; } }
void ResourceOwnerEnlargeCatCacheRefs | ( | ResourceOwner | owner | ) |
Definition at line 691 of file resowner.c.
References ResourceOwnerData::catrefs, ResourceOwnerData::maxcatrefs, MemoryContextAlloc(), ResourceOwnerData::ncatrefs, NULL, repalloc(), and TopMemoryContext.
Referenced by SearchCatCache().
{ int newmax; if (owner->ncatrefs < owner->maxcatrefs) return; /* nothing to do */ if (owner->catrefs == NULL) { newmax = 16; owner->catrefs = (HeapTuple *) MemoryContextAlloc(TopMemoryContext, newmax * sizeof(HeapTuple)); owner->maxcatrefs = newmax; } else { newmax = owner->maxcatrefs * 2; owner->catrefs = (HeapTuple *) repalloc(owner->catrefs, newmax * sizeof(HeapTuple)); owner->maxcatrefs = newmax; } }
void ResourceOwnerEnlargeFiles | ( | ResourceOwner | owner | ) |
Definition at line 1159 of file resowner.c.
References ResourceOwnerData::files, ResourceOwnerData::maxfiles, MemoryContextAlloc(), ResourceOwnerData::nfiles, NULL, repalloc(), and TopMemoryContext.
Referenced by OpenTemporaryFile().
{ int newmax; if (owner->nfiles < owner->maxfiles) return; /* nothing to do */ if (owner->files == NULL) { newmax = 16; owner->files = (File *) MemoryContextAlloc(TopMemoryContext, newmax * sizeof(File)); owner->maxfiles = newmax; } else { newmax = owner->maxfiles * 2; owner->files = (File *) repalloc(owner->files, newmax * sizeof(File)); owner->maxfiles = newmax; } }
void ResourceOwnerEnlargePlanCacheRefs | ( | ResourceOwner | owner | ) |
Definition at line 914 of file resowner.c.
References ResourceOwnerData::maxplanrefs, MemoryContextAlloc(), ResourceOwnerData::nplanrefs, NULL, ResourceOwnerData::planrefs, repalloc(), and TopMemoryContext.
Referenced by GetCachedPlan().
{ int newmax; if (owner->nplanrefs < owner->maxplanrefs) return; /* nothing to do */ if (owner->planrefs == NULL) { newmax = 16; owner->planrefs = (CachedPlan **) MemoryContextAlloc(TopMemoryContext, newmax * sizeof(CachedPlan *)); owner->maxplanrefs = newmax; } else { newmax = owner->maxplanrefs * 2; owner->planrefs = (CachedPlan **) repalloc(owner->planrefs, newmax * sizeof(CachedPlan *)); owner->maxplanrefs = newmax; } }
void ResourceOwnerEnlargeRelationRefs | ( | ResourceOwner | owner | ) |
Definition at line 833 of file resowner.c.
References ResourceOwnerData::maxrelrefs, MemoryContextAlloc(), ResourceOwnerData::nrelrefs, NULL, ResourceOwnerData::relrefs, repalloc(), and TopMemoryContext.
Referenced by RelationIncrementReferenceCount().
{ int newmax; if (owner->nrelrefs < owner->maxrelrefs) return; /* nothing to do */ if (owner->relrefs == NULL) { newmax = 16; owner->relrefs = (Relation *) MemoryContextAlloc(TopMemoryContext, newmax * sizeof(Relation)); owner->maxrelrefs = newmax; } else { newmax = owner->maxrelrefs * 2; owner->relrefs = (Relation *) repalloc(owner->relrefs, newmax * sizeof(Relation)); owner->maxrelrefs = newmax; } }
void ResourceOwnerEnlargeSnapshots | ( | ResourceOwner | owner | ) |
Definition at line 1076 of file resowner.c.
References ResourceOwnerData::maxsnapshots, MemoryContextAlloc(), ResourceOwnerData::nsnapshots, NULL, repalloc(), ResourceOwnerData::snapshots, and TopMemoryContext.
Referenced by RegisterSnapshotOnOwner().
{ int newmax; if (owner->nsnapshots < owner->maxsnapshots) return; /* nothing to do */ if (owner->snapshots == NULL) { newmax = 16; owner->snapshots = (Snapshot *) MemoryContextAlloc(TopMemoryContext, newmax * sizeof(Snapshot)); owner->maxsnapshots = newmax; } else { newmax = owner->maxsnapshots * 2; owner->snapshots = (Snapshot *) repalloc(owner->snapshots, newmax * sizeof(Snapshot)); owner->maxsnapshots = newmax; } }
void ResourceOwnerEnlargeTupleDescs | ( | ResourceOwner | owner | ) |
Definition at line 994 of file resowner.c.
References ResourceOwnerData::maxtupdescs, MemoryContextAlloc(), ResourceOwnerData::ntupdescs, NULL, repalloc(), TopMemoryContext, and ResourceOwnerData::tupdescs.
Referenced by IncrTupleDescRefCount().
{ int newmax; if (owner->ntupdescs < owner->maxtupdescs) return; /* nothing to do */ if (owner->tupdescs == NULL) { newmax = 16; owner->tupdescs = (TupleDesc *) MemoryContextAlloc(TopMemoryContext, newmax * sizeof(TupleDesc)); owner->maxtupdescs = newmax; } else { newmax = owner->maxtupdescs * 2; owner->tupdescs = (TupleDesc *) repalloc(owner->tupdescs, newmax * sizeof(TupleDesc)); owner->maxtupdescs = newmax; } }
void ResourceOwnerForgetBuffer | ( | ResourceOwner | owner, | |
Buffer | buffer | |||
) |
Definition at line 602 of file resowner.c.
References ResourceOwnerData::buffers, elog, ERROR, i, ResourceOwnerData::name, ResourceOwnerData::nbuffers, and NULL.
Referenced by ReleaseAndReadBuffer(), ReleaseBuffer(), and UnpinBuffer().
{ if (owner != NULL) { Buffer *buffers = owner->buffers; int nb1 = owner->nbuffers - 1; int i; /* * Scan back-to-front because it's more likely we are releasing a * recently pinned buffer. This isn't always the case of course, but * it's the way to bet. */ for (i = nb1; i >= 0; i--) { if (buffers[i] == buffer) { while (i < nb1) { buffers[i] = buffers[i + 1]; i++; } owner->nbuffers = nb1; return; } } elog(ERROR, "buffer %d is not owned by resource owner %s", buffer, owner->name); } }
void ResourceOwnerForgetCatCacheListRef | ( | ResourceOwner | owner, | |
CatCList * | list | |||
) |
Definition at line 802 of file resowner.c.
References ResourceOwnerData::catlistrefs, elog, ERROR, i, ResourceOwnerData::name, and ResourceOwnerData::ncatlistrefs.
Referenced by ReleaseCatCacheList().
{ CatCList **catlistrefs = owner->catlistrefs; int nc1 = owner->ncatlistrefs - 1; int i; for (i = nc1; i >= 0; i--) { if (catlistrefs[i] == list) { while (i < nc1) { catlistrefs[i] = catlistrefs[i + 1]; i++; } owner->ncatlistrefs = nc1; return; } } elog(ERROR, "catcache list reference %p is not owned by resource owner %s", list, owner->name); }
void ResourceOwnerForgetCatCacheRef | ( | ResourceOwner | owner, | |
HeapTuple | tuple | |||
) |
Definition at line 731 of file resowner.c.
References ResourceOwnerData::catrefs, elog, ERROR, i, ResourceOwnerData::name, and ResourceOwnerData::ncatrefs.
Referenced by ReleaseCatCache().
{ HeapTuple *catrefs = owner->catrefs; int nc1 = owner->ncatrefs - 1; int i; for (i = nc1; i >= 0; i--) { if (catrefs[i] == tuple) { while (i < nc1) { catrefs[i] = catrefs[i + 1]; i++; } owner->ncatrefs = nc1; return; } } elog(ERROR, "catcache reference %p is not owned by resource owner %s", tuple, owner->name); }
void ResourceOwnerForgetFile | ( | ResourceOwner | owner, | |
File | file | |||
) |
Definition at line 1199 of file resowner.c.
References elog, ERROR, ResourceOwnerData::files, i, ResourceOwnerData::name, and ResourceOwnerData::nfiles.
Referenced by FileClose().
void ResourceOwnerForgetLock | ( | ResourceOwner | owner, | |
LOCALLOCK * | locallock | |||
) |
Definition at line 662 of file resowner.c.
References Assert, elog, ERROR, i, ResourceOwnerData::locks, MAX_RESOWNER_LOCKS, ResourceOwnerData::name, and ResourceOwnerData::nlocks.
Referenced by LockReassignOwner(), LockRelease(), LockReleaseAll(), ReleaseLockIfHeld(), and RemoveLocalLock().
{ int i; if (owner->nlocks > MAX_RESOWNER_LOCKS) return; /* we have overflowed */ Assert(owner->nlocks > 0); for (i = owner->nlocks - 1; i >= 0; i--) { if (locallock == owner->locks[i]) { owner->locks[i] = owner->locks[owner->nlocks - 1]; owner->nlocks--; return; } } elog(ERROR, "lock reference %p is not owned by resource owner %s", locallock, owner->name); }
void ResourceOwnerForgetPlanCacheRef | ( | ResourceOwner | owner, | |
CachedPlan * | plan | |||
) |
Definition at line 954 of file resowner.c.
References elog, ERROR, i, ResourceOwnerData::name, ResourceOwnerData::nplanrefs, and ResourceOwnerData::planrefs.
Referenced by ReleaseCachedPlan().
{ CachedPlan **planrefs = owner->planrefs; int np1 = owner->nplanrefs - 1; int i; for (i = np1; i >= 0; i--) { if (planrefs[i] == plan) { while (i < np1) { planrefs[i] = planrefs[i + 1]; i++; } owner->nplanrefs = np1; return; } } elog(ERROR, "plancache reference %p is not owned by resource owner %s", plan, owner->name); }
void ResourceOwnerForgetRelationRef | ( | ResourceOwner | owner, | |
Relation | rel | |||
) |
Definition at line 873 of file resowner.c.
References elog, ERROR, i, ResourceOwnerData::name, ResourceOwnerData::nrelrefs, RelationGetRelationName, and ResourceOwnerData::relrefs.
Referenced by RelationDecrementReferenceCount().
{ Relation *relrefs = owner->relrefs; int nr1 = owner->nrelrefs - 1; int i; for (i = nr1; i >= 0; i--) { if (relrefs[i] == rel) { while (i < nr1) { relrefs[i] = relrefs[i + 1]; i++; } owner->nrelrefs = nr1; return; } } elog(ERROR, "relcache reference %s is not owned by resource owner %s", RelationGetRelationName(rel), owner->name); }
void ResourceOwnerForgetSnapshot | ( | ResourceOwner | owner, | |
Snapshot | snapshot | |||
) |
Definition at line 1116 of file resowner.c.
References elog, ERROR, i, ResourceOwnerData::name, ResourceOwnerData::nsnapshots, and ResourceOwnerData::snapshots.
Referenced by UnregisterSnapshotFromOwner().
{ Snapshot *snapshots = owner->snapshots; int ns1 = owner->nsnapshots - 1; int i; for (i = ns1; i >= 0; i--) { if (snapshots[i] == snapshot) { while (i < ns1) { snapshots[i] = snapshots[i + 1]; i++; } owner->nsnapshots = ns1; return; } } elog(ERROR, "snapshot reference %p is not owned by resource owner %s", snapshot, owner->name); }
void ResourceOwnerForgetTupleDesc | ( | ResourceOwner | owner, | |
TupleDesc | tupdesc | |||
) |
Definition at line 1034 of file resowner.c.
References elog, ERROR, i, ResourceOwnerData::name, ResourceOwnerData::ntupdescs, and ResourceOwnerData::tupdescs.
Referenced by DecrTupleDescRefCount().
{ TupleDesc *tupdescs = owner->tupdescs; int nt1 = owner->ntupdescs - 1; int i; for (i = nt1; i >= 0; i--) { if (tupdescs[i] == tupdesc) { while (i < nt1) { tupdescs[i] = tupdescs[i + 1]; i++; } owner->ntupdescs = nt1; return; } } elog(ERROR, "tupdesc reference %p is not owned by resource owner %s", tupdesc, owner->name); }
ResourceOwner ResourceOwnerGetParent | ( | ResourceOwner | owner | ) |
Definition at line 449 of file resowner.c.
References ResourceOwnerData::parent.
Referenced by LockReassignCurrentOwner().
{ return owner->parent; }
void ResourceOwnerNewParent | ( | ResourceOwner | owner, | |
ResourceOwner | newparent | |||
) |
Definition at line 458 of file resowner.c.
References Assert, ResourceOwnerData::firstchild, ResourceOwnerData::nextchild, and ResourceOwnerData::parent.
Referenced by AtSubCommit_Portals(), and ResourceOwnerDelete().
{ ResourceOwner oldparent = owner->parent; if (oldparent) { if (owner == oldparent->firstchild) oldparent->firstchild = owner->nextchild; else { ResourceOwner child; for (child = oldparent->firstchild; child; child = child->nextchild) { if (owner == child->nextchild) { child->nextchild = owner->nextchild; break; } } } } if (newparent) { Assert(owner != newparent); owner->parent = newparent; owner->nextchild = newparent->firstchild; newparent->firstchild = owner; } else { owner->parent = NULL; owner->nextchild = NULL; } }
void ResourceOwnerRelease | ( | ResourceOwner | owner, | |
ResourceReleasePhase | phase, | |||
bool | isCommit, | |||
bool | isTopLevel | |||
) |
Definition at line 195 of file resowner.c.
References PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, and ResourceOwnerReleaseInternal().
Referenced by AbortSubTransaction(), AbortTransaction(), BackgroundWriterMain(), CheckpointerMain(), CommitSubTransaction(), CommitTransaction(), PortalDrop(), PrepareTransaction(), and WalWriterMain().
{ /* Rather than PG_TRY at every level of recursion, set it up once */ ResourceOwner save; save = CurrentResourceOwner; PG_TRY(); { ResourceOwnerReleaseInternal(owner, phase, isCommit, isTopLevel); } PG_CATCH(); { CurrentResourceOwner = save; PG_RE_THROW(); } PG_END_TRY(); CurrentResourceOwner = save; }
static void ResourceOwnerReleaseInternal | ( | ResourceOwner | owner, | |
ResourceReleasePhase | phase, | |||
bool | isCommit, | |||
bool | isTopLevel | |||
) | [static] |
Definition at line 218 of file resowner.c.
References ResourceReleaseCallbackItem::arg, Assert, ResourceOwnerData::buffers, ResourceReleaseCallbackItem::callback, ResourceOwnerData::catlistrefs, ResourceOwnerData::catrefs, DecrTupleDescRefCount(), FileClose(), ResourceOwnerData::files, ResourceOwnerData::firstchild, LockReassignCurrentOwner(), LockReleaseCurrentOwner(), ResourceOwnerData::locks, MAX_RESOWNER_LOCKS, ResourceOwnerData::nbuffers, ResourceOwnerData::ncatlistrefs, ResourceOwnerData::ncatrefs, ResourceReleaseCallbackItem::next, ResourceOwnerData::nextchild, ResourceOwnerData::nfiles, ResourceOwnerData::nlocks, ResourceOwnerData::nplanrefs, ResourceOwnerData::nrelrefs, ResourceOwnerData::nsnapshots, ResourceOwnerData::ntupdescs, NULL, ResourceOwnerData::parent, ResourceOwnerData::planrefs, PrintBufferLeakWarning(), PrintCatCacheLeakWarning(), PrintCatCacheListLeakWarning(), PrintFileLeakWarning(), PrintPlanCacheLeakWarning(), PrintRelCacheLeakWarning(), PrintSnapshotLeakWarning(), PrintTupleDescLeakWarning(), ProcReleaseLocks(), RelationClose(), ReleaseBuffer(), ReleaseCachedPlan(), ReleaseCatCache(), ReleaseCatCacheList(), ReleasePredicateLocks(), ReleaseResources_hash(), ResourceOwnerData::relrefs, RESOURCE_RELEASE_AFTER_LOCKS, RESOURCE_RELEASE_BEFORE_LOCKS, RESOURCE_RELEASE_LOCKS, ResourceOwnerData::snapshots, ResourceOwnerData::tupdescs, and UnregisterSnapshot().
Referenced by ResourceOwnerRelease().
{ ResourceOwner child; ResourceOwner save; ResourceReleaseCallbackItem *item; /* Recurse to handle descendants */ for (child = owner->firstchild; child != NULL; child = child->nextchild) ResourceOwnerReleaseInternal(child, phase, isCommit, isTopLevel); /* * Make CurrentResourceOwner point to me, so that ReleaseBuffer etc don't * get confused. We needn't PG_TRY here because the outermost level will * fix it on error abort. */ save = CurrentResourceOwner; CurrentResourceOwner = owner; if (phase == RESOURCE_RELEASE_BEFORE_LOCKS) { /* * Release buffer pins. Note that ReleaseBuffer will remove the * buffer entry from my list, so I just have to iterate till there are * none. * * During a commit, there shouldn't be any remaining pins --- that * would indicate failure to clean up the executor correctly --- so * issue warnings. In the abort case, just clean up quietly. * * We are careful to do the releasing back-to-front, so as to avoid * O(N^2) behavior in ResourceOwnerForgetBuffer(). */ while (owner->nbuffers > 0) { if (isCommit) PrintBufferLeakWarning(owner->buffers[owner->nbuffers - 1]); ReleaseBuffer(owner->buffers[owner->nbuffers - 1]); } /* * Release relcache references. Note that RelationClose will remove * the relref entry from my list, so I just have to iterate till there * are none. * * As with buffer pins, warn if any are left at commit time, and * release back-to-front for speed. */ while (owner->nrelrefs > 0) { if (isCommit) PrintRelCacheLeakWarning(owner->relrefs[owner->nrelrefs - 1]); RelationClose(owner->relrefs[owner->nrelrefs - 1]); } } else if (phase == RESOURCE_RELEASE_LOCKS) { if (isTopLevel) { /* * For a top-level xact we are going to release all locks (or at * least all non-session locks), so just do a single lmgr call at * the top of the recursion. */ if (owner == TopTransactionResourceOwner) { ProcReleaseLocks(isCommit); ReleasePredicateLocks(isCommit); } } else { /* * Release locks retail. Note that if we are committing a * subtransaction, we do NOT release its locks yet, but transfer * them to the parent. */ LOCALLOCK **locks; int nlocks; Assert(owner->parent != NULL); /* * Pass the list of locks owned by this resource owner to the lock * manager, unless it has overflowed. */ if (owner->nlocks > MAX_RESOWNER_LOCKS) { locks = NULL; nlocks = 0; } else { locks = owner->locks; nlocks = owner->nlocks; } if (isCommit) LockReassignCurrentOwner(locks, nlocks); else LockReleaseCurrentOwner(locks, nlocks); } } else if (phase == RESOURCE_RELEASE_AFTER_LOCKS) { /* * Release catcache references. Note that ReleaseCatCache will remove * the catref entry from my list, so I just have to iterate till there * are none. * * As with buffer pins, warn if any are left at commit time, and * release back-to-front for speed. */ while (owner->ncatrefs > 0) { if (isCommit) PrintCatCacheLeakWarning(owner->catrefs[owner->ncatrefs - 1]); ReleaseCatCache(owner->catrefs[owner->ncatrefs - 1]); } /* Ditto for catcache lists */ while (owner->ncatlistrefs > 0) { if (isCommit) PrintCatCacheListLeakWarning(owner->catlistrefs[owner->ncatlistrefs - 1]); ReleaseCatCacheList(owner->catlistrefs[owner->ncatlistrefs - 1]); } /* Ditto for plancache references */ while (owner->nplanrefs > 0) { if (isCommit) PrintPlanCacheLeakWarning(owner->planrefs[owner->nplanrefs - 1]); ReleaseCachedPlan(owner->planrefs[owner->nplanrefs - 1], true); } /* Ditto for tupdesc references */ while (owner->ntupdescs > 0) { if (isCommit) PrintTupleDescLeakWarning(owner->tupdescs[owner->ntupdescs - 1]); DecrTupleDescRefCount(owner->tupdescs[owner->ntupdescs - 1]); } /* Ditto for snapshot references */ while (owner->nsnapshots > 0) { if (isCommit) PrintSnapshotLeakWarning(owner->snapshots[owner->nsnapshots - 1]); UnregisterSnapshot(owner->snapshots[owner->nsnapshots - 1]); } /* Ditto for temporary files */ while (owner->nfiles > 0) { if (isCommit) PrintFileLeakWarning(owner->files[owner->nfiles - 1]); FileClose(owner->files[owner->nfiles - 1]); } /* Clean up index scans too */ ReleaseResources_hash(); } /* Let add-on modules get a chance too */ for (item = ResourceRelease_callbacks; item; item = item->next) (*item->callback) (phase, isCommit, isTopLevel, item->arg); CurrentResourceOwner = save; }
void ResourceOwnerRememberBuffer | ( | ResourceOwner | owner, | |
Buffer | buffer | |||
) |
Definition at line 585 of file resowner.c.
References Assert, ResourceOwnerData::buffers, ResourceOwnerData::maxbuffers, ResourceOwnerData::nbuffers, and NULL.
Referenced by IncrBufferRefCount(), LocalBufferAlloc(), PinBuffer(), and PinBuffer_Locked().
void ResourceOwnerRememberCatCacheListRef | ( | ResourceOwner | owner, | |
CatCList * | list | |||
) |
Definition at line 791 of file resowner.c.
References Assert, ResourceOwnerData::catlistrefs, ResourceOwnerData::maxcatlistrefs, and ResourceOwnerData::ncatlistrefs.
Referenced by SearchCatCacheList().
{ Assert(owner->ncatlistrefs < owner->maxcatlistrefs); owner->catlistrefs[owner->ncatlistrefs] = list; owner->ncatlistrefs++; }
void ResourceOwnerRememberCatCacheRef | ( | ResourceOwner | owner, | |
HeapTuple | tuple | |||
) |
Definition at line 720 of file resowner.c.
References Assert, ResourceOwnerData::catrefs, ResourceOwnerData::maxcatrefs, and ResourceOwnerData::ncatrefs.
Referenced by SearchCatCache().
void ResourceOwnerRememberFile | ( | ResourceOwner | owner, | |
File | file | |||
) |
Definition at line 1188 of file resowner.c.
References Assert, ResourceOwnerData::files, ResourceOwnerData::maxfiles, and ResourceOwnerData::nfiles.
Referenced by OpenTemporaryFile().
void ResourceOwnerRememberLock | ( | ResourceOwner | owner, | |
LOCALLOCK * | locallock | |||
) |
Definition at line 644 of file resowner.c.
References ResourceOwnerData::locks, MAX_RESOWNER_LOCKS, and ResourceOwnerData::nlocks.
Referenced by GrantLockLocal(), and LockReassignOwner().
{ if (owner->nlocks > MAX_RESOWNER_LOCKS) return; /* we have already overflowed */ if (owner->nlocks < MAX_RESOWNER_LOCKS) owner->locks[owner->nlocks] = locallock; else { /* overflowed */ } owner->nlocks++; }
void ResourceOwnerRememberPlanCacheRef | ( | ResourceOwner | owner, | |
CachedPlan * | plan | |||
) |
Definition at line 943 of file resowner.c.
References Assert, ResourceOwnerData::maxplanrefs, ResourceOwnerData::nplanrefs, and ResourceOwnerData::planrefs.
Referenced by GetCachedPlan().
void ResourceOwnerRememberRelationRef | ( | ResourceOwner | owner, | |
Relation | rel | |||
) |
Definition at line 862 of file resowner.c.
References Assert, ResourceOwnerData::maxrelrefs, ResourceOwnerData::nrelrefs, and ResourceOwnerData::relrefs.
Referenced by RelationIncrementReferenceCount().
void ResourceOwnerRememberSnapshot | ( | ResourceOwner | owner, | |
Snapshot | snapshot | |||
) |
Definition at line 1105 of file resowner.c.
References Assert, ResourceOwnerData::maxsnapshots, ResourceOwnerData::nsnapshots, and ResourceOwnerData::snapshots.
Referenced by RegisterSnapshotOnOwner().
{ Assert(owner->nsnapshots < owner->maxsnapshots); owner->snapshots[owner->nsnapshots] = snapshot; owner->nsnapshots++; }
void ResourceOwnerRememberTupleDesc | ( | ResourceOwner | owner, | |
TupleDesc | tupdesc | |||
) |
Definition at line 1023 of file resowner.c.
References Assert, ResourceOwnerData::maxtupdescs, ResourceOwnerData::ntupdescs, and ResourceOwnerData::tupdescs.
Referenced by IncrTupleDescRefCount().
void UnregisterResourceReleaseCallback | ( | ResourceReleaseCallback | callback, | |
void * | arg | |||
) |
Definition at line 520 of file resowner.c.
References ResourceReleaseCallbackItem::next, and pfree().
{ ResourceReleaseCallbackItem *item; ResourceReleaseCallbackItem *prev; prev = NULL; for (item = ResourceRelease_callbacks; item; prev = item, item = item->next) { if (item->callback == callback && item->arg == arg) { if (prev) prev->next = item->next; else ResourceRelease_callbacks = item->next; pfree(item); break; } } }
Definition at line 108 of file resowner.c.
Referenced by _hash_regscan(), AssignTransactionId(), AtAbort_ResourceOwner(), AtStart_ResourceOwner(), AtSubAbort_ResourceOwner(), AtSubStart_ResourceOwner(), BackgroundWriterMain(), BgBufferSync(), BufferSync(), CheckpointerMain(), CleanupSubTransaction(), CleanupTransaction(), close_lo_relation(), CommitSubTransaction(), CommitTransaction(), DecrTupleDescRefCount(), exec_init_tuple_store(), exec_stmt_block(), FlushDatabaseBuffers(), FlushRelationBuffers(), GetCachedPlan(), IncrBufferRefCount(), IncrTupleDescRefCount(), InitWalSender(), LocalBufferAlloc(), LockAcquireExtended(), LockReassignCurrentOwner(), LockReassignOwner(), LockRelease(), open_lo_relation(), open_share_lock(), OpenTemporaryFile(), PersistHoldablePortal(), PinBuffer(), PinBuffer_Locked(), plperl_spi_exec(), plperl_spi_exec_prepared(), plperl_spi_fetchrow(), plperl_spi_prepare(), plperl_spi_query(), plperl_spi_query_prepared(), plpgsql_estate_setup(), pltcl_SPI_execute(), pltcl_SPI_execute_plan(), pltcl_SPI_prepare(), pltcl_subtrans_abort(), pltcl_subtrans_commit(), PLy_abort_open_subtransactions(), PLy_cursor_fetch(), PLy_cursor_iternext(), PLy_cursor_plan(), PLy_cursor_query(), PLy_spi_execute_plan(), PLy_spi_execute_query(), PLy_spi_prepare(), PLy_spi_subtransaction_abort(), PLy_spi_subtransaction_commit(), PLy_subtransaction_enter(), PLy_subtransaction_exit(), PopTransaction(), PortalCleanup(), PortalRun(), PortalRunFetch(), PortalStart(), PrepareTransaction(), ReadBuffer_common(), RegisterSnapshot(), RelationDecrementReferenceCount(), RelationIncrementReferenceCount(), ReleaseAndReadBuffer(), ReleaseBuffer(), ReleaseCachedPlan(), ReleaseCatCache(), ReleaseCatCacheList(), ReleaseLockIfHeld(), ReleaseResources_hash(), SearchCatCache(), SearchCatCacheList(), tuplestore_begin_common(), tuplestore_puttuple_common(), UnpinBuffer(), UnregisterSnapshot(), WalReceiverMain(), and WalWriterMain().
Definition at line 109 of file resowner.c.
Referenced by AtStart_ResourceOwner(), AtSubStart_ResourceOwner(), CleanupSubTransaction(), CleanupTransaction(), CommitSubTransaction(), CommitTransaction(), CreatePortal(), PopTransaction(), and PrepareTransaction().
ResourceReleaseCallbackItem* ResourceRelease_callbacks = NULL [static] |
Definition at line 122 of file resowner.c.
Definition at line 110 of file resowner.c.
Referenced by AbortTransaction(), AtAbort_ResourceOwner(), AtStart_ResourceOwner(), CleanupTransaction(), close_lo_relation(), CommitTransaction(), inv_close(), inv_open(), open_lo_relation(), open_share_lock(), PortalRun(), and PrepareTransaction().