Skip to content

Commit f2c95e7

Browse files
jansupolsenivam
authored andcommitted
Fix releasing RequestScope multiple times.
Signed-off-by: jansupol <[email protected]>
1 parent 92dafb9 commit f2c95e7

File tree

2 files changed

+58
-2
lines changed

2 files changed

+58
-2
lines changed

inject/hk2/src/main/java/org/glassfish/jersey/inject/hk2/Hk2RequestScope.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ public boolean contains(ForeignDescriptor provider) {
139139
*/
140140
@Override
141141
public void release() {
142-
if (referenceCounter.decrementAndGet() < 1) {
142+
if (referenceCounter.decrementAndGet() == 0) {
143143
try {
144144
ArrayList<ForeignDescriptor> reverse = new ArrayList<>(store.keySet());
145145
Collections.reverse(reverse);

tests/e2e-core-common/src/test/java/org/glassfish/jersey/tests/e2e/common/process/internal/RequestScopeTest.java

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.glassfish.jersey.tests.e2e.common.process.internal;
1818

1919
import java.lang.reflect.Type;
20+
import java.util.concurrent.atomic.AtomicBoolean;
2021
import java.util.concurrent.atomic.AtomicInteger;
2122
import java.util.function.Consumer;
2223

@@ -171,12 +172,67 @@ public void accept(Object o) {
171172
Assertions.assertEquals(987654321, instanceRelease.get());
172173
}
173174

175+
@Test
176+
public void testMultipleReleases() throws InterruptedException {
177+
final RequestScope requestScope = new Hk2RequestScope();
178+
final AtomicBoolean passed = new AtomicBoolean(true);
179+
final int CNT = 200;
180+
Thread[] thread = new Thread[CNT];
181+
Hk2RequestScope.Instance instance = requestScope.runInScope(() -> {
182+
final Hk2RequestScope.Instance internalInstance = (Hk2RequestScope.Instance) requestScope.current();
183+
for (int index = 1; index != CNT; index++) {
184+
TestProvider testProvider = new TestProvider(String.valueOf(index)) {
185+
@Override
186+
public int hashCode() {
187+
return super.hashCode() + Integer.parseInt(id);
188+
}
189+
};
190+
final ForeignDescriptor fd = ForeignDescriptor.wrap(testProvider, new Consumer<Object>() {
191+
@Override
192+
public void accept(Object o) {
193+
// noop
194+
}
195+
});
196+
internalInstance.put(fd, String.valueOf(index));
197+
198+
for (int i = 0; i != CNT; i++) {
199+
thread[i] = new Thread(new Runnable() {
200+
@Override
201+
public void run() {
202+
final long waitTime = (int) (Math.random() * 5 + 1) * 10L;
203+
try {
204+
Thread.sleep(waitTime);
205+
} catch (InterruptedException e) {
206+
throw new RuntimeException(e);
207+
}
208+
try {
209+
internalInstance.release();
210+
} catch (Throwable throwable) {
211+
passed.set(false);
212+
}
213+
}
214+
});
215+
}
216+
for (int i = 0; i != CNT; i++) {
217+
thread[i].start();
218+
}
219+
}
220+
return internalInstance;
221+
});
222+
223+
for (int i = 0; i != CNT; i++) {
224+
thread[i].join();
225+
}
226+
227+
Assertions.assertTrue(passed.get());
228+
}
229+
174230
/**
175231
* Test request scope inhabitant.
176232
*/
177233
public static class TestProvider extends AbstractActiveDescriptor<String> {
178234

179-
private final String id;
235+
public final String id;
180236

181237
public TestProvider(final String id) {
182238
super();

0 commit comments

Comments
 (0)