Path: blob/master/src/java.desktop/share/classes/com/sun/imageio/stream/StreamCloser.java
41161 views
/*1* Copyright (c) 2005, 2021, 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 sun.awt.util.ThreadGroupUtils;2829import java.io.IOException;30import java.security.AccessController;31import java.security.PrivilegedAction;32import java.util.Set;33import java.util.WeakHashMap;34import javax.imageio.stream.ImageInputStream;3536/**37* This class provide means to properly close hanging38* image input/output streams on VM shutdown.39* This might be useful for proper cleanup such as removal40* of temporary files.41*42* Addition of stream do not prevent it from being garbage collected43* if no other references to it exists. Stream can be closed44* explicitly without removal from StreamCloser queue.45* Explicit removal from the queue only helps to save some memory.46*/47public class StreamCloser {4849private static WeakHashMap<CloseAction, Object> toCloseQueue;50private static Thread streamCloser;5152@SuppressWarnings("removal")53public static void addToQueue(CloseAction ca) {54synchronized (StreamCloser.class) {55if (toCloseQueue == null) {56toCloseQueue =57new WeakHashMap<CloseAction, Object>();58}5960toCloseQueue.put(ca, null);6162if (streamCloser == null) {63final Runnable streamCloserRunnable = new Runnable() {64public void run() {65if (toCloseQueue != null) {66synchronized (StreamCloser.class) {67Set<CloseAction> set =68toCloseQueue.keySet();69// Make a copy of the set in order to avoid70// concurrent modification (the is.close()71// will in turn call removeFromQueue())72CloseAction[] actions =73new CloseAction[set.size()];74actions = set.toArray(actions);75for (CloseAction ca : actions) {76if (ca != null) {77try {78ca.performAction();79} catch (IOException e) {80}81}82}83}84}85}86};8788AccessController.doPrivileged((PrivilegedAction<Object>) () -> {89/* The thread must be a member of a thread group90* which will not get GCed before VM exit.91* Make its parent the top-level thread group.92*/93ThreadGroup tg = ThreadGroupUtils.getRootThreadGroup();94streamCloser = new Thread(tg, streamCloserRunnable,95"StreamCloser", 0, false);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}106107public static void removeFromQueue(CloseAction ca) {108synchronized (StreamCloser.class) {109if (toCloseQueue != null) {110toCloseQueue.remove(ca);111}112}113}114115public static CloseAction createCloseAction(ImageInputStream iis) {116return new CloseAction(iis);117}118119public static final class CloseAction {120private ImageInputStream iis;121122private CloseAction(ImageInputStream iis) {123this.iis = iis;124}125126public void performAction() throws IOException {127if (iis != null) {128iis.close();129}130}131}132}133134135