/* * Copyright (c) 2016, 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 * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * 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.
*/
// Set to true to enable additional debug output staticboolean debug = true;
// True to test while running with -Xrs staticboolean RUNNING_WITH_Xrs = Boolean.getBoolean("Xrs");
/** * Print a debug message if enabled. * * @param format the format * @param args the arguments
*/ staticvoid printf(String format, Object... args) { if (debug) {
System.out.printf(" " + format, args);
}
}
// Provider of invalid signal names
@DataProvider(name = "invalidSunMiscSignalNames")
Object[][] invalidSunMiscSignalNames() { returnnew Object[][]{
{""},
{"I"},
{"SIG"},
{"SIGabc"},
{"SIGINT"}, // prefix not allowed
{"abc"},
};
}
static Object[][] concatArrays(Object[][]... arrays) { int l = 0; for (Object[][] a : arrays) {
l += a.length;
}
Object[][] newArray = new Object[l][];
l = 0; for (int i = 0; i < arrays.length; i++) {
System.arraycopy(arrays[i], 0, newArray, l, arrays[i].length);
l += arrays[i].length;
}
return newArray;
}
// Return true if the signal is one of the shutdown signals known to the VM privatestaticboolean isShutdownSignal(Signal signal) {
String name = signal.getName(); return name.equals("INT") || name.equals("HUP") || name.equals("TERM");
}
/** * Quick verification of supported signals using sun.misc.Signal. * * @param name the signal name * @throws InterruptedException would be an error if thrown
*/
@Test(dataProvider = "supportedSignals") staticvoid testSunMisc(String name, IsSupported supported, CanRegister register,
CanRaise raise, Invoked invoked) throws InterruptedException {
Handler h = new Handler();
SignalHandler orig = null;
Signal signal = null; try {
signal = new Signal(name); Assert.assertEquals(supported, IsSupported.YES, "Unexpected support for " + name);
// Note: JDK 8 did not check/throw NPE, passing null resulted in a segv
@Test(expectedExceptions = NullPointerException.class) staticvoid nullSignal() { new Signal(null);
}
// Test expected exception when raising a signal when no handler defined
@Test staticvoid testRaiseNoConsumer() {
Signal signal = new Signal("INT");
SignalHandler orig = null; try {
orig = Signal.handle(signal, SignalHandler.SIG_DFL);
printf("oldHandler: %s%n", orig); if (orig == SignalHandler.SIG_IGN) { // SIG_IGN for TERM means it cannot be handled return;
}
Signal.raise(signal); Assert.fail("Should have thrown IllegalArgumentException");
} catch (IllegalArgumentException iae) {
printf("IAE message: %s%n", iae.getMessage());
} finally { // Restore original signal handler if (orig != null && signal != null) {
Signal.handle(signal, orig);
}
}
}
/** * The thread that runs the handler for sun.misc.Signal should be a * Daemon thread.
*/
@Test staticvoid isDaemonThread() throws InterruptedException { if (RUNNING_WITH_Xrs) { return;
}
Handler handler = new Handler();
Signal signal = new Signal("INT");
SignalHandler orig = Signal.handle(signal, handler);
printf("oldHandler: %s%n", orig); if (orig == SignalHandler.SIG_IGN) { // SIG_IGN for INT means it cannot be handled return;
}
Signal.raise(signal); boolean handled = handler.semaphore()
.tryAcquire(Utils.adjustTimeout(100L), TimeUnit.MILLISECONDS); if (!handled) { // For debug try again
printf("Second try to see signal");
handled = handler.semaphore()
.tryAcquire(Utils.adjustTimeout(2L), TimeUnit.SECONDS);
} Assert.assertEquals(handled, !RUNNING_WITH_Xrs, "raising s.m.Signal did not get a callback;");
Assert.assertTrue(handler.wasDaemon(), "Thread.isDaemon running the handler; ");
}
// Check that trying to invoke SIG_DFL.handle throws UnsupportedOperationException.
@Test(expectedExceptions = UnsupportedOperationException.class) staticvoid cannotHandleSIGDFL() {
Signal signal = new Signal("INT"); Assert.assertNotNull(SignalHandler.SIG_DFL, "SIG_DFL null; ");
SignalHandler.SIG_DFL.handle(signal);
}
// Check that trying to invoke SIG_IGN.handle throws UnsupportedOperationException.
@Test(expectedExceptions = UnsupportedOperationException.class) staticvoid cannotHandleSIGIGN() {
Signal signal = new Signal("INT"); Assert.assertNotNull(SignalHandler.SIG_IGN, "SIG_IGN null; ");
SignalHandler.SIG_IGN.handle(signal);
}
// Check that setting a Signal handler returns the previous handler.
@Test() staticvoid checkLastHandler() { if (RUNNING_WITH_Xrs) { return;
}
Signal signal = new Signal("TERM");
Handler h1 = new Handler();
Handler h2 = new Handler();
SignalHandler orig = Signal.handle(signal, h1); if (orig == SignalHandler.SIG_IGN) { // SIG_IGN for TERM means it cannot be handled return;
}
/** * Test Handler, a SignalHandler for Signal notifications. * Signals a semaphore when invoked and records whether * the thread calling the Handler was a daemon.
*/ staticclass Handler implements SignalHandler { // A semaphore to check for accept being called
Semaphore sema = new Semaphore(0);
/** * Releases the semaphore when called as SignalHandler.handle. * * @param signal the Signal that occurred
*/
@Override publicvoid handle(Signal signal) { synchronized (this) {
wasDaemon = Thread.currentThread().isDaemon();
}
sema.release();
printf("sun.misc.handle sig: %s, num: %d%n", signal.getName(), signal.getNumber());
}
// Main can be used to run the tests from the command line with only testng.jar.
@SuppressWarnings("raw_types")
@Test(enabled = false) publicstaticvoid main(String[] args) { Class<?>[] testclass = {SunMiscSignalTest.class};
TestNG testng = new TestNG();
testng.setTestClasses(testclass);
testng.run();
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.