1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
/*-------------------------------------------------------------------------
*
* 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-2025, 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
#define RELEASE_PRIO_WAITEVENTSETS 700
/* 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 value, const ResourceOwnerDesc *kind);
extern void ResourceOwnerForget(ResourceOwner owner, Datum value, 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);
/* special support for AIO */
struct dlist_node;
extern void ResourceOwnerRememberAioHandle(ResourceOwner owner, struct dlist_node *ioh_node);
extern void ResourceOwnerForgetAioHandle(ResourceOwner owner, struct dlist_node *ioh_node);
#endif /* RESOWNER_H */
|