--- old/src/java.base/share/classes/jdk/internal/ref/Cleaner.java 2016-03-06 13:37:19.296615512 +0100 +++ /dev/null 2016-03-06 10:21:05.155252491 +0100 @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.internal.ref; - -import java.lang.ref.*; -import java.security.AccessController; -import java.security.PrivilegedAction; - - -/** - * General-purpose phantom-reference-based cleaners. - * - *

Cleaners are a lightweight and more robust alternative to finalization. - * They are lightweight because they are not created by the VM and thus do not - * require a JNI upcall to be created, and because their cleanup code is - * invoked directly by the reference-handler thread rather than by the - * finalizer thread. They are more robust because they use phantom references, - * the weakest type of reference object, thereby avoiding the nasty ordering - * problems inherent to finalization. - * - *

A cleaner tracks a referent object and encapsulates a thunk of arbitrary - * cleanup code. Some time after the GC detects that a cleaner's referent has - * become phantom-reachable, the reference-handler thread will run the cleaner. - * Cleaners may also be invoked directly; they are thread safe and ensure that - * they run their thunks at most once. - * - *

Cleaners are not a replacement for finalization. They should be used - * only when the cleanup code is extremely simple and straightforward. - * Nontrivial cleaners are inadvisable since they risk blocking the - * reference-handler thread and delaying further cleanup and finalization. - * - * - * @author Mark Reinhold - */ - -public class Cleaner - extends PhantomReference - implements Runnable -{ - - // Dummy reference queue, needed because the PhantomReference constructor - // insists that we pass a queue. Nothing will ever be placed on this queue - // since the reference handler invokes cleaners explicitly. - // - private static final ReferenceQueue dummyQueue = new ReferenceQueue<>(); - - // Doubly-linked list of live cleaners, which prevents the cleaners - // themselves from being GC'd before their referents - // - private static Cleaner first = null; - - private Cleaner - next = null, - prev = null; - - private static synchronized Cleaner add(Cleaner cl) { - if (first != null) { - cl.next = first; - first.prev = cl; - } - first = cl; - return cl; - } - - private static synchronized boolean remove(Cleaner cl) { - - // If already removed, do nothing - if (cl.next == cl) - return false; - - // Update list - if (first == cl) { - if (cl.next != null) - first = cl.next; - else - first = cl.prev; - } - if (cl.next != null) - cl.next.prev = cl.prev; - if (cl.prev != null) - cl.prev.next = cl.next; - - // Indicate removal by pointing the cleaner to itself - cl.next = cl; - cl.prev = cl; - return true; - - } - - private final Runnable thunk; - - private Cleaner(Object referent, Runnable thunk) { - super(referent, dummyQueue); - this.thunk = thunk; - } - - /** - * Creates a new cleaner. - * - * @param ob the referent object to be cleaned - * @param thunk - * The cleanup code to be run when the cleaner is invoked. The - * cleanup code is run directly from the reference-handler thread, - * so it should be as simple and straightforward as possible. - * - * @return The new cleaner - */ - public static Cleaner create(Object ob, Runnable thunk) { - if (thunk == null) - return null; - return add(new Cleaner(ob, thunk)); - } - - /** - * Runs this cleaner, if it has not been run before. - */ - public void clean() { - if (!remove(this)) - return; - try { - thunk.run(); - } catch (final Throwable x) { - AccessController.doPrivileged(new PrivilegedAction<>() { - public Void run() { - if (System.err != null) - new Error("Cleaner terminated abnormally", x) - .printStackTrace(); - System.exit(1); - return null; - }}); - } - } - - @Override public void run() { - SecurityManager security = System.getSecurityManager(); - if (security != null) - security.checkPackageAccess("jdk.internal.ref"); - this.clean(); - } - -}