/*
 *    GeoTools - OpenSource mapping toolkit
 *    http://geotools.org
 *    (C) 2006, GeoTools Project Managment Committee (PMC)
 *    (C) 2006, Institut de Recherche pour le Développement
 *    (C) 2006, Geomatys
 *   
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License as published by the Free Software Foundation;
 *    version 2.1 of the License.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 */
package org.geotools.image.io.stream;

// J2SE dependencies
import java.util.Timer;
import java.util.TimerTask;


/**
 * Stops execution of {@link System#runFinalization} when a timeout is reach. This timer is
 * used in order to prevent system freeze that occurs sometime when waiting for finalization
 * in {@link UrlInputSpi#createInputStreamInstance}. If a {@code finalize()} method is blocked
 * in an I/O operation upon an interruptible channel, the channel will be closed and the finalize
 * method will receive a {@link java.nio.channels.ClosedByInterruptException}.
 * See {@link Thread#interrupt} javadoc for more details.
 * <p>
 * Most of the time, interruptions are never performed.
 *
 * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/unsupported/coverageio/src/main/java/org/geotools/image/io/stream/FinalizationStopper.java $
 * @version $Id: FinalizationStopper.java 25595 2007-05-20 13:58:56Z desruisseaux $
 * @author Martin Desruisseaux
 */
final class FinalizationStopper extends TimerTask {
    /**
     * Timer for stopping execution of {@link System#runFinalization}.
     *
     * @todo Uncomment the String argument when we will be allowed to compile for J2SE 1.5.
     */
    private static final Timer TIMER = new Timer(/*"Finalization stopper",*/ true);

    /**
     * The processus to stop.
     */
    private final Thread toStop;

    /**
     * {@code true} if the thread has been interrupted at least once.
     */
    volatile boolean interrupted;

    /**
     * Stops a new task which will stops current thread after the specified timeout. The
     * interruption will be repeated until {@link UrlInputSpi#createInputStreamInstance}
     * stop them.
     */
    FinalizationStopper(final long timeout) {
        this.toStop = Thread.currentThread();
        TIMER.schedule(this, timeout, timeout);
    }

    /**
     * Stops the thread.
     */
    public void run() {
        interrupted = true;
        toStop.interrupt();
    }
}
