Skip to content

Commit d95f1e2

Browse files
committed
Cleanup and fix for FinalizationService
PullRequest: truffleruby/489
2 parents 82b3f94 + ca282cd commit d95f1e2

File tree

2 files changed

+26
-26
lines changed

2 files changed

+26
-26
lines changed

src/main/java/org/truffleruby/core/FinalizationService.java

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,11 @@ public static class FinalizerReference extends PhantomReference<Object> {
6060
* {@link FinalizationService} monitor, to avoid concurrent access.
6161
*/
6262
private final Deque<Finalizer> finalizers = new LinkedList<>();
63+
64+
/** The doubly-linked list of FinalizerReference, needed to collect finalizer Procs for ObjectSpace. */
6365
private FinalizerReference next = null;
6466
private FinalizerReference prev = null;
6567

66-
private static FinalizerReference first = null;
67-
6868
private FinalizerReference(Object object, ReferenceQueue<? super Object> queue) {
6969
super(object, queue);
7070
}
@@ -73,10 +73,11 @@ private void addFinalizer(Class<?> owner, Runnable action, DynamicObject root) {
7373
finalizers.addLast(new Finalizer(owner, action, root));
7474
}
7575

76-
private FinalizerReference removeFinalizers(Class<?> owner) {
76+
private FinalizerReference removeFinalizers(FinalizationService finalizationService, Class<?> owner) {
7777
finalizers.removeIf(f -> f.getOwner() == owner);
78+
7879
if (finalizers.isEmpty()) {
79-
remove(this);
80+
finalizationService.remove(this);
8081
return null;
8182
} else {
8283
return this;
@@ -98,24 +99,21 @@ private void collectRoots(Collection<DynamicObject> roots) {
9899
}
99100

100101
private final RubyContext context;
101-
102102
private final ReferenceQueue<Object> finalizerQueue = new ReferenceQueue<>();
103-
103+
/** The finalizer Ruby thread, spawned lazily. */
104104
private DynamicObject finalizerThread;
105+
/** The head of a doubly-linked list of FinalizerReference, needed to collect finalizer Procs for ObjectSpace. */
106+
private FinalizerReference first = null;
105107

106108
public FinalizationService(RubyContext context) {
107109
this.context = context;
108110
}
109111

110-
public FinalizerReference addFinalizer(Object object, FinalizerReference ref, Class<?> owner, Runnable action) {
111-
return addFinalizer(object, ref, owner, action, null);
112-
}
113-
114112
public synchronized FinalizerReference addFinalizer(Object object, FinalizerReference finalizerReference, Class<?> owner, Runnable action, DynamicObject root) {
115113

116114
if (finalizerReference == null) {
117115
finalizerReference = new FinalizerReference(object, finalizerQueue);
118-
FinalizationService.add(finalizerReference);
116+
add(finalizerReference);
119117
}
120118

121119
finalizerReference.addFinalizer(owner, action, root);
@@ -163,17 +161,18 @@ private void createFinalizationThread() {
163161

164162
threadManager.initialize(finalizerThread, null, "finalizer", () -> {
165163
while (true) {
166-
final FinalizerReference finalizerReference = (FinalizerReference) threadManager.runUntilResult(null,
167-
finalizerQueue::remove);
164+
final FinalizerReference finalizerReference =
165+
(FinalizerReference) threadManager.runUntilResult(null, finalizerQueue::remove);
168166

169167
runFinalizer(finalizerReference);
170168
}
171169
});
172170
}
173171

174172
private void runFinalizer(FinalizerReference finalizerReference) {
173+
remove(finalizerReference);
174+
175175
try {
176-
FinalizationService.remove(finalizerReference);
177176
while (!context.isFinalizing()) {
178177
final Finalizer finalizer;
179178
synchronized (this) {
@@ -198,7 +197,7 @@ private void runFinalizer(FinalizerReference finalizerReference) {
198197
}
199198

200199
public synchronized void collectRoots(Collection<DynamicObject> roots) {
201-
FinalizerReference finalizerReference = FinalizerReference.first;
200+
FinalizerReference finalizerReference = first;
202201
while (finalizerReference != null) {
203202
finalizerReference.collectRoots(roots);
204203
finalizerReference = finalizerReference.next;
@@ -207,23 +206,24 @@ public synchronized void collectRoots(Collection<DynamicObject> roots) {
207206

208207
public synchronized FinalizerReference removeFinalizers(Object object, FinalizerReference ref, Class<?> owner) {
209208
if (ref != null) {
210-
return ref.removeFinalizers(owner);
209+
return ref.removeFinalizers(this, owner);
211210
} else {
212211
return null;
213212
}
214213
}
215214

216-
static synchronized void remove(FinalizerReference ref) {
215+
private synchronized void remove(FinalizerReference ref) {
217216
if (ref.next == ref) {
218217
// Already removed.
219218
return;
220219
}
221220

222-
if (FinalizerReference.first == ref) {
221+
if (first == ref) {
223222
if (ref.next != null) {
224-
FinalizerReference.first = ref.next;
223+
first = ref.next;
225224
} else {
226-
FinalizerReference.first = ref.prev;
225+
// The list becomes empty
226+
first = null;
227227
}
228228
}
229229

@@ -239,12 +239,12 @@ static synchronized void remove(FinalizerReference ref) {
239239
ref.prev = ref;
240240
}
241241

242-
static synchronized void add(FinalizerReference newRef) {
243-
if (FinalizerReference.first != null) {
244-
newRef.next = FinalizerReference.first;
245-
FinalizerReference.first.prev = newRef;
242+
private synchronized void add(FinalizerReference newRef) {
243+
if (first != null) {
244+
newRef.next = first;
245+
first.prev = newRef;
246246
}
247-
FinalizerReference.first = newRef;
247+
first = newRef;
248248
}
249249

250250
}

src/main/java/org/truffleruby/extra/ffi/Pointer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ public synchronized void enableAutorelease(FinalizationService finalizationServi
248248

249249
// We must be careful here that the finalizer does not capture the Pointer itself that we'd
250250
// like to finalize.
251-
finalizerRef = finalizationService.addFinalizer(this, finalizerRef, Pointer.class, new FreeAddressFinalizer(address));
251+
finalizerRef = finalizationService.addFinalizer(this, finalizerRef, Pointer.class, new FreeAddressFinalizer(address), null);
252252

253253
autorelease = true;
254254
}

0 commit comments

Comments
 (0)