PostgreSQL Source Code  git master
test_resowner_basic.c File Reference
#include "postgres.h"
#include "fmgr.h"
#include "lib/ilist.h"
#include "utils/memutils.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 44 of file test_resowner_basic.c.

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

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

Referenced by test_resowner_priorities().

◆ ReleaseString()

static void ReleaseString ( Datum  res)
static

Definition at line 38 of file test_resowner_basic.c.

39 {
40  elog(NOTICE, "releasing string: %s", DatumGetPointer(res));
41 }
#define elog(elevel,...)
Definition: elog.h:224
#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 188 of file test_resowner_basic.c.

189 {
190  ResourceOwner resowner;
191  Datum str_resource;
192 
193  resowner = ResourceOwnerCreate(CurrentResourceOwner, "TestOwner");
194 
195  ResourceOwnerEnlarge(resowner);
196  str_resource = CStringGetDatum("my string");
197  ResourceOwnerRemember(resowner, str_resource, &string_desc);
198 
199  ResourceOwnerRelease(resowner, RESOURCE_RELEASE_BEFORE_LOCKS, true, false);
200 
201  /*
202  * Try to forget the resource that was remembered earlier. Fails because
203  * we already called ResourceOwnerRelease.
204  */
205  ResourceOwnerForget(resowner, str_resource, &string_desc);
206 
207  /* unreachable */
208  elog(ERROR, "ResourceOwnerForget should have errored out");
209 
210  PG_RETURN_VOID();
211 }
#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 142 of file test_resowner_basic.c.

143 {
144  ResourceOwner resowner;
145 
146  resowner = ResourceOwnerCreate(CurrentResourceOwner, "TestOwner");
147 
148  ResourceOwnerEnlarge(resowner);
149 
150  ResourceOwnerRemember(resowner, CStringGetDatum("my string"), &string_desc);
151 
152  /* don't call ResourceOwnerForget, so that it is leaked */
153 
154  ResourceOwnerRelease(resowner, RESOURCE_RELEASE_BEFORE_LOCKS, true, false);
155  ResourceOwnerRelease(resowner, RESOURCE_RELEASE_LOCKS, true, false);
156  ResourceOwnerRelease(resowner, RESOURCE_RELEASE_AFTER_LOCKS, true, false);
157 
158  ResourceOwnerDelete(resowner);
159 
160  PG_RETURN_VOID();
161 }
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 52 of file test_resowner_basic.c.

53 {
54  int32 nkinds = PG_GETARG_INT32(0);
55  int32 nresources = PG_GETARG_INT32(1);
56  ResourceOwner parent,
57  child;
58  ResourceOwnerDesc *before_desc;
59  ResourceOwnerDesc *after_desc;
60 
61  if (nkinds <= 0)
62  elog(ERROR, "nkinds must be greater than zero");
63  if (nresources <= 0)
64  elog(ERROR, "nresources must be greater than zero");
65 
66  parent = ResourceOwnerCreate(CurrentResourceOwner, "test parent");
67  child = ResourceOwnerCreate(parent, "test child");
68 
69  before_desc = palloc(nkinds * sizeof(ResourceOwnerDesc));
70  for (int i = 0; i < nkinds; i++)
71  {
72  before_desc[i].name = psprintf("test resource before locks %d", i);
74  before_desc[i].release_priority = RELEASE_PRIO_FIRST + i;
75  before_desc[i].ReleaseResource = ReleaseString;
76  before_desc[i].DebugPrint = PrintString;
77  }
78  after_desc = palloc(nkinds * sizeof(ResourceOwnerDesc));
79  for (int i = 0; i < nkinds; i++)
80  {
81  after_desc[i].name = psprintf("test resource after locks %d", i);
83  after_desc[i].release_priority = RELEASE_PRIO_FIRST + i;
84  after_desc[i].ReleaseResource = ReleaseString;
85  after_desc[i].DebugPrint = PrintString;
86  }
87 
88  /* Add a bunch of resources to child, with different priorities */
89  for (int i = 0; i < nresources; i++)
90  {
91  ResourceOwnerDesc *kind = &before_desc[i % nkinds];
92 
93  ResourceOwnerEnlarge(child);
95  CStringGetDatum(psprintf("child before locks priority %d", kind->release_priority)),
96  kind);
97  }
98  for (int i = 0; i < nresources; i++)
99  {
100  ResourceOwnerDesc *kind = &after_desc[i % nkinds];
101 
102  ResourceOwnerEnlarge(child);
103  ResourceOwnerRemember(child,
104  CStringGetDatum(psprintf("child after locks priority %d", kind->release_priority)),
105  kind);
106  }
107 
108  /* And also to the parent */
109  for (int i = 0; i < nresources; i++)
110  {
111  ResourceOwnerDesc *kind = &after_desc[i % nkinds];
112 
113  ResourceOwnerEnlarge(parent);
114  ResourceOwnerRemember(parent,
115  CStringGetDatum(psprintf("parent after locks priority %d", kind->release_priority)),
116  kind);
117  }
118  for (int i = 0; i < nresources; i++)
119  {
120  ResourceOwnerDesc *kind = &before_desc[i % nkinds];
121 
122  ResourceOwnerEnlarge(parent);
123  ResourceOwnerRemember(parent,
124  CStringGetDatum(psprintf("parent before locks priority %d", kind->release_priority)),
125  kind);
126  }
127 
128  elog(NOTICE, "releasing resources before locks");
130  elog(NOTICE, "releasing locks");
131  ResourceOwnerRelease(parent, RESOURCE_RELEASE_LOCKS, false, false);
132  elog(NOTICE, "releasing resources after locks");
133  ResourceOwnerRelease(parent, RESOURCE_RELEASE_AFTER_LOCKS, false, false);
134 
135  ResourceOwnerDelete(parent);
136 
137  PG_RETURN_VOID();
138 }
signed int int32
Definition: c.h:494
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
int i
Definition: isn.c:73
void * palloc(Size size)
Definition: mcxt.c:1316
#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 165 of file test_resowner_basic.c.

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

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 20 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 29 of file test_resowner_basic.c.

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