#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().
1.7.1