/* * This file is part of the Jikes RVM project (http://jikesrvm.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. You * may obtain a copy of the License at * * http://www.opensource.org/licenses/eclipse-1.0.php * * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. */ package org.mmtk.harness; /** * A timeout thread. Exits the harness if it isn't cancelled in time. * * Use like this: * * TimeoutThread timeout = new TimeoutThread(10); * .. do stuff .. * timeout.cancel(); */ final class TimeoutThread implements Runnable { private static final boolean VERBOSE = false; private static final int MILLIS_PER_SECOND = 1000; private final long timeout; private boolean cancelled = false; private volatile boolean started = false; /** * Create a timeout object and start it running in its own * thread. * @param seconds Timeout in seconds */ TimeoutThread(int seconds) { this.timeout = seconds * MILLIS_PER_SECOND; new Thread(this).start(); synchronized (this) { while (!started) { try { /* Wait for the timeout thread to start running */ wait(); } catch (InterruptedException e) { } } } } /** * @see java.lang.Thread#run() */ @Override public void run() { long startTime = System.currentTimeMillis(); synchronized (this) { /* Inform the caller that the timeout thread has started */ started = true; notify(); while (!cancelled) { try { /* Sleep until woken by a cancel or the timer has expired */ long now = System.currentTimeMillis(); if (now - startTime >= timeout) { System.err.printf("Collection exceeded timeout %dms%n",timeout); Main.exitWithFailure(); } long sleepTime = Math.max(1,timeout - (now - startTime)); if (VERBOSE) { System.err.printf("Collection timeout: sleeping for %dms%n",sleepTime); } wait(sleepTime); } catch (InterruptedException e) { // Ignore interruptions } } } } /** Cancel the timeout */ public void cancel() { synchronized (this) { if (VERBOSE) { System.err.printf("Collection timeout: cancelled%n"); } cancelled = true; notify(); } } }