8158174: jshell tool: leaks threads waiting on StopDetectingInputStream
authorjlahoda
Thu, 09 Jun 2016 14:20:11 +0200
changeset 38909 80e42e2d475b
parent 38908 f0c186d76c8a
child 38910 6cd27826bb5c
8158174: jshell tool: leaks threads waiting on StopDetectingInputStream Summary: Shutdown StopDetectingInputStream when closing the ConsoleIOContext. Reviewed-by: rfield
langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java
langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/StopDetectingInputStream.java
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java	Wed Jun 08 00:32:31 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java	Thu Jun 09 14:20:11 2016 +0200
@@ -215,6 +215,7 @@
         } catch (Exception ex) {
             throw new IOException(ex);
         }
+        input.shutdown();
     }
 
     private void bind(String shortcut, Object action) {
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/StopDetectingInputStream.java	Wed Jun 08 00:32:31 2016 -0700
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/StopDetectingInputStream.java	Thu Jun 09 14:20:11 2016 +0200
@@ -61,11 +61,14 @@
                         //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 @@
                 } catch (IOException ex) {
                     errorHandler.accept(ex);
                 } finally {
-                    state = StopDetectingInputStream.State.CLOSED;
+                    synchronized (StopDetectingInputStream.this) {
+                        state = StopDetectingInputStream.State.CLOSED;
+                    }
                 }
             }
         };
@@ -107,6 +112,11 @@
         }
     }
 
+    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 @@
         notifyAll();
     }
 
-    private synchronized void waitInputNeeded() {
+    private synchronized State waitInputNeeded() {
         while (state == State.WAIT) {
             try {
                 wait();
@@ -142,6 +152,8 @@
                 //ignore
             }
         }
+
+        return state;
     }
 
     public enum State {