PostgreSQL Source Code git master
test_resowner_basic.c File Reference
#include "postgres.h"
#include "fmgr.h"
#include "utils/resowner.h"
Include dependency graph for test_resowner_basic.c:

Go to the source code of this file.

Functions

static void ReleaseString (Datum res)
 
static char * PrintString (Datum res)
 
 PG_FUNCTION_INFO_V1 (test_resowner_priorities)
 
Datum test_resowner_priorities (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (test_resowner_leak)
 
Datum test_resowner_leak (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (test_resowner_remember_between_phases)
 
Datum test_resowner_remember_between_phases (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (test_resowner_forget_between_phases)
 
Datum test_resowner_forget_between_phases (PG_FUNCTION_ARGS)
 

Variables

 PG_MODULE_MAGIC
 
static const ResourceOwnerDesc string_desc
 

Function Documentation

◆ PG_FUNCTION_INFO_V1() [1/4]

PG_FUNCTION_INFO_V1 ( test_resowner_forget_between_phases  )

◆ PG_FUNCTION_INFO_V1() [2/4]

PG_FUNCTION_INFO_V1 ( test_resowner_leak  )

◆ PG_FUNCTION_INFO_V1() [3/4]

PG_FUNCTION_INFO_V1 ( test_resowner_priorities  )

◆ PG_FUNCTION_INFO_V1() [4/4]

PG_FUNCTION_INFO_V1 ( test_resowner_remember_between_phases  )

◆ PrintString()

static char * PrintString ( Datum  res)
static

Definition at line 42 of file test_resowner_basic.c.

43{
44 return psprintf("test string \"%s\"", DatumGetPointer(res));
45}
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:317
char * psprintf(const char *fmt,...)
Definition: psprintf.c:43

References DatumGetPointer(), and psprintf().

Referenced by test_resowner_priorities().

◆ ReleaseString()

static void ReleaseString ( Datum  res)
static

Definition at line 36 of file test_resowner_basic.c.

37{
38 elog(NOTICE, "releasing string: %s", DatumGetPointer(res));
39}
#define elog(elevel,...)
Definition: elog.h:225
#define NOTICE
Definition: elog.h:35

References DatumGetPointer(), elog, and NOTICE.

Referenced by test_resowner_priorities().

◆ test_resowner_forget_between_phases()

Datum test_resowner_forget_between_phases ( PG_FUNCTION_ARGS  )

Definition at line 186 of file test_resowner_basic.c.

187{
188 ResourceOwner resowner;
189 Datum str_resource;
190
191 resowner = ResourceOwnerCreate(CurrentResourceOwner, "TestOwner");
192
193 ResourceOwnerEnlarge(resowner);
194 str_resource = CStringGetDatum("my string");
195 ResourceOwnerRemember(resowner, str_resource, &string_desc);
196
198
199 /*
200 * Try to forget the resource that was remembered earlier. Fails because
201 * we already called ResourceOwnerRelease.
202 */
203 ResourceOwnerForget(resowner, str_resource, &string_desc);
204
205 /* unreachable */
206 elog(ERROR, "ResourceOwnerForget should have errored out");
207
209}
#define ERROR
Definition: elog.h:39
#define PG_RETURN_VOID()
Definition: fmgr.h:349
uintptr_t Datum
Definition: postgres.h:69
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:355
ResourceOwner ResourceOwnerCreate(ResourceOwner parent, const char *name)
Definition: resowner.c:421
ResourceOwner CurrentResourceOwner
Definition: resowner.c:173
void ResourceOwnerRelease(ResourceOwner owner, ResourceReleasePhase phase, bool isCommit, bool isTopLevel)
Definition: resowner.c:658
void ResourceOwnerForget(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition: resowner.c:564
void ResourceOwnerRemember(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition: resowner.c:524
void ResourceOwnerEnlarge(ResourceOwner owner)
Definition: resowner.c:452
@ RESOURCE_RELEASE_BEFORE_LOCKS
Definition: resowner.h:54
static const ResourceOwnerDesc string_desc

References CStringGetDatum(), CurrentResourceOwner, elog, ERROR, PG_RETURN_VOID, RESOURCE_RELEASE_BEFORE_LOCKS, ResourceOwnerCreate(), ResourceOwnerEnlarge(), ResourceOwnerForget(), ResourceOwnerRelease(), ResourceOwnerRemember(), and string_desc.

◆ test_resowner_leak()

Datum test_resowner_leak ( PG_FUNCTION_ARGS  )

Definition at line 140 of file test_resowner_basic.c.

141{
142 ResourceOwner resowner;
143
144 resowner = ResourceOwnerCreate(CurrentResourceOwner, "TestOwner");
145
146 ResourceOwnerEnlarge(resowner);
147
148 ResourceOwnerRemember(resowner, CStringGetDatum("my string"), &string_desc);
149
150 /* don't call ResourceOwnerForget, so that it is leaked */
151
153 ResourceOwnerRelease(resowner, RESOURCE_RELEASE_LOCKS, true, false);
155
156 ResourceOwnerDelete(resowner);
157
159}
void ResourceOwnerDelete(ResourceOwner owner)
Definition: resowner.c:871
@ RESOURCE_RELEASE_LOCKS
Definition: resowner.h:55
@ RESOURCE_RELEASE_AFTER_LOCKS
Definition: resowner.h:56

References CStringGetDatum(), CurrentResourceOwner, PG_RETURN_VOID, RESOURCE_RELEASE_AFTER_LOCKS, RESOURCE_RELEASE_BEFORE_LOCKS, RESOURCE_RELEASE_LOCKS, ResourceOwnerCreate(), ResourceOwnerDelete(), ResourceOwnerEnlarge(), ResourceOwnerRelease(), ResourceOwnerRemember(), and string_desc.

◆ test_resowner_priorities()

Datum test_resowner_priorities ( PG_FUNCTION_ARGS  )

Definition at line 50 of file test_resowner_basic.c.

51{
52 int32 nkinds = PG_GETARG_INT32(0);
53 int32 nresources = PG_GETARG_INT32(1);
54 ResourceOwner parent,
55 child;
56 ResourceOwnerDesc *before_desc;
57 ResourceOwnerDesc *after_desc;
58
59 if (nkinds <= 0)
60 elog(ERROR, "nkinds must be greater than zero");
61 if (nresources <= 0)
62 elog(ERROR, "nresources must be greater than zero");
63
64 parent = ResourceOwnerCreate(CurrentResourceOwner, "test parent");
65 child = ResourceOwnerCreate(parent, "test child");
66
67 before_desc = palloc(nkinds * sizeof(ResourceOwnerDesc));
68 for (int i = 0; i < nkinds; i++)
69 {
70 before_desc[i].name = psprintf("test resource before locks %d", i);
72 before_desc[i].release_priority = RELEASE_PRIO_FIRST + i;
73 before_desc[i].ReleaseResource = ReleaseString;
74 before_desc[i].DebugPrint = PrintString;
75 }
76 after_desc = palloc(nkinds * sizeof(ResourceOwnerDesc));
77 for (int i = 0; i < nkinds; i++)
78 {
79 after_desc[i].name = psprintf("test resource after locks %d", i);
81 after_desc[i].release_priority = RELEASE_PRIO_FIRST + i;
82 after_desc[i].ReleaseResource = ReleaseString;
83 after_desc[i].DebugPrint = PrintString;
84 }
85
86 /* Add a bunch of resources to child, with different priorities */
87 for (int i = 0; i < nresources; i++)
88 {
89 ResourceOwnerDesc *kind = &before_desc[i % nkinds];
90
93 CStringGetDatum(psprintf("child before locks priority %d", kind->release_priority)),
94 kind);
95 }
96 for (int i = 0; i < nresources; i++)
97 {
98 ResourceOwnerDesc *kind = &after_desc[i % nkinds];
99
102 CStringGetDatum(psprintf("child after locks priority %d", kind->release_priority)),
103 kind);
104 }
105
106 /* And also to the parent */
107 for (int i = 0; i < nresources; i++)
108 {
109 ResourceOwnerDesc *kind = &after_desc[i % nkinds];
110
111 ResourceOwnerEnlarge(parent);
113 CStringGetDatum(psprintf("parent after locks priority %d", kind->release_priority)),
114 kind);
115 }
116 for (int i = 0; i < nresources; i++)
117 {
118 ResourceOwnerDesc *kind = &before_desc[i % nkinds];
119
120 ResourceOwnerEnlarge(parent);
122 CStringGetDatum(psprintf("parent before locks priority %d", kind->release_priority)),
123 kind);
124 }
125
126 elog(NOTICE, "releasing resources before locks");
128 elog(NOTICE, "releasing locks");
129 ResourceOwnerRelease(parent, RESOURCE_RELEASE_LOCKS, false, false);
130 elog(NOTICE, "releasing resources after locks");
132
133 ResourceOwnerDelete(parent);
134
136}
int32_t int32
Definition: c.h:498
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
int i
Definition: isn.c:77
void * palloc(Size size)
Definition: mcxt.c:1945
#define RELEASE_PRIO_FIRST
Definition: resowner.h:80
char *(* DebugPrint)(Datum res)
Definition: resowner.h:118
ResourceReleasePhase release_phase
Definition: resowner.h:96
void(* ReleaseResource)(Datum res)
Definition: resowner.h:108
ResourceReleasePriority release_priority
Definition: resowner.h:97
const char * name
Definition: resowner.h:93
static void ReleaseString(Datum res)
static char * PrintString(Datum res)

References CStringGetDatum(), CurrentResourceOwner, ResourceOwnerDesc::DebugPrint, elog, ERROR, i, ResourceOwnerDesc::name, NOTICE, palloc(), PG_GETARG_INT32, PG_RETURN_VOID, PrintString(), psprintf(), ResourceOwnerDesc::release_phase, RELEASE_PRIO_FIRST, ResourceOwnerDesc::release_priority, ResourceOwnerDesc::ReleaseResource, ReleaseString(), RESOURCE_RELEASE_AFTER_LOCKS, RESOURCE_RELEASE_BEFORE_LOCKS, RESOURCE_RELEASE_LOCKS, ResourceOwnerCreate(), ResourceOwnerDelete(), ResourceOwnerEnlarge(), ResourceOwnerRelease(), and ResourceOwnerRemember().

◆ test_resowner_remember_between_phases()

Datum test_resowner_remember_between_phases ( PG_FUNCTION_ARGS  )

Definition at line 163 of file test_resowner_basic.c.

164{
165 ResourceOwner resowner;
166
167 resowner = ResourceOwnerCreate(CurrentResourceOwner, "TestOwner");
168
170
171 /*
172 * Try to remember a new resource. Fails because we already called
173 * ResourceOwnerRelease.
174 */
175 ResourceOwnerEnlarge(resowner);
176 ResourceOwnerRemember(resowner, CStringGetDatum("my string"), &string_desc);
177
178 /* unreachable */
179 elog(ERROR, "ResourceOwnerEnlarge should have errored out");
180
182}

References CStringGetDatum(), CurrentResourceOwner, elog, ERROR, PG_RETURN_VOID, RESOURCE_RELEASE_BEFORE_LOCKS, ResourceOwnerCreate(), ResourceOwnerEnlarge(), ResourceOwnerRelease(), ResourceOwnerRemember(), and string_desc.

Variable Documentation

◆ PG_MODULE_MAGIC

PG_MODULE_MAGIC

Definition at line 18 of file test_resowner_basic.c.

◆ string_desc

const ResourceOwnerDesc string_desc
static
Initial value:
= {
.name = "test resource",
.release_phase = RESOURCE_RELEASE_AFTER_LOCKS,
.release_priority = RELEASE_PRIO_FIRST,
.ReleaseResource = ReleaseString,
.DebugPrint = PrintString
}

Definition at line 27 of file test_resowner_basic.c.

Referenced by test_resowner_forget_between_phases(), test_resowner_leak(), and test_resowner_remember_between_phases().