PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
resowner.c File Reference
#include "postgres.h"
#include "common/hashfn.h"
#include "common/int.h"
#include "lib/ilist.h"
#include "storage/aio.h"
#include "storage/ipc.h"
#include "storage/predicate.h"
#include "storage/proc.h"
#include "utils/memutils.h"
#include "utils/resowner.h"
Include dependency graph for resowner.c:

Go to the source code of this file.

Data Structures

struct  ResourceElem
 
struct  ResourceOwnerData
 
struct  ResourceReleaseCallbackItem
 

Macros

#define RESOWNER_ARRAY_SIZE   32
 
#define RESOWNER_HASH_INIT_SIZE   64
 
#define RESOWNER_HASH_MAX_ITEMS(capacity)    Min(capacity - RESOWNER_ARRAY_SIZE, (capacity)/4 * 3)
 
#define MAX_RESOWNER_LOCKS   15
 

Typedefs

typedef struct ResourceElem ResourceElem
 
typedef struct ResourceReleaseCallbackItem ResourceReleaseCallbackItem
 

Functions

 StaticAssertDecl (RESOWNER_HASH_MAX_ITEMS(RESOWNER_HASH_INIT_SIZE) >=RESOWNER_ARRAY_SIZE, "initial hash size too small compared to array size")
 
static uint32 hash_resource_elem (Datum value, const ResourceOwnerDesc *kind)
 
static void ResourceOwnerAddToHash (ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
 
static int resource_priority_cmp (const void *a, const void *b)
 
static void ResourceOwnerSort (ResourceOwner owner)
 
static void ResourceOwnerReleaseAll (ResourceOwner owner, ResourceReleasePhase phase, bool printLeakWarnings)
 
static void ResourceOwnerReleaseInternal (ResourceOwner owner, ResourceReleasePhase phase, bool isCommit, bool isTopLevel)
 
static void ReleaseAuxProcessResourcesCallback (int code, Datum arg)
 
ResourceOwner ResourceOwnerCreate (ResourceOwner parent, const char *name)
 
void ResourceOwnerEnlarge (ResourceOwner owner)
 
void ResourceOwnerRemember (ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
 
void ResourceOwnerForget (ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
 
void ResourceOwnerRelease (ResourceOwner owner, ResourceReleasePhase phase, bool isCommit, bool isTopLevel)
 
void ResourceOwnerReleaseAllOfKind (ResourceOwner owner, const ResourceOwnerDesc *kind)
 
void ResourceOwnerDelete (ResourceOwner owner)
 
ResourceOwner ResourceOwnerGetParent (ResourceOwner owner)
 
void ResourceOwnerNewParent (ResourceOwner owner, ResourceOwner newparent)
 
void RegisterResourceReleaseCallback (ResourceReleaseCallback callback, void *arg)
 
void UnregisterResourceReleaseCallback (ResourceReleaseCallback callback, void *arg)
 
void CreateAuxProcessResourceOwner (void)
 
void ReleaseAuxProcessResources (bool isCommit)
 
void ResourceOwnerRememberLock (ResourceOwner owner, LOCALLOCK *locallock)
 
void ResourceOwnerForgetLock (ResourceOwner owner, LOCALLOCK *locallock)
 
void ResourceOwnerRememberAioHandle (ResourceOwner owner, struct dlist_node *ioh_node)
 
void ResourceOwnerForgetAioHandle (ResourceOwner owner, struct dlist_node *ioh_node)
 

Variables

ResourceOwner CurrentResourceOwner = NULL
 
ResourceOwner CurTransactionResourceOwner = NULL
 
ResourceOwner TopTransactionResourceOwner = NULL
 
ResourceOwner AuxProcessResourceOwner = NULL
 
static ResourceReleaseCallbackItemResourceRelease_callbacks = NULL
 

Macro Definition Documentation

◆ MAX_RESOWNER_LOCKS

#define MAX_RESOWNER_LOCKS   15

Definition at line 107 of file resowner.c.

◆ RESOWNER_ARRAY_SIZE

#define RESOWNER_ARRAY_SIZE   32

Definition at line 73 of file resowner.c.

◆ RESOWNER_HASH_INIT_SIZE

#define RESOWNER_HASH_INIT_SIZE   64

Definition at line 79 of file resowner.c.

◆ RESOWNER_HASH_MAX_ITEMS

#define RESOWNER_HASH_MAX_ITEMS (   capacity)     Min(capacity - RESOWNER_ARRAY_SIZE, (capacity)/4 * 3)

Definition at line 91 of file resowner.c.

Typedef Documentation

◆ ResourceElem

typedef struct ResourceElem ResourceElem

◆ ResourceReleaseCallbackItem

Function Documentation

◆ CreateAuxProcessResourceOwner()

void CreateAuxProcessResourceOwner ( void  )

Definition at line 999 of file resowner.c.

1000{
1003 AuxProcessResourceOwner = ResourceOwnerCreate(NULL, "AuxiliaryProcess");
1005
1006 /*
1007 * Register a shmem-exit callback for cleanup of aux-process resource
1008 * owner. (This needs to run after, e.g., ShutdownXLOG.)
1009 */
1011}
Assert(PointerIsAligned(start, uint64))
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:365
static void ReleaseAuxProcessResourcesCallback(int code, Datum arg)
Definition: resowner.c:1044
ResourceOwner ResourceOwnerCreate(ResourceOwner parent, const char *name)
Definition: resowner.c:421
ResourceOwner CurrentResourceOwner
Definition: resowner.c:173
ResourceOwner AuxProcessResourceOwner
Definition: resowner.c:176

References Assert(), AuxProcessResourceOwner, CurrentResourceOwner, on_shmem_exit(), ReleaseAuxProcessResourcesCallback(), and ResourceOwnerCreate().

Referenced by AuxiliaryProcessMainCommon(), InitPostgres(), and InitWalSender().

◆ hash_resource_elem()

static uint32 hash_resource_elem ( Datum  value,
const ResourceOwnerDesc kind 
)
inlinestatic

Definition at line 222 of file resowner.c.

223{
224 /*
225 * Most resource kinds store a pointer in 'value', and pointers are unique
226 * all on their own. But some resources store plain integers (Files and
227 * Buffers as of this writing), so we want to incorporate the 'kind' in
228 * the hash too, otherwise those resources will collide a lot. But
229 * because there are only a few resource kinds like that - and only a few
230 * resource kinds to begin with - we don't need to work too hard to mix
231 * 'kind' into the hash. Just add it with hash_combine(), it perturbs the
232 * result enough for our purposes.
233 */
234#if SIZEOF_DATUM == 8
235 return hash_combine64(murmurhash64((uint64) value), (uint64) kind);
236#else
237 return hash_combine(murmurhash32((uint32) value), (uint32) kind);
238#endif
239}
uint64_t uint64
Definition: c.h:503
uint32_t uint32
Definition: c.h:502
static uint64 hash_combine64(uint64 a, uint64 b)
Definition: hashfn.h:80
static uint64 murmurhash64(uint64 data)
Definition: hashfn.h:106
static uint32 hash_combine(uint32 a, uint32 b)
Definition: hashfn.h:68
static uint32 murmurhash32(uint32 data)
Definition: hashfn.h:92
static struct @165 value

References hash_combine(), hash_combine64(), murmurhash32(), murmurhash64(), and value.

Referenced by ResourceOwnerAddToHash(), and ResourceOwnerForget().

◆ RegisterResourceReleaseCallback()

void RegisterResourceReleaseCallback ( ResourceReleaseCallback  callback,
void *  arg 
)

Definition at line 961 of file resowner.c.

962{
964
968 item->callback = callback;
969 item->arg = arg;
972}
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1256
MemoryContext TopMemoryContext
Definition: mcxt.c:165
void * arg
static ResourceReleaseCallbackItem * ResourceRelease_callbacks
Definition: resowner.c:195
struct ResourceReleaseCallbackItem * next
Definition: resowner.c:190
ResourceReleaseCallback callback
Definition: resowner.c:191
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:46

References ResourceReleaseCallbackItem::arg, arg, ResourceReleaseCallbackItem::callback, callback(), MemoryContextAlloc(), ResourceReleaseCallbackItem::next, ResourceRelease_callbacks, and TopMemoryContext.

◆ ReleaseAuxProcessResources()

void ReleaseAuxProcessResources ( bool  isCommit)

Definition at line 1019 of file resowner.c.

1020{
1021 /*
1022 * At this writing, the only thing that could actually get released is
1023 * buffer pins; but we may as well do the full release protocol.
1024 */
1027 isCommit, true);
1030 isCommit, true);
1033 isCommit, true);
1034 /* allow it to be reused */
1037}
void ResourceOwnerRelease(ResourceOwner owner, ResourceReleasePhase phase, bool isCommit, bool isTopLevel)
Definition: resowner.c:658
@ RESOURCE_RELEASE_LOCKS
Definition: resowner.h:55
@ RESOURCE_RELEASE_BEFORE_LOCKS
Definition: resowner.h:54
@ RESOURCE_RELEASE_AFTER_LOCKS
Definition: resowner.h:56

References AuxProcessResourceOwner, ResourceOwnerData::releasing, RESOURCE_RELEASE_AFTER_LOCKS, RESOURCE_RELEASE_BEFORE_LOCKS, RESOURCE_RELEASE_LOCKS, ResourceOwnerRelease(), and ResourceOwnerData::sorted.

Referenced by AutoVacLauncherMain(), BackgroundWriterMain(), CheckpointerMain(), InitPostgres(), perform_base_backup(), pgarch_archiveXlog(), ReleaseAuxProcessResourcesCallback(), UploadManifest(), WalSndErrorCleanup(), WalSummarizerMain(), and WalWriterMain().

◆ ReleaseAuxProcessResourcesCallback()

static void ReleaseAuxProcessResourcesCallback ( int  code,
Datum  arg 
)
static

Definition at line 1044 of file resowner.c.

1045{
1046 bool isCommit = (code == 0);
1047
1049}
void ReleaseAuxProcessResources(bool isCommit)
Definition: resowner.c:1019

References ReleaseAuxProcessResources().

Referenced by CreateAuxProcessResourceOwner().

◆ resource_priority_cmp()

static int resource_priority_cmp ( const void *  a,
const void *  b 
)
static

Definition at line 269 of file resowner.c.

270{
271 const ResourceElem *ra = (const ResourceElem *) a;
272 const ResourceElem *rb = (const ResourceElem *) b;
273
274 /* Note: reverse order */
275 if (ra->kind->release_phase == rb->kind->release_phase)
277 else if (ra->kind->release_phase > rb->kind->release_phase)
278 return -1;
279 else
280 return 1;
281}
static int pg_cmp_u32(uint32 a, uint32 b)
Definition: int.h:652
int b
Definition: isn.c:74
int a
Definition: isn.c:73
const ResourceOwnerDesc * kind
Definition: resowner.c:67
ResourceReleasePhase release_phase
Definition: resowner.h:96
ResourceReleasePriority release_priority
Definition: resowner.h:97

References a, b, ResourceElem::kind, pg_cmp_u32(), ResourceOwnerDesc::release_phase, and ResourceOwnerDesc::release_priority.

Referenced by ResourceOwnerSort().

◆ ResourceOwnerAddToHash()

static void ResourceOwnerAddToHash ( ResourceOwner  owner,
Datum  value,
const ResourceOwnerDesc kind 
)
static

Definition at line 245 of file resowner.c.

246{
247 uint32 mask = owner->capacity - 1;
248 uint32 idx;
249
250 Assert(kind != NULL);
251
252 /* Insert into first free slot at or after hash location. */
253 idx = hash_resource_elem(value, kind) & mask;
254 for (;;)
255 {
256 if (owner->hash[idx].kind == NULL)
257 break; /* found a free slot */
258 idx = (idx + 1) & mask;
259 }
260 owner->hash[idx].item = value;
261 owner->hash[idx].kind = kind;
262 owner->nhash++;
263}
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:262
static uint32 hash_resource_elem(Datum value, const ResourceOwnerDesc *kind)
Definition: resowner.c:222
Datum item
Definition: resowner.c:66
ResourceElem * hash
Definition: resowner.c:154

References Assert(), ResourceOwnerData::capacity, ResourceOwnerData::hash, hash_resource_elem(), idx(), ResourceElem::item, ResourceElem::kind, ResourceOwnerData::nhash, and value.

Referenced by ResourceOwnerEnlarge().

◆ ResourceOwnerCreate()

ResourceOwner ResourceOwnerCreate ( ResourceOwner  parent,
const char *  name 
)

Definition at line 421 of file resowner.c.

422{
423 ResourceOwner owner;
424
426 sizeof(struct ResourceOwnerData));
427 owner->name = name;
428
429 if (parent)
430 {
431 owner->parent = parent;
432 owner->nextchild = parent->firstchild;
433 parent->firstchild = owner;
434 }
435
436 dlist_init(&owner->aio_handles);
437
438 return owner;
439}
static void dlist_init(dlist_head *head)
Definition: ilist.h:314
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1290
struct ResourceOwnerData * ResourceOwner
Definition: resowner.h:27
ResourceOwner parent
Definition: resowner.c:114
dlist_head aio_handles
Definition: resowner.c:165
const char * name
Definition: resowner.c:117
ResourceOwner nextchild
Definition: resowner.c:116
ResourceOwner firstchild
Definition: resowner.c:115
const char * name

References ResourceOwnerData::aio_handles, dlist_init(), ResourceOwnerData::firstchild, MemoryContextAllocZero(), name, ResourceOwnerData::name, ResourceOwnerData::nextchild, ResourceOwnerData::parent, and TopMemoryContext.

Referenced by AtStart_ResourceOwner(), AtSubStart_ResourceOwner(), CreateAuxProcessResourceOwner(), CreatePortal(), plpgsql_call_handler(), plpgsql_create_econtext(), plpgsql_inline_handler(), test_dsa_resowners(), test_resowner_forget_between_phases(), test_resowner_leak(), test_resowner_many(), test_resowner_priorities(), and test_resowner_remember_between_phases().

◆ ResourceOwnerDelete()

void ResourceOwnerDelete ( ResourceOwner  owner)

Definition at line 871 of file resowner.c.

872{
873 /* We had better not be deleting CurrentResourceOwner ... */
875
876 /* And it better not own any resources, either */
877 Assert(owner->narr == 0);
878 Assert(owner->nhash == 0);
879 Assert(owner->nlocks == 0 || owner->nlocks == MAX_RESOWNER_LOCKS + 1);
880
881 /*
882 * Delete children. The recursive call will delink the child from me, so
883 * just iterate as long as there is a child.
884 */
885 while (owner->firstchild != NULL)
887
888 /*
889 * We delink the owner from its parent before deleting it, so that if
890 * there's an error we won't have deleted/busted owners still attached to
891 * the owner tree. Better a leak than a crash.
892 */
893 ResourceOwnerNewParent(owner, NULL);
894
895 /* And free the object. */
896 if (owner->hash)
897 pfree(owner->hash);
898 pfree(owner);
899}
void pfree(void *pointer)
Definition: mcxt.c:2146
void ResourceOwnerNewParent(ResourceOwner owner, ResourceOwner newparent)
Definition: resowner.c:914
#define MAX_RESOWNER_LOCKS
Definition: resowner.c:107
void ResourceOwnerDelete(ResourceOwner owner)
Definition: resowner.c:871

References Assert(), CurrentResourceOwner, ResourceOwnerData::firstchild, ResourceOwnerData::hash, MAX_RESOWNER_LOCKS, ResourceOwnerData::narr, ResourceOwnerData::nhash, ResourceOwnerData::nlocks, pfree(), ResourceOwnerDelete(), and ResourceOwnerNewParent().

Referenced by CleanupSubTransaction(), CleanupTransaction(), CommitSubTransaction(), CommitTransaction(), plpgsql_call_handler(), plpgsql_inline_handler(), PortalDrop(), PrepareTransaction(), ResourceOwnerDelete(), test_dsa_resowners(), test_resowner_leak(), test_resowner_many(), and test_resowner_priorities().

◆ ResourceOwnerEnlarge()

void ResourceOwnerEnlarge ( ResourceOwner  owner)

Definition at line 452 of file resowner.c.

453{
454 /*
455 * Mustn't try to remember more resources after we have already started
456 * releasing
457 */
458 if (owner->releasing)
459 elog(ERROR, "ResourceOwnerEnlarge called after release started");
460
461 if (owner->narr < RESOWNER_ARRAY_SIZE)
462 return; /* no work needed */
463
464 /*
465 * Is there space in the hash? If not, enlarge it.
466 */
467 if (owner->narr + owner->nhash >= owner->grow_at)
468 {
469 uint32 i,
470 oldcap,
471 newcap;
472 ResourceElem *oldhash;
473 ResourceElem *newhash;
474
475 oldhash = owner->hash;
476 oldcap = owner->capacity;
477
478 /* Double the capacity (it must stay a power of 2!) */
479 newcap = (oldcap > 0) ? oldcap * 2 : RESOWNER_HASH_INIT_SIZE;
481 newcap * sizeof(ResourceElem));
482
483 /*
484 * We assume we can't fail below this point, so OK to scribble on the
485 * owner
486 */
487 owner->hash = newhash;
488 owner->capacity = newcap;
489 owner->grow_at = RESOWNER_HASH_MAX_ITEMS(newcap);
490 owner->nhash = 0;
491
492 if (oldhash != NULL)
493 {
494 /*
495 * Transfer any pre-existing entries into the new hash table; they
496 * don't necessarily go where they were before, so this simple
497 * logic is the best way.
498 */
499 for (i = 0; i < oldcap; i++)
500 {
501 if (oldhash[i].kind != NULL)
502 ResourceOwnerAddToHash(owner, oldhash[i].item, oldhash[i].kind);
503 }
504
505 /* And release old hash table. */
506 pfree(oldhash);
507 }
508 }
509
510 /* Move items from the array to the hash */
511 for (int i = 0; i < owner->narr; i++)
512 ResourceOwnerAddToHash(owner, owner->arr[i].item, owner->arr[i].kind);
513 owner->narr = 0;
514
515 Assert(owner->nhash <= owner->grow_at);
516}
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:226
int i
Definition: isn.c:77
#define RESOWNER_HASH_INIT_SIZE
Definition: resowner.c:79
#define RESOWNER_HASH_MAX_ITEMS(capacity)
Definition: resowner.c:91
static void ResourceOwnerAddToHash(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition: resowner.c:245
#define RESOWNER_ARRAY_SIZE
Definition: resowner.c:73
ResourceElem arr[RESOWNER_ARRAY_SIZE]
Definition: resowner.c:142

References ResourceOwnerData::arr, Assert(), ResourceOwnerData::capacity, elog, ERROR, ResourceOwnerData::grow_at, ResourceOwnerData::hash, i, ResourceElem::item, ResourceElem::kind, MemoryContextAllocZero(), ResourceOwnerData::narr, ResourceOwnerData::nhash, pfree(), ResourceOwnerData::releasing, ResourceOwnerAddToHash(), RESOWNER_ARRAY_SIZE, RESOWNER_HASH_INIT_SIZE, RESOWNER_HASH_MAX_ITEMS, and TopMemoryContext.

Referenced by BufferAlloc(), CachedPlanAllowsSimpleValidityCheck(), CachedPlanIsSimplyValid(), CreateWaitEventSet(), dsm_create_descriptor(), dsm_unpin_mapping(), EvictAllUnpinnedBuffers(), EvictRelUnpinnedBuffers(), EvictUnpinnedBuffer(), ExtendBufferedRelLocal(), ExtendBufferedRelShared(), FlushDatabaseBuffers(), FlushRelationBuffers(), FlushRelationsAllBuffers(), GetCachedPlan(), GetLocalVictimBuffer(), GetVictimBuffer(), IncrBufferRefCount(), IncrTupleDescRefCount(), llvm_create_context(), LocalBufferAlloc(), OpenTemporaryFile(), PathNameCreateTemporaryFile(), PathNameOpenTemporaryFile(), pg_cryptohash_create(), pg_hmac_create(), px_find_cipher(), px_find_digest(), ReadRecentBuffer(), RegisterSnapshotOnOwner(), RelationIncrementReferenceCount(), RememberManyTestResources(), SearchCatCacheInternal(), SearchCatCacheList(), SearchCatCacheMiss(), StartBufferIO(), SyncOneBuffer(), test_resowner_forget_between_phases(), test_resowner_leak(), test_resowner_priorities(), and test_resowner_remember_between_phases().

◆ ResourceOwnerForget()

void ResourceOwnerForget ( ResourceOwner  owner,
Datum  value,
const ResourceOwnerDesc kind 
)

Definition at line 564 of file resowner.c.

565{
566 /*
567 * Mustn't call this after we have already started releasing resources.
568 * (Release callback functions are not allowed to release additional
569 * resources.)
570 */
571 if (owner->releasing)
572 elog(ERROR, "ResourceOwnerForget called for %s after release started", kind->name);
573 Assert(!owner->sorted);
574
575 /* Search through all items in the array first. */
576 for (int i = owner->narr - 1; i >= 0; i--)
577 {
578 if (owner->arr[i].item == value &&
579 owner->arr[i].kind == kind)
580 {
581 owner->arr[i] = owner->arr[owner->narr - 1];
582 owner->narr--;
583
584#ifdef RESOWNER_STATS
585 narray_lookups++;
586#endif
587 return;
588 }
589 }
590
591 /* Search hash */
592 if (owner->nhash > 0)
593 {
594 uint32 mask = owner->capacity - 1;
595 uint32 idx;
596
597 idx = hash_resource_elem(value, kind) & mask;
598 for (uint32 i = 0; i < owner->capacity; i++)
599 {
600 if (owner->hash[idx].item == value &&
601 owner->hash[idx].kind == kind)
602 {
603 owner->hash[idx].item = (Datum) 0;
604 owner->hash[idx].kind = NULL;
605 owner->nhash--;
606
607#ifdef RESOWNER_STATS
608 nhash_lookups++;
609#endif
610 return;
611 }
612 idx = (idx + 1) & mask;
613 }
614 }
615
616 /*
617 * Use %p to print the reference, since most objects tracked by a resource
618 * owner are pointers. It's a bit misleading if it's not a pointer, but
619 * this is a programmer error, anyway.
620 */
621 elog(ERROR, "%s %p is not owned by resource owner %s",
622 kind->name, DatumGetPointer(value), owner->name);
623}
uintptr_t Datum
Definition: postgres.h:69
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:317
const char * name
Definition: resowner.h:93

References ResourceOwnerData::arr, Assert(), ResourceOwnerData::capacity, DatumGetPointer(), elog, ERROR, ResourceOwnerData::hash, hash_resource_elem(), i, idx(), ResourceElem::item, ResourceElem::kind, ResourceOwnerData::name, ResourceOwnerDesc::name, ResourceOwnerData::narr, ResourceOwnerData::nhash, ResourceOwnerData::releasing, ResourceOwnerData::sorted, and value.

Referenced by ForgetManyTestResources(), ResourceOwnerForgetBuffer(), ResourceOwnerForgetBufferIO(), ResourceOwnerForgetCatCacheListRef(), ResourceOwnerForgetCatCacheRef(), ResourceOwnerForgetCryptoHash(), ResourceOwnerForgetDSM(), ResourceOwnerForgetFile(), ResourceOwnerForgetHMAC(), ResourceOwnerForgetJIT(), ResourceOwnerForgetOSSLCipher(), ResourceOwnerForgetOSSLDigest(), ResourceOwnerForgetPlanCacheRef(), ResourceOwnerForgetRelationRef(), ResourceOwnerForgetSnapshot(), ResourceOwnerForgetTupleDesc(), ResourceOwnerForgetWaitEventSet(), and test_resowner_forget_between_phases().

◆ ResourceOwnerForgetAioHandle()

void ResourceOwnerForgetAioHandle ( ResourceOwner  owner,
struct dlist_node ioh_node 
)

Definition at line 1110 of file resowner.c.

1111{
1112 dlist_delete_from(&owner->aio_handles, ioh_node);
1113}
static void dlist_delete_from(dlist_head *head, dlist_node *node)
Definition: ilist.h:429

References ResourceOwnerData::aio_handles, and dlist_delete_from().

Referenced by pgaio_io_reclaim(), and pgaio_io_release_resowner().

◆ ResourceOwnerForgetLock()

void ResourceOwnerForgetLock ( ResourceOwner  owner,
LOCALLOCK locallock 
)

Definition at line 1082 of file resowner.c.

1083{
1084 int i;
1085
1086 if (owner->nlocks > MAX_RESOWNER_LOCKS)
1087 return; /* we have overflowed */
1088
1089 Assert(owner->nlocks > 0);
1090 for (i = owner->nlocks - 1; i >= 0; i--)
1091 {
1092 if (locallock == owner->locks[i])
1093 {
1094 owner->locks[i] = owner->locks[owner->nlocks - 1];
1095 owner->nlocks--;
1096 return;
1097 }
1098 }
1099 elog(ERROR, "lock reference %p is not owned by resource owner %s",
1100 locallock, owner->name);
1101}
LOCALLOCK * locks[MAX_RESOWNER_LOCKS]
Definition: resowner.c:159

References Assert(), elog, ERROR, i, ResourceOwnerData::locks, MAX_RESOWNER_LOCKS, ResourceOwnerData::name, and ResourceOwnerData::nlocks.

Referenced by LockReassignOwner(), LockRelease(), LockReleaseAll(), ReleaseLockIfHeld(), and RemoveLocalLock().

◆ ResourceOwnerGetParent()

ResourceOwner ResourceOwnerGetParent ( ResourceOwner  owner)

Definition at line 905 of file resowner.c.

906{
907 return owner->parent;
908}

References ResourceOwnerData::parent.

Referenced by LockReassignCurrentOwner().

◆ ResourceOwnerNewParent()

void ResourceOwnerNewParent ( ResourceOwner  owner,
ResourceOwner  newparent 
)

Definition at line 914 of file resowner.c.

916{
917 ResourceOwner oldparent = owner->parent;
918
919 if (oldparent)
920 {
921 if (owner == oldparent->firstchild)
922 oldparent->firstchild = owner->nextchild;
923 else
924 {
925 ResourceOwner child;
926
927 for (child = oldparent->firstchild; child; child = child->nextchild)
928 {
929 if (owner == child->nextchild)
930 {
931 child->nextchild = owner->nextchild;
932 break;
933 }
934 }
935 }
936 }
937
938 if (newparent)
939 {
940 Assert(owner != newparent);
941 owner->parent = newparent;
942 owner->nextchild = newparent->firstchild;
943 newparent->firstchild = owner;
944 }
945 else
946 {
947 owner->parent = NULL;
948 owner->nextchild = NULL;
949 }
950}

References Assert(), ResourceOwnerData::firstchild, ResourceOwnerData::nextchild, and ResourceOwnerData::parent.

Referenced by AtSubAbort_Portals(), AtSubCommit_Portals(), and ResourceOwnerDelete().

◆ ResourceOwnerRelease()

void ResourceOwnerRelease ( ResourceOwner  owner,
ResourceReleasePhase  phase,
bool  isCommit,
bool  isTopLevel 
)

Definition at line 658 of file resowner.c.

662{
663 /* There's not currently any setup needed before recursing */
664 ResourceOwnerReleaseInternal(owner, phase, isCommit, isTopLevel);
665
666#ifdef RESOWNER_STATS
667 if (isTopLevel)
668 {
669 elog(LOG, "RESOWNER STATS: lookups: array %d, hash %d",
670 narray_lookups, nhash_lookups);
671 narray_lookups = 0;
672 nhash_lookups = 0;
673 }
674#endif
675}
#define LOG
Definition: elog.h:31
static void ResourceOwnerReleaseInternal(ResourceOwner owner, ResourceReleasePhase phase, bool isCommit, bool isTopLevel)
Definition: resowner.c:678

References elog, LOG, and ResourceOwnerReleaseInternal().

Referenced by AbortSubTransaction(), AbortTransaction(), CommitSubTransaction(), CommitTransaction(), PortalDrop(), PrepareTransaction(), ReleaseAuxProcessResources(), test_dsa_resowners(), test_resowner_forget_between_phases(), test_resowner_leak(), test_resowner_many(), test_resowner_priorities(), and test_resowner_remember_between_phases().

◆ ResourceOwnerReleaseAll()

static void ResourceOwnerReleaseAll ( ResourceOwner  owner,
ResourceReleasePhase  phase,
bool  printLeakWarnings 
)
static

Definition at line 348 of file resowner.c.

350{
353
354 /*
355 * ResourceOwnerSort must've been called already. All the resources are
356 * either in the array or the hash.
357 */
358 Assert(owner->releasing);
359 Assert(owner->sorted);
360 if (owner->nhash == 0)
361 {
362 items = owner->arr;
363 nitems = owner->narr;
364 }
365 else
366 {
367 Assert(owner->narr == 0);
368 items = owner->hash;
369 nitems = owner->nhash;
370 }
371
372 /*
373 * The resources are sorted in reverse priority order. Release them
374 * starting from the end, until we hit the end of the phase that we are
375 * releasing now. We will continue from there when called again for the
376 * next phase.
377 */
378 while (nitems > 0)
379 {
380 uint32 idx = nitems - 1;
381 Datum value = items[idx].item;
382 const ResourceOwnerDesc *kind = items[idx].kind;
383
384 if (kind->release_phase > phase)
385 break;
386 Assert(kind->release_phase == phase);
387
388 if (printLeakWarnings)
389 {
390 char *res_str;
391
392 res_str = kind->DebugPrint ?
393 kind->DebugPrint(value)
394 : psprintf("%s %p", kind->name, DatumGetPointer(value));
395 elog(WARNING, "resource was not closed: %s", res_str);
396 pfree(res_str);
397 }
398 kind->ReleaseResource(value);
399 nitems--;
400 }
401 if (owner->nhash == 0)
402 owner->narr = nitems;
403 else
404 owner->nhash = nitems;
405}
#define WARNING
Definition: elog.h:36
#define nitems(x)
Definition: indent.h:31
char * psprintf(const char *fmt,...)
Definition: psprintf.c:43
char *(* DebugPrint)(Datum res)
Definition: resowner.h:118
void(* ReleaseResource)(Datum res)
Definition: resowner.h:108
static ItemArray items
Definition: test_tidstore.c:48

References ResourceOwnerData::arr, Assert(), DatumGetPointer(), ResourceOwnerDesc::DebugPrint, elog, ResourceOwnerData::hash, idx(), items, ResourceOwnerDesc::name, ResourceOwnerData::narr, ResourceOwnerData::nhash, nitems, pfree(), psprintf(), ResourceOwnerDesc::release_phase, ResourceOwnerDesc::ReleaseResource, ResourceOwnerData::releasing, ResourceOwnerData::sorted, value, and WARNING.

Referenced by ResourceOwnerReleaseInternal().

◆ ResourceOwnerReleaseAllOfKind()

void ResourceOwnerReleaseAllOfKind ( ResourceOwner  owner,
const ResourceOwnerDesc kind 
)

Definition at line 818 of file resowner.c.

819{
820 /* Mustn't call this after we have already started releasing resources. */
821 if (owner->releasing)
822 elog(ERROR, "ResourceOwnerForget called for %s after release started", kind->name);
823 Assert(!owner->sorted);
824
825 /*
826 * Temporarily set 'releasing', to prevent calls to ResourceOwnerRemember
827 * while we're scanning the owner. Enlarging the hash would cause us to
828 * lose track of the point we're scanning.
829 */
830 owner->releasing = true;
831
832 /* Array first */
833 for (int i = 0; i < owner->narr; i++)
834 {
835 if (owner->arr[i].kind == kind)
836 {
837 Datum value = owner->arr[i].item;
838
839 owner->arr[i] = owner->arr[owner->narr - 1];
840 owner->narr--;
841 i--;
842
843 kind->ReleaseResource(value);
844 }
845 }
846
847 /* Then hash */
848 for (int i = 0; i < owner->capacity; i++)
849 {
850 if (owner->hash[i].kind == kind)
851 {
852 Datum value = owner->hash[i].item;
853
854 owner->hash[i].item = (Datum) 0;
855 owner->hash[i].kind = NULL;
856 owner->nhash--;
857
858 kind->ReleaseResource(value);
859 }
860 }
861 owner->releasing = false;
862}

References ResourceOwnerData::arr, Assert(), ResourceOwnerData::capacity, elog, ERROR, ResourceOwnerData::hash, i, ResourceElem::item, ResourceElem::kind, ResourceOwnerDesc::name, ResourceOwnerData::narr, ResourceOwnerData::nhash, ResourceOwnerDesc::ReleaseResource, ResourceOwnerData::releasing, ResourceOwnerData::sorted, and value.

Referenced by ReleaseAllPlanCacheRefsInOwner().

◆ ResourceOwnerReleaseInternal()

static void ResourceOwnerReleaseInternal ( ResourceOwner  owner,
ResourceReleasePhase  phase,
bool  isCommit,
bool  isTopLevel 
)
static

Definition at line 678 of file resowner.c.

682{
683 ResourceOwner child;
684 ResourceOwner save;
687
688 /* Recurse to handle descendants */
689 for (child = owner->firstchild; child != NULL; child = child->nextchild)
690 ResourceOwnerReleaseInternal(child, phase, isCommit, isTopLevel);
691
692 /*
693 * To release the resources in the right order, sort them by phase and
694 * priority.
695 *
696 * The ReleaseResource callback functions are not allowed to remember or
697 * forget any other resources after this. Otherwise we lose track of where
698 * we are in processing the hash/array.
699 */
700 if (!owner->releasing)
701 {
703 Assert(!owner->sorted);
704 owner->releasing = true;
705 }
706 else
707 {
708 /*
709 * Phase is normally > RESOURCE_RELEASE_BEFORE_LOCKS, if this is not
710 * the first call to ResourceOwnerRelease. But if an error happens
711 * between the release phases, we might get called again for the same
712 * ResourceOwner from AbortTransaction.
713 */
714 }
715 if (!owner->sorted)
716 {
717 ResourceOwnerSort(owner);
718 owner->sorted = true;
719 }
720
721 /*
722 * Make CurrentResourceOwner point to me, so that the release callback
723 * functions know which resource owner is been released.
724 */
726 CurrentResourceOwner = owner;
727
729 {
730 /*
731 * Release all resources that need to be released before the locks.
732 *
733 * During a commit, there shouldn't be any remaining resources ---
734 * that would indicate failure to clean up the executor correctly ---
735 * so issue warnings. In the abort case, just clean up quietly.
736 */
737 ResourceOwnerReleaseAll(owner, phase, isCommit);
738
739 while (!dlist_is_empty(&owner->aio_handles))
740 {
741 dlist_node *node = dlist_head_node(&owner->aio_handles);
742
743 pgaio_io_release_resowner(node, !isCommit);
744 }
745 }
746 else if (phase == RESOURCE_RELEASE_LOCKS)
747 {
748 if (isTopLevel)
749 {
750 /*
751 * For a top-level xact we are going to release all locks (or at
752 * least all non-session locks), so just do a single lmgr call at
753 * the top of the recursion.
754 */
755 if (owner == TopTransactionResourceOwner)
756 {
757 ProcReleaseLocks(isCommit);
758 ReleasePredicateLocks(isCommit, false);
759 }
760 }
761 else
762 {
763 /*
764 * Release locks retail. Note that if we are committing a
765 * subtransaction, we do NOT release its locks yet, but transfer
766 * them to the parent.
767 */
768 LOCALLOCK **locks;
769 int nlocks;
770
771 Assert(owner->parent != NULL);
772
773 /*
774 * Pass the list of locks owned by this resource owner to the lock
775 * manager, unless it has overflowed.
776 */
777 if (owner->nlocks > MAX_RESOWNER_LOCKS)
778 {
779 locks = NULL;
780 nlocks = 0;
781 }
782 else
783 {
784 locks = owner->locks;
785 nlocks = owner->nlocks;
786 }
787
788 if (isCommit)
789 LockReassignCurrentOwner(locks, nlocks);
790 else
791 LockReleaseCurrentOwner(locks, nlocks);
792 }
793 }
794 else if (phase == RESOURCE_RELEASE_AFTER_LOCKS)
795 {
796 /*
797 * Release all resources that need to be released after the locks.
798 */
799 ResourceOwnerReleaseAll(owner, phase, isCommit);
800 }
801
802 /* Let add-on modules get a chance too */
803 for (item = ResourceRelease_callbacks; item; item = next)
804 {
805 /* allow callbacks to unregister themselves when called */
806 next = item->next;
807 item->callback(phase, isCommit, isTopLevel, item->arg);
808 }
809
811}
void pgaio_io_release_resowner(dlist_node *ioh_node, bool on_error)
Definition: aio.c:262
static int32 next
Definition: blutils.c:224
static dlist_node * dlist_head_node(dlist_head *head)
Definition: ilist.h:565
static bool dlist_is_empty(const dlist_head *head)
Definition: ilist.h:336
void LockReassignCurrentOwner(LOCALLOCK **locallocks, int nlocks)
Definition: lock.c:2671
void LockReleaseCurrentOwner(LOCALLOCK **locallocks, int nlocks)
Definition: lock.c:2576
void ReleasePredicateLocks(bool isCommit, bool isReadOnlySafe)
Definition: predicate.c:3312
ResourceOwner TopTransactionResourceOwner
Definition: resowner.c:175
static void ResourceOwnerReleaseAll(ResourceOwner owner, ResourceReleasePhase phase, bool printLeakWarnings)
Definition: resowner.c:348
static void ResourceOwnerSort(ResourceOwner owner)
Definition: resowner.c:292
void ProcReleaseLocks(bool isCommit)
Definition: proc.c:892

References ResourceOwnerData::aio_handles, ResourceReleaseCallbackItem::arg, Assert(), ResourceReleaseCallbackItem::callback, CurrentResourceOwner, dlist_head_node(), dlist_is_empty(), ResourceOwnerData::firstchild, LockReassignCurrentOwner(), LockReleaseCurrentOwner(), ResourceOwnerData::locks, MAX_RESOWNER_LOCKS, next, ResourceReleaseCallbackItem::next, ResourceOwnerData::nextchild, ResourceOwnerData::nlocks, ResourceOwnerData::parent, pgaio_io_release_resowner(), ProcReleaseLocks(), ReleasePredicateLocks(), ResourceOwnerData::releasing, RESOURCE_RELEASE_AFTER_LOCKS, RESOURCE_RELEASE_BEFORE_LOCKS, RESOURCE_RELEASE_LOCKS, ResourceOwnerReleaseAll(), ResourceOwnerReleaseInternal(), ResourceOwnerSort(), ResourceRelease_callbacks, ResourceOwnerData::sorted, and TopTransactionResourceOwner.

Referenced by ResourceOwnerRelease(), and ResourceOwnerReleaseInternal().

◆ ResourceOwnerRemember()

void ResourceOwnerRemember ( ResourceOwner  owner,
Datum  value,
const ResourceOwnerDesc kind 
)

Definition at line 524 of file resowner.c.

525{
526 uint32 idx;
527
528 /* sanity check the ResourceOwnerDesc */
529 Assert(kind->release_phase != 0);
530 Assert(kind->release_priority != 0);
531
532 /*
533 * Mustn't try to remember more resources after we have already started
534 * releasing. We already checked this in ResourceOwnerEnlarge.
535 */
536 Assert(!owner->releasing);
537 Assert(!owner->sorted);
538
539 if (owner->narr >= RESOWNER_ARRAY_SIZE)
540 {
541 /* forgot to call ResourceOwnerEnlarge? */
542 elog(ERROR, "ResourceOwnerRemember called but array was full");
543 }
544
545 /* Append to the array. */
546 idx = owner->narr;
547 owner->arr[idx].item = value;
548 owner->arr[idx].kind = kind;
549 owner->narr++;
550}

References ResourceOwnerData::arr, Assert(), elog, ERROR, idx(), ResourceElem::item, ResourceElem::kind, ResourceOwnerData::narr, ResourceOwnerDesc::release_phase, ResourceOwnerDesc::release_priority, ResourceOwnerData::releasing, RESOWNER_ARRAY_SIZE, ResourceOwnerData::sorted, and value.

Referenced by RememberManyTestResources(), ResourceOwnerRememberBuffer(), ResourceOwnerRememberBufferIO(), ResourceOwnerRememberCatCacheListRef(), ResourceOwnerRememberCatCacheRef(), ResourceOwnerRememberCryptoHash(), ResourceOwnerRememberDSM(), ResourceOwnerRememberFile(), ResourceOwnerRememberHMAC(), ResourceOwnerRememberJIT(), ResourceOwnerRememberOSSLCipher(), ResourceOwnerRememberOSSLDigest(), ResourceOwnerRememberPlanCacheRef(), ResourceOwnerRememberRelationRef(), ResourceOwnerRememberSnapshot(), ResourceOwnerRememberTupleDesc(), ResourceOwnerRememberWaitEventSet(), test_resowner_forget_between_phases(), test_resowner_leak(), test_resowner_priorities(), and test_resowner_remember_between_phases().

◆ ResourceOwnerRememberAioHandle()

void ResourceOwnerRememberAioHandle ( ResourceOwner  owner,
struct dlist_node ioh_node 
)

Definition at line 1104 of file resowner.c.

1105{
1106 dlist_push_tail(&owner->aio_handles, ioh_node);
1107}
static void dlist_push_tail(dlist_head *head, dlist_node *node)
Definition: ilist.h:364

References ResourceOwnerData::aio_handles, and dlist_push_tail().

Referenced by pgaio_io_resowner_register().

◆ ResourceOwnerRememberLock()

void ResourceOwnerRememberLock ( ResourceOwner  owner,
LOCALLOCK locallock 
)

Definition at line 1062 of file resowner.c.

1063{
1064 Assert(locallock != NULL);
1065
1066 if (owner->nlocks > MAX_RESOWNER_LOCKS)
1067 return; /* we have already overflowed */
1068
1069 if (owner->nlocks < MAX_RESOWNER_LOCKS)
1070 owner->locks[owner->nlocks] = locallock;
1071 else
1072 {
1073 /* overflowed */
1074 }
1075 owner->nlocks++;
1076}

References Assert(), ResourceOwnerData::locks, MAX_RESOWNER_LOCKS, and ResourceOwnerData::nlocks.

Referenced by GrantLockLocal(), and LockReassignOwner().

◆ ResourceOwnerSort()

static void ResourceOwnerSort ( ResourceOwner  owner)
static

Definition at line 292 of file resowner.c.

293{
296
297 if (owner->nhash == 0)
298 {
299 items = owner->arr;
300 nitems = owner->narr;
301 }
302 else
303 {
304 /*
305 * Compact the hash table, so that all the elements are in the
306 * beginning of the 'hash' array, with no empty elements.
307 */
308 uint32 dst = 0;
309
310 for (int idx = 0; idx < owner->capacity; idx++)
311 {
312 if (owner->hash[idx].kind != NULL)
313 {
314 if (dst != idx)
315 owner->hash[dst] = owner->hash[idx];
316 dst++;
317 }
318 }
319
320 /*
321 * Move all entries from the fixed-size array to 'hash'.
322 *
323 * RESOWNER_HASH_MAX_ITEMS is defined so that there is always enough
324 * free space to move all the elements from the fixed-size array to
325 * the hash.
326 */
327 Assert(dst + owner->narr <= owner->capacity);
328 for (int idx = 0; idx < owner->narr; idx++)
329 {
330 owner->hash[dst] = owner->arr[idx];
331 dst++;
332 }
333 Assert(dst == owner->nhash + owner->narr);
334 owner->narr = 0;
335 owner->nhash = dst;
336
337 items = owner->hash;
338 nitems = owner->nhash;
339 }
340
342}
#define qsort(a, b, c, d)
Definition: port.h:479
static int resource_priority_cmp(const void *a, const void *b)
Definition: resowner.c:269

References ResourceOwnerData::arr, Assert(), ResourceOwnerData::capacity, ResourceOwnerData::hash, idx(), items, ResourceElem::kind, ResourceOwnerData::narr, ResourceOwnerData::nhash, nitems, qsort, and resource_priority_cmp().

Referenced by ResourceOwnerReleaseInternal().

◆ StaticAssertDecl()

StaticAssertDecl ( RESOWNER_HASH_MAX_ITEMS(RESOWNER_HASH_INIT_SIZE) >=  RESOWNER_ARRAY_SIZE,
"initial hash size too small compared to array size"   
)

◆ UnregisterResourceReleaseCallback()

void UnregisterResourceReleaseCallback ( ResourceReleaseCallback  callback,
void *  arg 
)

Definition at line 975 of file resowner.c.

976{
979
980 prev = NULL;
981 for (item = ResourceRelease_callbacks; item; prev = item, item = item->next)
982 {
983 if (item->callback == callback && item->arg == arg)
984 {
985 if (prev)
986 prev->next = item->next;
987 else
989 pfree(item);
990 break;
991 }
992 }
993}

References ResourceReleaseCallbackItem::arg, arg, ResourceReleaseCallbackItem::callback, callback(), ResourceReleaseCallbackItem::next, pfree(), and ResourceRelease_callbacks.

Variable Documentation

◆ AuxProcessResourceOwner

◆ CurrentResourceOwner

ResourceOwner CurrentResourceOwner = NULL

Definition at line 173 of file resowner.c.

Referenced by _SPI_execute_plan(), apply_spooled_messages(), AssignTransactionId(), AsyncReadBuffers(), AtAbort_ResourceOwner(), AtStart_ResourceOwner(), AtSubAbort_ResourceOwner(), AtSubStart_ResourceOwner(), attach_internal(), buffer_call_start_io(), buffer_stage_common(), BufferAlloc(), CleanupSubTransaction(), CleanupTransaction(), close_lo_relation(), CommitSubTransaction(), CommitTransaction(), create_internal(), CreateAuxProcessResourceOwner(), DecrTupleDescRefCount(), dsm_create_descriptor(), dsm_unpin_mapping(), EvictAllUnpinnedBuffers(), EvictRelUnpinnedBuffers(), EvictUnpinnedBuffer(), exec_eval_simple_expr(), exec_init_tuple_store(), exec_simple_check_plan(), exec_stmt_block(), ExecAppendAsyncEventWait(), ExplainExecuteQuery(), ExtendBufferedRelLocal(), ExtendBufferedRelShared(), extendBufFile(), FlushDatabaseBuffers(), FlushRelationBuffers(), FlushRelationsAllBuffers(), get_segment_by_index(), GetCurrentFDWTuplestore(), GetLocalVictimBuffer(), GetVictimBuffer(), handle_get(), handle_get_and_error(), handle_get_release(), handle_get_twice(), IncrBufferRefCount(), IncrTupleDescRefCount(), init_execution_state(), InitPostgres(), llvm_create_context(), LocalBufferAlloc(), lock_and_open_sequence(), LockAcquireExtended(), LockReassignCurrentOwner(), LockReassignOwner(), LockRelease(), LogicalSlotAdvanceAndCheckSnapState(), make_callstmt_target(), make_new_segment(), makeBufFileCommon(), MakeTransitionCaptureState(), open_lo_relation(), OpenTemporaryFile(), PathNameCreateTemporaryFile(), PathNameOpenTemporaryFile(), perform_base_backup(), PersistHoldablePortal(), pg_cryptohash_create(), pg_hmac_create(), pg_logical_slot_get_changes_guts(), pgaio_io_resowner_register(), PinBuffer(), PinBuffer_Locked(), PinLocalBuffer(), plperl_spi_exec(), plperl_spi_exec_prepared(), plperl_spi_fetchrow(), plperl_spi_prepare(), plperl_spi_query(), plperl_spi_query_prepared(), plpgsql_estate_setup(), pltcl_func_handler(), pltcl_init_tuple_store(), pltcl_returnnext(), pltcl_SPI_execute(), pltcl_SPI_execute_plan(), pltcl_SPI_prepare(), pltcl_subtrans_abort(), pltcl_subtrans_commit(), pltcl_subtransaction(), 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(), px_find_cipher(), px_find_digest(), read_rel_block_ll(), ReadRecentBuffer(), RegisterSnapshot(), RegisterTemporaryFile(), RelationDecrementReferenceCount(), RelationIncrementReferenceCount(), ReleaseCatCache(), ReleaseCatCacheList(), ReleaseCatCacheListWithOwner(), ReleaseCatCacheWithOwner(), ReleaseLockIfHeld(), ResourceOwnerDelete(), ResourceOwnerReleaseInternal(), SearchCatCacheInternal(), SearchCatCacheList(), SearchCatCacheMiss(), ShutdownXLOG(), SnapBuildClearExportedSnapshot(), SnapBuildExportSnapshot(), SPI_plan_get_cached_plan(), StartBufferIO(), StartupXLOG(), SyncOneBuffer(), TerminateBufferIO(), test_dsa_resowners(), test_resowner_forget_between_phases(), test_resowner_leak(), test_resowner_many(), test_resowner_priorities(), test_resowner_remember_between_phases(), tuplestore_begin_common(), tuplestore_puttuple_common(), UnpinBuffer(), UnpinLocalBuffer(), UnregisterSnapshot(), UploadManifest(), and WaitLatchOrSocket().

◆ CurTransactionResourceOwner

◆ ResourceRelease_callbacks

ResourceReleaseCallbackItem* ResourceRelease_callbacks = NULL
static

◆ TopTransactionResourceOwner