167 lines
5.7 KiB
C
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 */
|