Skip to content

Commit 0dc126e

Browse files
authored
Tests to verify proper life-cycle of RecyclerPool implementations, from databind perspective (#4324)
1 parent c210bdc commit 0dc126e

File tree

1 file changed

+73
-0
lines changed

1 file changed

+73
-0
lines changed

src/test/java/com/fasterxml/jackson/databind/util/BufferRecyclersDatabindTest.java

+73
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package com.fasterxml.jackson.databind.util;
22

3+
import java.lang.invoke.MethodHandle;
4+
import java.lang.invoke.MethodHandles;
5+
import java.lang.invoke.MethodType;
36
import java.nio.charset.StandardCharsets;
7+
import java.util.function.Predicate;
48

59
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
610

@@ -54,6 +58,10 @@ public void testParserWithBoundedPool() throws Exception {
5458
_testParser(JsonRecyclerPools.sharedBoundedPool());
5559
}
5660

61+
public void testParserWithHybridPool() throws Exception {
62+
_testParser(new HybridTestPool());
63+
}
64+
5765
private void _testParser(RecyclerPool<BufferRecycler> pool) throws Exception
5866
{
5967
ObjectMapper mapper = JsonMapper.builder(
@@ -100,6 +108,10 @@ public void testGeneratorWithBoundedPool() throws Exception {
100108
_testGenerator(JsonRecyclerPools.sharedBoundedPool());
101109
}
102110

111+
public void testGeneratorWithHybridPool() throws Exception {
112+
_testGenerator(new HybridTestPool());
113+
}
114+
103115
private void _testGenerator(RecyclerPool<BufferRecycler> pool) throws Exception
104116
{
105117
ObjectMapper mapper = JsonMapper.builder(
@@ -115,4 +127,65 @@ private void _testGenerator(RecyclerPool<BufferRecycler> pool) throws Exception
115127
assertEquals(EXP, new String(mapper.writeValueAsBytes(new Pojo4321(-42, "bogus")),
116128
StandardCharsets.UTF_8));
117129
}
130+
131+
static class HybridTestPool implements RecyclerPool<BufferRecycler>
132+
{
133+
private static final long serialVersionUID = 1L;
134+
135+
private static final Predicate<Thread> isVirtual = VirtualPredicate.findIsVirtualPredicate();
136+
137+
private final RecyclerPool<BufferRecycler> nativePool = JsonRecyclerPools.threadLocalPool();
138+
private final RecyclerPool<BufferRecycler> virtualPool = JsonRecyclerPools.newLockFreePool();
139+
140+
@Override
141+
public BufferRecycler acquirePooled() {
142+
return isVirtual.test(Thread.currentThread()) ?
143+
virtualPool.acquirePooled() :
144+
nativePool.acquirePooled();
145+
}
146+
147+
@Override
148+
public void releasePooled(BufferRecycler pooled) {
149+
if (isVirtual.test(Thread.currentThread())) {
150+
virtualPool.releasePooled(pooled);
151+
} else {
152+
nativePool.releasePooled(pooled);
153+
}
154+
}
155+
156+
static class VirtualPredicate {
157+
static final MethodHandle virtualMh = findVirtualMH();
158+
159+
static MethodHandle findVirtualMH() {
160+
try {
161+
return MethodHandles.publicLookup().findVirtual(Thread.class, "isVirtual",
162+
MethodType.methodType(boolean.class));
163+
} catch (Exception e) {
164+
return null;
165+
}
166+
}
167+
168+
static Predicate<Thread> findIsVirtualPredicate() {
169+
if (virtualMh != null) {
170+
return new Predicate<Thread>() {
171+
@Override
172+
public boolean test(Thread thread) {
173+
try {
174+
return (boolean) virtualMh.invokeExact(thread);
175+
} catch (Throwable e) {
176+
throw new RuntimeException(e);
177+
}
178+
}
179+
};
180+
}
181+
182+
return new Predicate<Thread>() {
183+
@Override
184+
public boolean test(Thread thread) {
185+
return false;
186+
}
187+
};
188+
}
189+
}
190+
}
118191
}

0 commit comments

Comments
 (0)