postgresql/src/include/utils/resowner.h

167 lines
5.7 KiB
C

/*-------------------------------------------------------------------------
*
* resowner.h
* POSTGRES resource owner definitions.
*
* Query-lifespan resources are tracked by associating them with
* ResourceOwner objects. This provides a simple mechanism for ensuring
* that such resources are freed at the right time.
* See utils/resowner/README for more info.
*
*
* Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/utils/resowner.h
*
*-------------------------------------------------------------------------
*/
#ifndef RESOWNER_H
#define RESOWNER_H
/*
* ResourceOwner objects are an opaque data structure known only within
* resowner.c.
*/
typedef struct ResourceOwnerData *ResourceOwner;
/*
* Globally known ResourceOwners
*/
extern PGDLLIMPORT ResourceOwner CurrentResourceOwner;
extern PGDLLIMPORT ResourceOwner CurTransactionResourceOwner;
extern PGDLLIMPORT ResourceOwner TopTransactionResourceOwner;
extern PGDLLIMPORT ResourceOwner AuxProcessResourceOwner;
/*
* Resource releasing is done in three phases: pre-locks, locks, and
* post-locks. The pre-lock phase must release any resources that are visible
* to other backends (such as pinned buffers); this ensures that when we
* release a lock that another backend may be waiting on, it will see us as
* being fully out of our transaction. The post-lock phase should be used for
* backend-internal cleanup.
*
* Within each phase, resources are released in priority order. Priority is
* just an integer specified in ResourceOwnerDesc. The priorities of built-in
* resource types are given below, extensions may use any priority relative to
* those or RELEASE_PRIO_FIRST/LAST. RELEASE_PRIO_FIRST is a fine choice if
* your resource doesn't depend on any other resources.
*/
typedef enum
{
RESOURCE_RELEASE_BEFORE_LOCKS = 1,
RESOURCE_RELEASE_LOCKS,
RESOURCE_RELEASE_AFTER_LOCKS,
} ResourceReleasePhase;
typedef uint32 ResourceReleasePriority;
/* priorities of built-in BEFORE_LOCKS resources */
#define RELEASE_PRIO_BUFFER_IOS 100
#define RELEASE_PRIO_BUFFER_PINS 200
#define RELEASE_PRIO_RELCACHE_REFS 300
#define RELEASE_PRIO_DSMS 400
#define RELEASE_PRIO_JIT_CONTEXTS 500
#define RELEASE_PRIO_CRYPTOHASH_CONTEXTS 600
#define RELEASE_PRIO_HMAC_CONTEXTS 700
/* priorities of built-in AFTER_LOCKS resources */
#define RELEASE_PRIO_CATCACHE_REFS 100
#define RELEASE_PRIO_CATCACHE_LIST_REFS 200
#define RELEASE_PRIO_PLANCACHE_REFS 300
#define RELEASE_PRIO_TUPDESC_REFS 400
#define RELEASE_PRIO_SNAPSHOT_REFS 500
#define RELEASE_PRIO_FILES 600
/* 0 is considered invalid */
#define RELEASE_PRIO_FIRST 1
#define RELEASE_PRIO_LAST UINT32_MAX
/*
* In order to track an object, resowner.c needs a few callbacks for it.
* The callbacks for resources of a specific kind are encapsulated in
* ResourceOwnerDesc.
*
* Note that the callbacks occur post-commit or post-abort, so the callback
* functions can only do noncritical cleanup and must not fail.
*/
typedef struct ResourceOwnerDesc
{
const char *name; /* name for the object kind, for debugging */
/* when are these objects released? */
ResourceReleasePhase release_phase;
ResourceReleasePriority release_priority;
/*
* Release resource.
*
* This is called for each resource in the resource owner, in the order
* specified by 'release_phase' and 'release_priority' when the whole
* resource owner is been released or when ResourceOwnerReleaseAllOfKind()
* is called. The resource is implicitly removed from the owner, the
* callback function doesn't need to call ResourceOwnerForget.
*/
void (*ReleaseResource) (Datum res);
/*
* Format a string describing the resource, for debugging purposes. If a
* resource has not been properly released before commit, this is used to
* print a WARNING.
*
* This can be left to NULL, in which case a generic "[resource name]: %p"
* format is used.
*/
char *(*DebugPrint) (Datum res);
} ResourceOwnerDesc;
/*
* Dynamically loaded modules can get control during ResourceOwnerRelease
* by providing a callback of this form.
*/
typedef void (*ResourceReleaseCallback) (ResourceReleasePhase phase,
bool isCommit,
bool isTopLevel,
void *arg);
/*
* Functions in resowner.c
*/
/* generic routines */
extern ResourceOwner ResourceOwnerCreate(ResourceOwner parent,
const char *name);
extern void ResourceOwnerRelease(ResourceOwner owner,
ResourceReleasePhase phase,
bool isCommit,
bool isTopLevel);
extern void ResourceOwnerDelete(ResourceOwner owner);
extern ResourceOwner ResourceOwnerGetParent(ResourceOwner owner);
extern void ResourceOwnerNewParent(ResourceOwner owner,
ResourceOwner newparent);
extern void ResourceOwnerEnlarge(ResourceOwner owner);
extern void ResourceOwnerRemember(ResourceOwner owner, Datum res, const ResourceOwnerDesc *kind);
extern void ResourceOwnerForget(ResourceOwner owner, Datum res, const ResourceOwnerDesc *kind);
extern void ResourceOwnerReleaseAllOfKind(ResourceOwner owner, const ResourceOwnerDesc *kind);
extern void RegisterResourceReleaseCallback(ResourceReleaseCallback callback,
void *arg);
extern void UnregisterResourceReleaseCallback(ResourceReleaseCallback callback,
void *arg);
extern void CreateAuxProcessResourceOwner(void);
extern void ReleaseAuxProcessResources(bool isCommit);
/* special support for local lock management */
struct LOCALLOCK;
extern void ResourceOwnerRememberLock(ResourceOwner owner, struct LOCALLOCK *locallock);
extern void ResourceOwnerForgetLock(ResourceOwner owner, struct LOCALLOCK *locallock);
#endif /* RESOWNER_H */