/* * Copyright (c) 2001, 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. * * This code 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 General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package nsk.share; /** * Harakiri is used to terminate a stress test with PASS exit status * before the test is terminated as timed out (and so failed). * *

Harakiri class holds a thread which sleeps for the given amount * of time, and then wakes up and executes System.exit() * with the given exit status. That thread is daemon, so it doesn't * prevent application from exiting once all its threads finish * before it's time for harakiri. Appointing harakiri in zero * delay implies immediate exit(). * *

There is a limitation: you may appoint no more than one harakiri * per application. */ public class Harakiri { /** * Use specific appoint() method to appoint harakiri. * * @see #appoint(int) * @see #appoint(int,int) */ protected Harakiri() {} /** * One harakiri per application, or null (by default). */ private static Thread harakiri = null; /** *

Return timeout (or waittime) value munus the margin * value (which is assumed 1 minute by default). * *

Treat args[0] as $TIMEOUT value, or seek for * -waittime=$WAITTIME value. If both parameters * (or either none of them) are assigned, throw an exception to * report parameters inconsistency. * *

Also, seek for -margin=... assignment, or assume margin * is 1 minute. * * @param args Is usually obtained via the application's command-line. * * @throws IllegalArgumentException If args[] is inconsistent. * * @see #appoint(int) * @see #appoint(int,int) */ public static int parseAppointment(String args[]) { int timeout=-1, margin=1; int timeouts=0, waittimes=0, margins=0; for (int i=0; i 1) throw new IllegalArgumentException( "more than one -waittime=... is set"); if (margins > 1) throw new IllegalArgumentException( "more than one -margin=... is set"); int result = timeout - margin; if (result <= 0) throw new IllegalArgumentException( "delay appointment must be greater than "+margin+" minutes"); return result; } /** * Appoint harakiri after the given amount of minutes, * so that exit status would be 95 (to simulate JCK-like PASS * status). * * @throws IllegalStateException If harakiri is already appointed. * * @see #appoint(int,int) * @see #parseAppointment(String[]) */ public static void appoint(int minutes) { appoint(minutes,95); // JCK-like PASS status } /** * Appoint Harakiri for the given amount of minutes, * so that the given status would be exited when time * is over. * * @throws IllegalStateException If harakiri is already appointed. * * @see #appoint(int) * @see #parseAppointment(String[]) */ public static void appoint(int minutes, int status) { if (harakiri != null) throw new IllegalStateException("Harakiri is already appointed."); final long timeToExit = System.currentTimeMillis() + 60*1000L*minutes; final int exitStatus = status; harakiri = new Thread(Harakiri.class.getName()) { public void run() { long timeToSleep = timeToExit - System.currentTimeMillis(); if (timeToSleep > 0) try { // // Use wait() instead of sleep(), because Java 2 // specification doesn't guarantee the method // sleep() to yield to other threads. // Object someDummyObject = new Object(); synchronized (someDummyObject) { someDummyObject.wait(timeToSleep); } } catch (InterruptedException exception) { exception.printStackTrace(System.err); // // OOPS, the dagger for harakiri looks broken: // return; }; // // OK, lets do it now: // System.err.println( "#\n# Harakiri: prescheduled program termination.\n#"); System.exit(exitStatus); // harakiri to all threads } }; harakiri.setPriority(Thread.MAX_PRIORITY); harakiri.setDaemon(true); harakiri.start(); } }