< prev index next >

src/java.base/share/classes/java/io/DeleteOnExitHook.java

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 2005, 2018, 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 --- 1,7 ---- /* ! * Copyright (c) 2005, 2019, 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
*** 33,43 **** * A set is used both to prevent double-insertion of the same file as well as offer * quick removal. */ class DeleteOnExitHook { ! private static LinkedHashSet<String> files = new LinkedHashSet<>(); static { // DeleteOnExitHook must be the last shutdown hook to be invoked. // Application shutdown hooks may add the first file to the // delete on exit list and cause the DeleteOnExitHook to be // registered during shutdown in progress. So set the --- 33,48 ---- * A set is used both to prevent double-insertion of the same file as well as offer * quick removal. */ class DeleteOnExitHook { ! private static class OrderCount { ! long order; ! int count; ! } ! private static long nextOrder; ! private static HashMap<String, OrderCount> files = new HashMap<>(); static { // DeleteOnExitHook must be the last shutdown hook to be invoked. // Application shutdown hooks may add the first file to the // delete on exit list and cause the DeleteOnExitHook to be // registered during shutdown in progress. So set the
*** 53,84 **** ); } private DeleteOnExitHook() {} ! static synchronized void add(String file) { if(files == null) { // DeleteOnExitHook is running. Too late to add a file throw new IllegalStateException("Shutdown in progress"); } ! files.add(file); } static void runHooks() { ! LinkedHashSet<String> theFiles; synchronized (DeleteOnExitHook.class) { theFiles = files; files = null; } ! ArrayList<String> toBeDeleted = new ArrayList<>(theFiles); ! ! // reverse the list to maintain previous jdk deletion order. ! // Last in first deleted. ! Collections.reverse(toBeDeleted); ! for (String filename : toBeDeleted) { ! (new File(filename)).delete(); ! } } } --- 58,102 ---- ); } private DeleteOnExitHook() {} ! static synchronized void deleteOnExit(String file) { if(files == null) { // DeleteOnExitHook is running. Too late to add a file throw new IllegalStateException("Shutdown in progress"); } ! OrderCount oc = files.computeIfAbsent(file, f -> new OrderCount()); ! oc.order = nextOrder++; ! oc.count++; ! } ! ! static synchronized void cancelDeleteOnExit(String file) { ! if(files != null) { ! files.compute(file, (f, oc) -> { ! if (oc == null) { ! throw new IllegalStateException( ! "Unbalanced cancelDeleteOnExit for missing deleteOnExit"); ! } ! return --oc.count <= 0 ? null : oc; ! }); ! } } static void runHooks() { ! HashMap<String, OrderCount> theFiles; synchronized (DeleteOnExitHook.class) { theFiles = files; files = null; } ! theFiles ! .entrySet() ! .stream() ! // last registered -> first deleted ! .sorted(Comparator.comparing(e -> -e.getValue().order)) ! .map(e -> new File(e.getKey())) ! .forEach(File::delete); } }
< prev index next >