< prev index next >

src/java.base/share/classes/jdk/internal/ref/CleanerImpl.java

Print this page

        

*** 23,42 **** * questions. */ package jdk.internal.ref; import java.lang.ref.Cleaner; import java.lang.ref.Cleaner.Cleanable; import java.lang.ref.ReferenceQueue; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; ! ! import jdk.internal.misc.InnocuousThread; /** * CleanerImpl manages a set of object references and corresponding cleaning actions. * CleanerImpl provides the functionality of {@link java.lang.ref.Cleaner}. */ --- 23,46 ---- * questions. */ package jdk.internal.ref; + import jdk.internal.misc.InnocuousThread; + import java.lang.ref.Cleaner; import java.lang.ref.Cleaner.Cleanable; import java.lang.ref.ReferenceQueue; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicInteger; + import java.util.function.Consumer; import java.util.function.Function; ! import java.util.function.LongConsumer; ! import java.util.function.LongSupplier; ! import java.util.function.Supplier; /** * CleanerImpl manages a set of object references and corresponding cleaning actions. * CleanerImpl provides the functionality of {@link java.lang.ref.Cleaner}. */
*** 187,196 **** --- 191,365 ---- } /** * Prevent access to referent even when it is still alive. * + * @throws UnsupportedOperationException always + */ + @Override + public Object get() { + throw new UnsupportedOperationException("get"); + } + + /** + * Direct clearing of the referent is not supported. + * + * @throws UnsupportedOperationException always + */ + @Override + public void clear() { + throw new UnsupportedOperationException("clear"); + } + } + + /** + * Reference-valued resource, automatically cleaned when + * the tracked referent becomes phantom-reachable. + * + * @param <T> the type of resource + * @since 10 + */ + public static final class PhantomCleanableResource<T> + extends PhantomCleanable<Object> + implements Cleaner.CleanableResource<T> { + + private final T resource; + private Consumer<? super T> deallocator; + + /** + * Constructor for a phantom cleanable resource. + * @param obj the object to monitor + * @param cleaner the cleaner + * @param allocator the resource allocator function + * @param deallocator the resource de-allocator function + */ + public PhantomCleanableResource(Object obj, Cleaner cleaner, + Supplier<? extends T> allocator, + Consumer<? super T> deallocator) { + super(obj, cleaner); + try { + this.resource = allocator.get(); + } catch (Throwable t) { + // effectively de-register this cleanable in case + // resource allocation fails + super.clear(); + throw t; + } + this.deallocator = deallocator; + } + + + @Override + protected void performCleanup() { + Consumer<? super T> deallocator = this.deallocator; + // only when deallocator was assigned, we can be sure that + // allocator.get() returned successfully + if (deallocator != null) { + // mark that cleanup has been performed + this.deallocator = null; + deallocator.accept(resource); + } + } + + /** + * Access to the allocated resource. + * + * @return the allocated resource + */ + @Override + public T value() { + if (deallocator == null) { + throw new IllegalStateException("Already cleaned"); + } + return resource; + } + + /** + * Prevent access to referent even when it is still alive. + * + * @throws UnsupportedOperationException always + */ + @Override + public Object get() { + throw new UnsupportedOperationException("get"); + } + + /** + * Direct clearing of the referent is not supported. + * + * @throws UnsupportedOperationException always + */ + @Override + public void clear() { + throw new UnsupportedOperationException("clear"); + } + } + + /** + * Long-valued resource, automatically cleaned when + * the tracked referent becomes phantom-reachable. + * + * @since 10 + */ + public static final class PhantomLongCleanableResource + extends PhantomCleanable<Object> + implements Cleaner.LongCleanableResource { + + private final long resource; + private LongConsumer deallocator; + + /** + * Constructor for a phantom cleanable resource. + * @param obj the object to monitor + * @param cleaner the cleaner + * @param allocator the resource allocator function + * @param deallocator the resource de-allocator function + */ + public PhantomLongCleanableResource(Object obj, Cleaner cleaner, + LongSupplier allocator, + LongConsumer deallocator) { + super(obj, cleaner); + try { + this.resource = allocator.getAsLong(); + } catch (Throwable t) { + // effectively de-register this cleanable in case + // resource allocation fails + super.clear(); + throw t; + } + this.deallocator = deallocator; + } + + + @Override + protected void performCleanup() { + LongConsumer deallocator = this.deallocator; + // only when deallocator was assigned, we can be sure that + // allocator.get() returned successfully + if (deallocator != null) { + // mark that cleanup has been performed + this.deallocator = null; + deallocator.accept(resource); + } + } + + /** + * Access to the allocated resource. + * + * @return the allocated resource + */ + @Override + public long value() { + if (deallocator == null) { + throw new IllegalStateException("Already cleaned"); + } + return resource; + } + + /** + * Prevent access to referent even when it is still alive. + * * @throws UnsupportedOperationException always */ @Override public Object get() { throw new UnsupportedOperationException("get");
< prev index next >