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 996 of file resowner.c.

997{
1000 AuxProcessResourceOwner = ResourceOwnerCreate(NULL, "AuxiliaryProcess");
1002
1003 /*
1004 * Register a shmem-exit callback for cleanup of aux-process resource
1005 * owner. (This needs to run after, e.g., ShutdownXLOG.)
1006 */
1008}
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:1041
ResourceOwner ResourceOwnerCreate(ResourceOwner parent, const char *name)
Definition: resowner.c:418
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 */
235 (uint64) (uintptr_t) kind);
236}
uint64_t uint64
Definition: c.h:543
static uint64 hash_combine64(uint64 a, uint64 b)
Definition: hashfn.h:80
static uint64 murmurhash64(uint64 data)
Definition: hashfn.h:106
static struct @171 value

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

Referenced by ResourceOwnerAddToHash(), and ResourceOwnerForget().

◆ RegisterResourceReleaseCallback()

void RegisterResourceReleaseCallback ( ResourceReleaseCallback  callback,
void *  arg 
)

Definition at line 958 of file resowner.c.

959{
961
965 item->callback = callback;
966 item->arg = arg;
969}
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1229
MemoryContext TopMemoryContext
Definition: mcxt.c:166
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 1016 of file resowner.c.

1017{
1018 /*
1019 * At this writing, the only thing that could actually get released is
1020 * buffer pins; but we may as well do the full release protocol.
1021 */
1024 isCommit, true);
1027 isCommit, true);
1030 isCommit, true);
1031 /* allow it to be reused */
1034}
void ResourceOwnerRelease(ResourceOwner owner, ResourceReleasePhase phase, bool isCommit, bool isTopLevel)
Definition: resowner.c:655
@ 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 1041 of file resowner.c.

1042{
1043 bool isCommit = (code == 0);
1044
1046}
void ReleaseAuxProcessResources(bool isCommit)
Definition: resowner.c:1016

References ReleaseAuxProcessResources().

Referenced by CreateAuxProcessResourceOwner().

◆ resource_priority_cmp()

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

Definition at line 266 of file resowner.c.

267{
268 const ResourceElem *ra = (const ResourceElem *) a;
269 const ResourceElem *rb = (const ResourceElem *) b;
270
271 /* Note: reverse order */
272 if (ra->kind->release_phase == rb->kind->release_phase)
274 else if (ra->kind->release_phase > rb->kind->release_phase)
275 return -1;
276 else
277 return 1;
278}
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 242 of file resowner.c.

243{
244 uint32 mask = owner->capacity - 1;
245 uint32 idx;
246
247 Assert(kind != NULL);
248
249 /* Insert into first free slot at or after hash location. */
250 idx = hash_resource_elem(value, kind) & mask;
251 for (;;)
252 {
253 if (owner->hash[idx].kind == NULL)
254 break; /* found a free slot */
255 idx = (idx + 1) & mask;
256 }
257 owner->hash[idx].item = value;
258 owner->hash[idx].kind = kind;
259 owner->nhash++;
260}
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:262
uint32_t uint32
Definition: c.h:542
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 418 of file resowner.c.

419{
420 ResourceOwner owner;
421
423 sizeof(struct ResourceOwnerData));
424 owner->name = name;
425
426 if (parent)
427 {
428 owner->parent = parent;
429 owner->nextchild = parent->firstchild;
430 parent->firstchild = owner;
431 }
432
433 dlist_init(&owner->aio_handles);
434
435 return owner;
436}
static void dlist_init(dlist_head *head)
Definition: ilist.h:314
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1263
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 868 of file resowner.c.

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

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 449 of file resowner.c.

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

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

1108{
1109 dlist_delete_from(&owner->aio_handles, ioh_node);
1110}
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 1079 of file resowner.c.

1080{
1081 int i;
1082
1083 if (owner->nlocks > MAX_RESOWNER_LOCKS)
1084 return; /* we have overflowed */
1085
1086 Assert(owner->nlocks > 0);
1087 for (i = owner->nlocks - 1; i >= 0; i--)
1088 {
1089 if (locallock == owner->locks[i])
1090 {
1091 owner->locks[i] = owner->locks[owner->nlocks - 1];
1092 owner->nlocks--;
1093 return;
1094 }
1095 }
1096 elog(ERROR, "lock reference %p is not owned by resource owner %s",
1097 locallock, owner->name);
1098}
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 902 of file resowner.c.

903{
904 return owner->parent;
905}

References ResourceOwnerData::parent.

Referenced by LockReassignCurrentOwner().

◆ ResourceOwnerNewParent()

void ResourceOwnerNewParent ( ResourceOwner  owner,
ResourceOwner  newparent 
)

Definition at line 911 of file resowner.c.

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

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 655 of file resowner.c.

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

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 345 of file resowner.c.

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

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

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 675 of file resowner.c.

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

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 521 of file resowner.c.

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

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 1101 of file resowner.c.

1102{
1103 dlist_push_tail(&owner->aio_handles, ioh_node);
1104}
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 1059 of file resowner.c.

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

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 289 of file resowner.c.

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

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 972 of file resowner.c.

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

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(), 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(), ReorderBufferImmediateInvalidation(), ReorderBufferProcessTXN(), 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(), TrackNewBufferPin(), tuplestore_begin_common(), tuplestore_puttuple_common(), UnpinBuffer(), UnpinLocalBuffer(), UnregisterSnapshot(), UploadManifest(), and WaitLatchOrSocket().

◆ CurTransactionResourceOwner

◆ ResourceRelease_callbacks

ResourceReleaseCallbackItem* ResourceRelease_callbacks = NULL
static

◆ TopTransactionResourceOwner