8171385: jshell tool: unresponsive to ctrl-C in input wait on Windows
Summary: Ensuring stop is sent using the proper channel depending on the current state of the StopDetectingInputStream.
Reviewed-by: rfield
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/StopDetectingInputStream.java Mon Jan 09 18:04:16 2017 -0800
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/StopDetectingInputStream.java Tue Jan 10 10:17:47 2017 +0100
@@ -66,7 +66,7 @@
if ((read = input.read()) == (-1)) {
break;
}
- if (read == 3 && currentState == State.BUFFER) {
+ if (read == 3 && getState() == State.BUFFER) {
stop.run();
} else {
write(read);
@@ -141,6 +141,10 @@
}
}
+ private synchronized State getState() {
+ return state;
+ }
+
private synchronized State waitInputNeeded() {
while (state == State.WAIT) {
try {
--- a/langtools/test/jdk/jshell/StopExecutionTest.java Mon Jan 09 18:04:16 2017 -0800
+++ b/langtools/test/jdk/jshell/StopExecutionTest.java Tue Jan 10 10:17:47 2017 +0100
@@ -23,6 +23,7 @@
/*
* @test
+ * @bug 8171385
* @summary Test JShell#stop
* @modules jdk.jshell/jdk.internal.jshell.tool
* @build KullaTesting TestingInputStream
@@ -30,9 +31,13 @@
*/
import java.io.IOException;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Random;
+import java.util.concurrent.CountDownLatch;
+import java.util.function.Consumer;
import jdk.internal.jshell.tool.StopDetectingInputStream;
import jdk.internal.jshell.tool.StopDetectingInputStream.State;
@@ -128,4 +133,31 @@
}
}
+ public void testStopDetectingInputBufferWaitStop() throws Exception {
+ Runnable shouldNotHappenRun =
+ () -> { throw new AssertionError("Should not happen."); };
+ Consumer<Exception> shouldNotHappenExc =
+ exc -> { throw new AssertionError("Should not happen.", exc); };
+ StopDetectingInputStream sd = new StopDetectingInputStream(shouldNotHappenRun, shouldNotHappenExc);
+ CountDownLatch reading = new CountDownLatch(1);
+ PipedInputStream is = new PipedInputStream() {
+ @Override
+ public int read() throws IOException {
+ reading.countDown();
+ return super.read();
+ }
+ };
+ PipedOutputStream os = new PipedOutputStream(is);
+
+ sd.setInputStream(is);
+ sd.setState(State.BUFFER);
+ reading.await();
+ sd.setState(State.WAIT);
+ os.write(3);
+ int value = sd.read();
+
+ if (value != 3) {
+ throw new AssertionError();
+ }
+ }
}