Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/com/sun/imageio/stream/StreamCloser.java
38923 views
/*1* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.imageio.stream;2627import java.io.IOException;28import java.util.Set;29import java.util.WeakHashMap;30import javax.imageio.stream.ImageInputStream;3132/**33* This class provide means to properly close hanging34* image input/output streams on VM shutdown.35* This might be useful for proper cleanup such as removal36* of temporary files.37*38* Addition of stream do not prevent it from being garbage collected39* if no other references to it exists. Stream can be closed40* explicitly without removal from StreamCloser queue.41* Explicit removal from the queue only helps to save some memory.42*/43public class StreamCloser {4445private static WeakHashMap<CloseAction, Object> toCloseQueue;46private static Thread streamCloser;4748public static void addToQueue(CloseAction ca) {49synchronized (StreamCloser.class) {50if (toCloseQueue == null) {51toCloseQueue =52new WeakHashMap<CloseAction, Object>();53}5455toCloseQueue.put(ca, null);5657if (streamCloser == null) {58final Runnable streamCloserRunnable = new Runnable() {59public void run() {60if (toCloseQueue != null) {61synchronized (StreamCloser.class) {62Set<CloseAction> set =63toCloseQueue.keySet();64// Make a copy of the set in order to avoid65// concurrent modification (the is.close()66// will in turn call removeFromQueue())67CloseAction[] actions =68new CloseAction[set.size()];69actions = set.toArray(actions);70for (CloseAction ca : actions) {71if (ca != null) {72try {73ca.performAction();74} catch (IOException e) {75}76}77}78}79}80}81};8283java.security.AccessController.doPrivileged(84new java.security.PrivilegedAction() {85public Object run() {86/* The thread must be a member of a thread group87* which will not get GCed before VM exit.88* Make its parent the top-level thread group.89*/90ThreadGroup tg =91Thread.currentThread().getThreadGroup();92for (ThreadGroup tgn = tg;93tgn != null;94tg = tgn, tgn = tg.getParent());95streamCloser = new Thread(tg, streamCloserRunnable);96/* Set context class loader to null in order to avoid97* keeping a strong reference to an application classloader.98*/99streamCloser.setContextClassLoader(null);100Runtime.getRuntime().addShutdownHook(streamCloser);101return null;102}103});104}105}106}107108public static void removeFromQueue(CloseAction ca) {109synchronized (StreamCloser.class) {110if (toCloseQueue != null) {111toCloseQueue.remove(ca);112}113}114}115116public static CloseAction createCloseAction(ImageInputStream iis) {117return new CloseAction(iis);118}119120public static final class CloseAction {121private ImageInputStream iis;122123private CloseAction(ImageInputStream iis) {124this.iis = iis;125}126127public void performAction() throws IOException {128if (iis != null) {129iis.close();130}131}132}133}134135136