Skip to content

Commit 5a9cdf9

Browse files
committed
Begin MemoryContext/ResourceOwner implementation
In addition to MemoryContextImpl and ResourceOwnerImpl proper, this step will require reworking DualState so state lives are bounded by Lifespan instances instead of arbitrary pointer values. Invocation will be made into yet another subtype of Lifespan, appropriate for the life of an object passed by PostgreSQL in a call and presumed good while the call is in progress. The DualState change will have to be rototilled through all of its clients. That will take the next several commits. The DualState.Key requirement that was introduced in 1.5.1 as a way to force DualState-guarded objects to be constructed only in upcalls from C (as a hedge against Java code inadvertently doing it on the wrong thread) will go away. We *want* Adapters to be able to easily construct things without leaving Java. Just don't do it on the wrong thread.
1 parent 712f5d2 commit 5a9cdf9

File tree

15 files changed

+2534
-265
lines changed

15 files changed

+2534
-265
lines changed

pljava-api/src/main/java/org/postgresql/pljava/model/Attribute.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,5 @@ public interface Attribute
3838
RegClass CLASS = formObjectId(RegClass.CLASSID, AttributeRelationId);
3939

4040
RegType type();
41+
short length();
4142
}

pljava-so/src/main/c/Backend.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -757,7 +757,7 @@ static void initsequencer(enum initstage is, bool tolerant)
757757
"and \"pljava-api.jar\" files, separated by the correct "
758758
"path separator for this platform.")
759759
));
760-
pljava_DualState_unregister();
760+
pljava_ResourceOwner_unregister();
761761
_destroyJavaVM(0, 0);
762762
goto check_tolerant;
763763
}

pljava-so/src/main/c/DualState.c

Lines changed: 1 addition & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018-2019 Tada AB and other contributors, as listed below.
2+
* Copyright (c) 2018-2022 Tada AB and other contributors, as listed below.
33
*
44
* All rights reserved. This program and the accompanying materials
55
* are made available under the terms of the The BSD 3-Clause License
@@ -20,7 +20,6 @@
2020
#include "org_postgresql_pljava_internal_DualState_SingleSPIcursorClose.h"
2121
#include "pljava/DualState.h"
2222

23-
#include "pljava/Backend.h"
2423
#include "pljava/Exception.h"
2524
#include "pljava/Invocation.h"
2625
#include "pljava/PgObject.h"
@@ -50,22 +49,8 @@ extern void pljava_ExecutionPlan_initialize(void);
5049

5150
static jclass s_DualState_class;
5251

53-
static jmethodID s_DualState_resourceOwnerRelease;
5452
static jmethodID s_DualState_cleanEnqueuedInstances;
5553

56-
static jobject s_DualState_key;
57-
58-
static void resourceReleaseCB(ResourceReleasePhase phase,
59-
bool isCommit, bool isTopLevel, void *arg);
60-
61-
/*
62-
* Return a capability that is only expected to be accessible to native code.
63-
*/
64-
jobject pljava_DualState_key(void)
65-
{
66-
return s_DualState_key;
67-
}
68-
6954
/*
7055
* Rather than using finalizers (deprecated in recent Java anyway), which can
7156
* increase the number of threads needing to interact with PG, DualState objects
@@ -79,39 +64,9 @@ void pljava_DualState_cleanEnqueuedInstances(void)
7964
s_DualState_cleanEnqueuedInstances);
8065
}
8166

82-
/*
83-
* Called when the lifespan/scope of a particular PG resource owner is about to
84-
* expire, to make the associated DualState objects inaccessible from Java. As
85-
* described in DualState.java, the argument will often be a PG ResourceOwner
86-
* (when this function is called by resourceReleaseCB), but pointers to other
87-
* structures can also be used (such a pointer clearly can't be confused with a
88-
* ResourceOwner existing at the same time). In PG 9.5+, it could be a
89-
* MemoryContext, with a MemoryContextCallback established to call this
90-
* function. For items whose scope is limited to a single PL/Java function
91-
* invocation, this can be a pointer to the Invocation.
92-
*/
93-
void pljava_DualState_nativeRelease(void *ro)
94-
{
95-
Ptr2Long p2l;
96-
97-
/*
98-
* This static assertion does not need to be in every file
99-
* that uses Ptr2Long, but it should be somewhere once, so here it is.
100-
*/
101-
StaticAssertStmt(sizeof p2l.ptrVal <= sizeof p2l.longVal,
102-
"Pointer will not fit in long on this platform");
103-
104-
p2l.longVal = 0L;
105-
p2l.ptrVal = ro;
106-
JNI_callStaticVoidMethodLocked(s_DualState_class,
107-
s_DualState_resourceOwnerRelease,
108-
p2l.longVal);
109-
}
110-
11167
void pljava_DualState_initialize(void)
11268
{
11369
jclass clazz;
114-
jmethodID ctor;
11570

11671
JNINativeMethod singlePfreeMethods[] =
11772
{
@@ -185,17 +140,9 @@ void pljava_DualState_initialize(void)
185140

186141
s_DualState_class = (jclass)JNI_newGlobalRef(PgObject_getJavaClass(
187142
"org/postgresql/pljava/internal/DualState"));
188-
s_DualState_resourceOwnerRelease = PgObject_getStaticJavaMethod(
189-
s_DualState_class, "resourceOwnerRelease", "(J)V");
190143
s_DualState_cleanEnqueuedInstances = PgObject_getStaticJavaMethod(
191144
s_DualState_class, "cleanEnqueuedInstances", "()V");
192145

193-
clazz = (jclass)PgObject_getJavaClass(
194-
"org/postgresql/pljava/internal/DualState$Key");
195-
ctor = PgObject_getJavaMethod(clazz, "<init>", "()V");
196-
s_DualState_key = JNI_newGlobalRef(JNI_newObject(clazz, ctor));
197-
JNI_deleteLocalRef(clazz);
198-
199146
clazz = (jclass)PgObject_getJavaClass(
200147
"org/postgresql/pljava/internal/DualState$SinglePfree");
201148
PgObject_registerNatives2(clazz, singlePfreeMethods);
@@ -231,8 +178,6 @@ void pljava_DualState_initialize(void)
231178
PgObject_registerNatives2(clazz, singleSPIcursorCloseMethods);
232179
JNI_deleteLocalRef(clazz);
233180

234-
RegisterResourceReleaseCallback(resourceReleaseCB, NULL);
235-
236181
/*
237182
* Call initialize() methods of known classes built upon DualState.
238183
*/
@@ -248,32 +193,6 @@ void pljava_DualState_initialize(void)
248193
pljava_VarlenaWrapper_initialize();
249194
}
250195

251-
void pljava_DualState_unregister(void)
252-
{
253-
UnregisterResourceReleaseCallback(resourceReleaseCB, NULL);
254-
}
255-
256-
static void resourceReleaseCB(ResourceReleasePhase phase,
257-
bool isCommit, bool isTopLevel, void *arg)
258-
{
259-
/*
260-
* The way ResourceOwnerRelease is implemented, callbacks to loadable
261-
* modules (like us!) happen /after/ all of the built-in releasey actions
262-
* for a particular phase. So, by looking for RESOURCE_RELEASE_LOCKS here,
263-
* we actually end up executing after all the built-in lock-related stuff
264-
* has been released, but before any of the built-in stuff released in the
265-
* RESOURCE_RELEASE_AFTER_LOCKS phase. Which, at least for the currently
266-
* implemented DualState subclasses, is about the right time.
267-
*/
268-
if ( RESOURCE_RELEASE_LOCKS != phase )
269-
return;
270-
271-
pljava_DualState_nativeRelease(CurrentResourceOwner);
272-
273-
if ( isTopLevel )
274-
Backend_warnJEP411(isCommit);
275-
}
276-
277196

278197

279198
/*

0 commit comments

Comments
 (0)