1 /* 2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.internal.ref; 27 28 import jdk.internal.misc.InnocuousThread; 29 import jdk.internal.vm.annotation.ReservedStackAccess; 30 31 import java.lang.ref.Cleaner; 32 import java.security.AccessController; 33 import java.security.PrivilegedAction; 34 import java.util.concurrent.ThreadFactory; 35 36 /** 37 * CleanerFactory provides a Cleaner for use within system modules. 38 * The cleaner is created on the first reference to the CleanerFactory. 39 */ 40 public final class CleanerFactory { 41 42 /* The common Cleaner. Lazily initialized */ 43 private static class Common { 44 static final Cleaner INSTANCE = Cleaner.create(new ThreadFactory() { 45 @Override 46 public Thread newThread(Runnable r) { 47 return AccessController.doPrivileged(new PrivilegedAction<>() { 48 @Override 49 public Thread run() { 50 Thread t = InnocuousThread.newSystemThread("Common-Cleaner", r); 51 t.setPriority(Thread.MAX_PRIORITY - 2); 52 return t; 53 } 54 }); 55 } 56 }); 57 } 58 59 /* The NIO DirectByteBuffer ExtendedCleaner. Lazily initialized */ 60 private static class DBB { 61 static final ExtendedCleaner INSTANCE = ExtendedCleaner.create(new ThreadFactory() { 62 @Override 63 public Thread newThread(Runnable r) { 64 return AccessController.doPrivileged(new PrivilegedAction<>() { 65 @Override 66 public Thread run() { 67 Thread t = InnocuousThread.newSystemThread("DirectByteBuffer-Cleaner", r); 68 t.setPriority(Thread.MAX_PRIORITY - 2); 69 return t; 70 } 71 }); 72 } 73 }); 74 } 75 76 /** 77 * Cleaner for use within system modules. 78 * <p> 79 * This Cleaner will run on a thread whose context class loader 80 * is {@code null}. The system cleaning action to perform in 81 * this Cleaner should handle a {@code null} context class loader. 82 * 83 * @return a Cleaner for use within system modules 84 */ 85 public static Cleaner cleaner() { 86 return Common.INSTANCE; 87 } 88 89 /** 90 * ExtendedCleaner for DirectByteBuffer use. 91 * <p> 92 * This Cleaner will mostly run on a background thread whose 93 * context class loader is {@code null}. But since this is 94 * {@link ExtendedCleaner} it allows other threads to help executing 95 * cleaning actions. Cleaning actions to be performed in this ExtendedCleaner 96 * should handle a {@code null} context class loader and any application 97 * thread. When they are executed by an application thread they are 98 * executed in the context of {@link ReservedStackAccess} annotation. 99 * 100 * @return an ExtendedCleaner for use in DirectByteBuffer 101 */ 102 public static ExtendedCleaner dbbCleaner() { 103 return DBB.INSTANCE; 104 } 105 }