Home | History | Annotate | Download | only in io
      1 /*
      2  * Copyright (c) 2005, 2010, 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 package java.io;
     26 
     27 import java.util.*;
     28 import java.io.File;
     29 
     30 /**
     31  * This class holds a set of filenames to be deleted on VM exit through a shutdown hook.
     32  * A set is used both to prevent double-insertion of the same file as well as offer
     33  * quick removal.
     34  */
     35 
     36 class DeleteOnExitHook {
     37     private static LinkedHashSet<String> files = new LinkedHashSet<>();
     38     static {
     39         // BEGIN Android-changed: Use Runtime.addShutdownHook() rather than SharedSecrets.
     40         Runtime.getRuntime().addShutdownHook(new Thread() {
     41             public void run() {
     42                 runHooks();
     43             }
     44         });
     45         // END Android-changed: Use Runtime.addShutdownHook() rather than SharedSecrets.
     46     }
     47 
     48     private DeleteOnExitHook() {}
     49 
     50     static synchronized void add(String file) {
     51         if(files == null) {
     52             // DeleteOnExitHook is running. Too late to add a file
     53             throw new IllegalStateException("Shutdown in progress");
     54         }
     55 
     56         files.add(file);
     57     }
     58 
     59     static void runHooks() {
     60         LinkedHashSet<String> theFiles;
     61 
     62         synchronized (DeleteOnExitHook.class) {
     63             theFiles = files;
     64             files = null;
     65         }
     66 
     67         ArrayList<String> toBeDeleted = new ArrayList<>(theFiles);
     68 
     69         // reverse the list to maintain previous jdk deletion order.
     70         // Last in first deleted.
     71         Collections.reverse(toBeDeleted);
     72         for (String filename : toBeDeleted) {
     73             (new File(filename)).delete();
     74         }
     75     }
     76 }
     77