# HG changeset patch # User jlahoda # Date 1484039867 -3600 # Node ID 0c7c13fa7bee9f55c8d7054aa2299c408cd90cdc # Parent 006808ae5f6e70459bbf9d23ce3e9acdd7cd9149 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 diff -r 006808ae5f6e -r 0c7c13fa7bee langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/StopDetectingInputStream.java --- 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 { diff -r 006808ae5f6e -r 0c7c13fa7bee langtools/test/jdk/jshell/StopExecutionTest.java --- 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 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(); + } + } }