< 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 >