package net.vhati.modmanager.core;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Iterator;
import java.util.List;
/**
* A shutdown hook that waits on threads before deleting files.
*
* This hook's waiting will keep the VM alive until the threads complete.
*
* Usage:
* DelayedDeleteHook deleteHook = new DelayedDeleteHook();
* Runtime.getRuntime().addShutdownHook( deleteHook );
*/
public class DelayedDeleteHook extends Thread {
private LinkedHashSet<Thread> watchedThreads = new LinkedHashSet<Thread>();
private LinkedHashSet<File> doomedFiles = new LinkedHashSet<File>();
public synchronized void addWatchedThread( Thread t ) {
if ( watchedThreads == null )
throw new IllegalStateException( "Shutdown in progress" );
watchedThreads.add( t );
}
public synchronized void addDoomedFile( File f ) {
if ( doomedFiles == null )
throw new IllegalStateException( "Shutdown in progress" );
doomedFiles.add( f );
}
@Override
public void run() {
ArrayList<Thread> pendingThreads;
ArrayList<File> pendingFiles;
boolean interrupted = false;
synchronized ( this ) {
pendingThreads = new ArrayList<Thread>( watchedThreads );
pendingFiles = new ArrayList<File>( doomedFiles );
watchedThreads = null;
doomedFiles = null;
}
try {
// Wait on each thread.
Iterator<Thread> it = pendingThreads.iterator();
while ( it.hasNext() ) {
Thread t = it.next();
while ( t.isAlive() ) {
try {
t.join();
}
catch ( InterruptedException e ) {
interrupted = true;
}
}
it.remove();
}
Collections.reverse( pendingFiles );
for ( File f : pendingFiles ) {
f.delete();
}
}
finally {
if ( interrupted ) Thread.currentThread().interrupt();
}
}
}