8158174: jshell tool: leaks threads waiting on StopDetectingInputStream

Shutdown StopDetectingInputStream when closing the ConsoleIOContext.

Reviewed-by: rfield
This commit is contained in:
Jan Lahoda 2016-06-09 14:20:11 +02:00
parent 8696e295a8
commit ec1f537d10
2 changed files with 17 additions and 4 deletions

View File

@ -215,6 +215,7 @@ class ConsoleIOContext extends IOContext {
} catch (Exception ex) {
throw new IOException(ex);
}
input.shutdown();
}
private void bind(String shortcut, Object action) {

View File

@ -61,11 +61,14 @@ public final class StopDetectingInputStream extends InputStream {
//an external editor is running. At the same time, it needs to run while the
//user's code is running (so Ctrl-C is detected). Hence waiting here until
//there is a confirmed need for input.
waitInputNeeded();
StopDetectingInputStream.State currentState = waitInputNeeded();
if (currentState == StopDetectingInputStream.State.CLOSED) {
break;
}
if ((read = input.read()) == (-1)) {
break;
}
if (read == 3 && state == StopDetectingInputStream.State.BUFFER) {
if (read == 3 && currentState == StopDetectingInputStream.State.BUFFER) {
stop.run();
} else {
write(read);
@ -74,7 +77,9 @@ public final class StopDetectingInputStream extends InputStream {
} catch (IOException ex) {
errorHandler.accept(ex);
} finally {
state = StopDetectingInputStream.State.CLOSED;
synchronized (StopDetectingInputStream.this) {
state = StopDetectingInputStream.State.CLOSED;
}
}
}
};
@ -107,6 +112,11 @@ public final class StopDetectingInputStream extends InputStream {
}
}
public synchronized void shutdown() {
state = State.CLOSED;
notifyAll();
}
public synchronized void write(int b) {
if (state != State.BUFFER) {
state = State.WAIT;
@ -134,7 +144,7 @@ public final class StopDetectingInputStream extends InputStream {
notifyAll();
}
private synchronized void waitInputNeeded() {
private synchronized State waitInputNeeded() {
while (state == State.WAIT) {
try {
wait();
@ -142,6 +152,8 @@ public final class StopDetectingInputStream extends InputStream {
//ignore
}
}
return state;
}
public enum State {