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:312
char * psprintf(const char *fmt,...)
Definition: psprintf.c:43

References DatumGetPointer(), psprintf(), and res.

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, NOTICE, and res.

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 
197  ResourceOwnerRelease(resowner, RESOURCE_RELEASE_BEFORE_LOCKS, true, false);
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 
208  PG_RETURN_VOID();
209 }
#define ERROR
Definition: elog.h:39
#define PG_RETURN_VOID()
Definition: fmgr.h:349
uintptr_t Datum
Definition: postgres.h:64
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:350
ResourceOwner ResourceOwnerCreate(ResourceOwner parent, const char *name)
Definition: resowner.c:413
ResourceOwner CurrentResourceOwner
Definition: resowner.c:165
void ResourceOwnerRelease(ResourceOwner owner, ResourceReleasePhase phase, bool isCommit, bool isTopLevel)
Definition: resowner.c:648
void ResourceOwnerForget(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition: resowner.c:554
void ResourceOwnerRemember(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
Definition: resowner.c:514
void ResourceOwnerEnlarge(ResourceOwner owner)
Definition: resowner.c:442
@ 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 
152  ResourceOwnerRelease(resowner, RESOURCE_RELEASE_BEFORE_LOCKS, true, false);
153  ResourceOwnerRelease(resowner, RESOURCE_RELEASE_LOCKS, true, false);
154  ResourceOwnerRelease(resowner, RESOURCE_RELEASE_AFTER_LOCKS, true, false);
155 
156  ResourceOwnerDelete(resowner);
157 
158  PG_RETURN_VOID();
159 }
void ResourceOwnerDelete(ResourceOwner owner)
Definition: resowner.c:854
@ 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 
91  ResourceOwnerEnlarge(child);
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 
100  ResourceOwnerEnlarge(child);
101  ResourceOwnerRemember(child,
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);
112  ResourceOwnerRemember(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);
121  ResourceOwnerRemember(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");
131  ResourceOwnerRelease(parent, RESOURCE_RELEASE_AFTER_LOCKS, false, false);
132 
133  ResourceOwnerDelete(parent);
134 
135  PG_RETURN_VOID();
136 }
int32_t int32
Definition: c.h:481
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
int i
Definition: isn.c:72
void * palloc(Size size)
Definition: mcxt.c:1317
#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 
169  ResourceOwnerRelease(resowner, RESOURCE_RELEASE_BEFORE_LOCKS, true, false);
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 
181  PG_RETURN_VOID();
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().