@@ -112,22 +112,40 @@ public void take(ManagedResource resource) {
112112 removeFromItems (resource .getPhantomReference ());
113113 }
114114
115+ /**
116+ * Registers a new (non-system controlled) resource to the system. Calls {@link
117+ * #register(java.lang.Object, java.lang.Object, boolean)} with {@code false} as last argument.
118+ *
119+ * @param object the underlying resource
120+ * @param function the finalizer action to call on the underlying resource
121+ * @return a wrapper object, containing the resource and serving as a reachability probe
122+ */
123+ @ CompilerDirectives .TruffleBoundary
124+ public ManagedResource register (Object object , Object function ) {
125+ return register (object , function , false );
126+ }
127+
115128 /**
116129 * Registers a new resource to the system. {@code function} will be called on {@code object} when
117130 * the value returned by this method becomes unreachable.
118131 *
119132 * @param object the underlying resource
120133 * @param function the finalizer action to call on the underlying resource
134+ * @param systemResource resource is subject to finalization when {@link #scheduleFinalization} is
135+ * called
121136 * @return a wrapper object, containing the resource and serving as a reachability probe
122137 */
123138 @ CompilerDirectives .TruffleBoundary
124- public synchronized ManagedResource register (Object object , Object function ) {
139+ public synchronized ManagedResource register (
140+ Object object , Object function , boolean systemResource ) {
125141 if (CLOSED == processor ) {
126142 throw EnsoContext .get (null )
127143 .raiseAssertionPanic (
128144 null , "Can't register new resources after resource manager is closed." , null );
129145 }
130- var resource = new ManagedResource (object , r -> new Item (r , object , function , referenceQueue ));
146+ var resource =
147+ new ManagedResource (
148+ object , r -> new Item (r , object , function , systemResource , referenceQueue ));
131149 var ref = (Item ) resource .getPhantomReference ();
132150 addPendingItem (ref );
133151 return resource ;
@@ -186,6 +204,21 @@ private synchronized void removeFromItems(PhantomReference<ManagedResource> it)
186204 }
187205 }
188206
207+ /**
208+ * Explicitly schedules all the <em>system references</em> registered with the manager for
209+ * finalization.
210+ *
211+ * @see #register
212+ */
213+ @ CompilerDirectives .TruffleBoundary
214+ public final synchronized void scheduleFinalization () {
215+ for (var item : pendingItems ) {
216+ if (item .systemResource ) {
217+ item .enqueue ();
218+ }
219+ }
220+ }
221+
189222 /**
190223 * Awaits next item in the queue, if any.
191224 *
@@ -360,6 +393,7 @@ Collection<Item> awaitShutdown() {
360393
361394 /** A storage representation of a finalizable object handled by this system. */
362395 private static final class Item extends PhantomReference <ManagedResource > {
396+ private final boolean systemResource ;
363397 private final Object underlying ;
364398 private final Object finalizer ;
365399
@@ -393,10 +427,12 @@ private Item(
393427 ManagedResource referent ,
394428 Object underlying ,
395429 Object finalizer ,
430+ boolean systemResource ,
396431 ReferenceQueue <ManagedResource > queue ) {
397432 super (referent , queue );
398433 this .underlying = underlying ;
399434 this .finalizer = finalizer ;
435+ this .systemResource = systemResource ;
400436 }
401437
402438 /**
0 commit comments