Skip to content

Commit f1c5ab7

Browse files
authored
Merge pull request jruby#9260 from headius/restore-embedding-cleaner
Restore Cleaner API use for embedding cleanup
2 parents 58905f5 + 9a480f4 commit f1c5ab7

1 file changed

Lines changed: 6 additions & 48 deletions

File tree

core/src/main/java/org/jruby/embed/internal/ThreadLocalContext.java

Lines changed: 6 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,8 @@
2929
*/
3030
package org.jruby.embed.internal;
3131

32-
import java.lang.ref.PhantomReference;
33-
import java.lang.ref.Reference;
34-
import java.lang.ref.ReferenceQueue;
32+
import java.lang.ref.Cleaner;
33+
import java.lang.ref.Cleaner.Cleanable;
3534
import java.util.concurrent.ConcurrentHashMap;
3635
import java.util.concurrent.atomic.AtomicReference;
3736
import java.util.function.Supplier;
@@ -44,8 +43,8 @@
4443
*/
4544
class ThreadLocalContext {
4645
private final ConcurrentHashMap<LocalContextCleaningAction, Object> contextRefs = new ConcurrentHashMap<>();
46+
private final Cleaner cleaner = Cleaner.create();
4747
private final Supplier<LocalContext> localContextFactory;
48-
private final Cleaner cleaner = new Cleaner();
4948

5049
public ThreadLocalContext(final Supplier<LocalContext> localContextFactory) {
5150
this.localContextFactory = localContextFactory;
@@ -62,13 +61,13 @@ protected AtomicReference<LocalContextCleaningAction> initialValue() {
6261
// GC'd (i.e. when this class gets GC'd because terminate() was never called).
6362
// see ThreadLocal JavaDoc: ref will stay reachable "as long as the thread is
6463
// alive and the ThreadLocal instance is accessible"
65-
ctx.register(ref, cleaner);
64+
final Cleanable cleanable = cleaner.register(ref, ctx);
6665
if (contextHolder == null)
6766
// boundary case if we're already terminating: clean up immediately, because
6867
// there is no more cleanup thread to do that later
6968
// the returned context will be null, but that's to be expected when operating
7069
// on an object that has been terminated
71-
ctx.run();
70+
cleanable.clean();
7271
return ref;
7372
}
7473
};
@@ -78,7 +77,6 @@ public LocalContext get() {
7877
}
7978

8079
public void terminate() {
81-
cleaner.interrupt();
8280
contextHolder = null;
8381
for (final LocalContextCleaningAction ref : contextRefs.keySet())
8482
ref.run();
@@ -90,14 +88,11 @@ public void terminate() {
9088
* everything that is GC-reachable from them will stay reachable until the
9189
* cleaning action has been run.
9290
*/
93-
static class LocalContextCleaningAction extends AtomicReference<LocalContext> implements Runnable {
91+
private static class LocalContextCleaningAction extends AtomicReference<LocalContext> implements Runnable {
9492
private static final long serialVersionUID = 1L;
9593

9694
private final ConcurrentHashMap<LocalContextCleaningAction, Object> contextRefs;
9795

98-
@SuppressWarnings("unused") // only used to make sure the PhantomReference doesn't get GC'd
99-
private CleanerReference phantomReference;
100-
10196
private LocalContextCleaningAction(final ConcurrentHashMap<LocalContextCleaningAction, Object> contextRefs,
10297
final LocalContext context) {
10398
super(context);
@@ -116,42 +111,5 @@ public void run() {
116111
lc.remove();
117112
contextRefs.remove(this);
118113
}
119-
120-
private void register(final AtomicReference<LocalContextCleaningAction> ref, final Cleaner cleaner) {
121-
phantomReference = new CleanerReference(ref, cleaner.q, this);
122-
}
123-
}
124-
125-
private static class CleanerReference extends PhantomReference<AtomicReference<LocalContextCleaningAction>> {
126-
private Runnable cleanup;
127-
128-
public CleanerReference(final AtomicReference<LocalContextCleaningAction> referent,
129-
final ReferenceQueue<AtomicReference<LocalContextCleaningAction>> q, final Runnable cleanup) {
130-
super(referent, q);
131-
this.cleanup = cleanup;
132-
}
133-
}
134-
135-
private static class Cleaner extends Thread {
136-
private final ReferenceQueue<AtomicReference<LocalContextCleaningAction>> q = new ReferenceQueue<>();
137-
138-
public Cleaner() {
139-
setName("JRuby-ThreadLocalContext-Cleaner-" + getId());
140-
setDaemon(true);
141-
start();
142-
}
143-
144-
@Override
145-
public void run() {
146-
while (!interrupted()) {
147-
final Reference<?> cleanable;
148-
try {
149-
cleanable = q.remove();
150-
} catch (InterruptedException e) {
151-
break;
152-
}
153-
((CleanerReference) cleanable).cleanup.run();
154-
}
155-
}
156114
}
157115
}

0 commit comments

Comments
 (0)