@@ -60,11 +60,11 @@ public static class FinalizerReference extends PhantomReference<Object> {
60
60
* {@link FinalizationService} monitor, to avoid concurrent access.
61
61
*/
62
62
private final Deque <Finalizer > finalizers = new LinkedList <>();
63
+
64
+ /** The doubly-linked list of FinalizerReference, needed to collect finalizer Procs for ObjectSpace. */
63
65
private FinalizerReference next = null ;
64
66
private FinalizerReference prev = null ;
65
67
66
- private static FinalizerReference first = null ;
67
-
68
68
private FinalizerReference (Object object , ReferenceQueue <? super Object > queue ) {
69
69
super (object , queue );
70
70
}
@@ -73,10 +73,11 @@ private void addFinalizer(Class<?> owner, Runnable action, DynamicObject root) {
73
73
finalizers .addLast (new Finalizer (owner , action , root ));
74
74
}
75
75
76
- private FinalizerReference removeFinalizers (Class <?> owner ) {
76
+ private FinalizerReference removeFinalizers (FinalizationService finalizationService , Class <?> owner ) {
77
77
finalizers .removeIf (f -> f .getOwner () == owner );
78
+
78
79
if (finalizers .isEmpty ()) {
79
- remove (this );
80
+ finalizationService . remove (this );
80
81
return null ;
81
82
} else {
82
83
return this ;
@@ -98,24 +99,21 @@ private void collectRoots(Collection<DynamicObject> roots) {
98
99
}
99
100
100
101
private final RubyContext context ;
101
-
102
102
private final ReferenceQueue <Object > finalizerQueue = new ReferenceQueue <>();
103
-
103
+ /** The finalizer Ruby thread, spawned lazily. */
104
104
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 ;
105
107
106
108
public FinalizationService (RubyContext context ) {
107
109
this .context = context ;
108
110
}
109
111
110
- public FinalizerReference addFinalizer (Object object , FinalizerReference ref , Class <?> owner , Runnable action ) {
111
- return addFinalizer (object , ref , owner , action , null );
112
- }
113
-
114
112
public synchronized FinalizerReference addFinalizer (Object object , FinalizerReference finalizerReference , Class <?> owner , Runnable action , DynamicObject root ) {
115
113
116
114
if (finalizerReference == null ) {
117
115
finalizerReference = new FinalizerReference (object , finalizerQueue );
118
- FinalizationService . add (finalizerReference );
116
+ add (finalizerReference );
119
117
}
120
118
121
119
finalizerReference .addFinalizer (owner , action , root );
@@ -163,17 +161,18 @@ private void createFinalizationThread() {
163
161
164
162
threadManager .initialize (finalizerThread , null , "finalizer" , () -> {
165
163
while (true ) {
166
- final FinalizerReference finalizerReference = ( FinalizerReference ) threadManager . runUntilResult ( null ,
167
- finalizerQueue ::remove );
164
+ final FinalizerReference finalizerReference =
165
+ ( FinalizerReference ) threadManager . runUntilResult ( null , finalizerQueue ::remove );
168
166
169
167
runFinalizer (finalizerReference );
170
168
}
171
169
});
172
170
}
173
171
174
172
private void runFinalizer (FinalizerReference finalizerReference ) {
173
+ remove (finalizerReference );
174
+
175
175
try {
176
- FinalizationService .remove (finalizerReference );
177
176
while (!context .isFinalizing ()) {
178
177
final Finalizer finalizer ;
179
178
synchronized (this ) {
@@ -198,7 +197,7 @@ private void runFinalizer(FinalizerReference finalizerReference) {
198
197
}
199
198
200
199
public synchronized void collectRoots (Collection <DynamicObject > roots ) {
201
- FinalizerReference finalizerReference = FinalizerReference . first ;
200
+ FinalizerReference finalizerReference = first ;
202
201
while (finalizerReference != null ) {
203
202
finalizerReference .collectRoots (roots );
204
203
finalizerReference = finalizerReference .next ;
@@ -207,23 +206,24 @@ public synchronized void collectRoots(Collection<DynamicObject> roots) {
207
206
208
207
public synchronized FinalizerReference removeFinalizers (Object object , FinalizerReference ref , Class <?> owner ) {
209
208
if (ref != null ) {
210
- return ref .removeFinalizers (owner );
209
+ return ref .removeFinalizers (this , owner );
211
210
} else {
212
211
return null ;
213
212
}
214
213
}
215
214
216
- static synchronized void remove (FinalizerReference ref ) {
215
+ private synchronized void remove (FinalizerReference ref ) {
217
216
if (ref .next == ref ) {
218
217
// Already removed.
219
218
return ;
220
219
}
221
220
222
- if (FinalizerReference . first == ref ) {
221
+ if (first == ref ) {
223
222
if (ref .next != null ) {
224
- FinalizerReference . first = ref .next ;
223
+ first = ref .next ;
225
224
} else {
226
- FinalizerReference .first = ref .prev ;
225
+ // The list becomes empty
226
+ first = null ;
227
227
}
228
228
}
229
229
@@ -239,12 +239,12 @@ static synchronized void remove(FinalizerReference ref) {
239
239
ref .prev = ref ;
240
240
}
241
241
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 ;
246
246
}
247
- FinalizerReference . first = newRef ;
247
+ first = newRef ;
248
248
}
249
249
250
250
}
0 commit comments