IDEA-54340 Deadlock while trying to execute large
authorGregory Shrago <Gregory.Shrago@jetbrains.com>
Mon, 26 Apr 2010 13:45:14 +0000 (17:45 +0400)
committerGregory Shrago <Gregory.Shrago@jetbrains.com>
Mon, 26 Apr 2010 14:10:44 +0000 (18:10 +0400)
IDEA-53888 Error when typing in console

platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java

index 3f1bf7904db6d2859faa048526e797d721c15356..b52e8a75bb2b9afe3c394e7b6b9fda4246e709f4 100644 (file)
@@ -130,7 +130,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
   }
 
   private static final int HYPERLINK_LAYER = HighlighterLayer.SELECTION - 123;
-  private final Alarm mySpareTimeAlarm = new Alarm();
+  private final Alarm mySpareTimeAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD, this);
 
   private final CopyOnWriteArraySet<ChangeListener> myListeners = new CopyOnWriteArraySet<ChangeListener>();
   private final Set<ConsoleViewContentType> myDeferredTypes = new HashSet<ConsoleViewContentType>();
@@ -177,8 +177,8 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
 
   private String myHelpId;
 
-  private final Alarm myFlushAlarm = new Alarm();
-
+  private final Alarm myFlushUserInputAlarm = new Alarm(Alarm.ThreadToUse.OWN_THREAD, this);
+  private final Alarm myFlushAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD, this);
   private final Runnable myFlushDeferredRunnable = new Runnable() {
     public void run() {
       flushDeferredText();
@@ -193,7 +193,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
 
   private final ArrayList<ConsoleInputListener> myConsoleInputListeners = new ArrayList<ConsoleInputListener>();
 
-  private final Alarm myFoldingAlarm;
+  private final Alarm myFoldingAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD, this);
   private final List<FoldRegion> myPendingFoldRegions = new ArrayList<FoldRegion>();
 
   public void addConsoleUserInputLestener(ConsoleInputListener consoleInputListener) {
@@ -264,7 +264,6 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
     }
 
     Disposer.register(project, this);
-    myFoldingAlarm = new Alarm(this);
   }
 
   public void attachToProcess(final ProcessHandler processHandler){
@@ -515,19 +514,25 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
   }
 
   private void flushDeferredUserInput() {
-    if (myState.isRunning()){
-      final String text = myDeferredUserInput.substring(0, myDeferredUserInput.length());
-      final int index = Math.max(text.lastIndexOf('\n'), text.lastIndexOf('\r'));
-      if (index < 0) return;
-      try{
-        myState.sendUserInput(text.substring(0, index + 1));
-      }
-      catch(IOException e){
-        return;
+    final String text = myDeferredUserInput.substring(0, myDeferredUserInput.length());
+    final int index = Math.max(text.lastIndexOf('\n'), text.lastIndexOf('\r'));
+    if (index < 0) return;
+    final String textToSend = text.substring(0, index + 1);
+    myDeferredUserInput.setLength(0);
+    myDeferredUserInput.append(text.substring(index + 1));
+    myFlushUserInputAlarm.addRequest(new Runnable() {
+      public void run() {
+        if (myState.isRunning()) {
+          try {
+            // this may block forever, see IDEA-54340
+            myState.sendUserInput(textToSend);
+          }
+          catch (IOException e) {
+            return;
+          }
+        }
       }
-      myDeferredUserInput.setLength(0);
-      myDeferredUserInput.append(text.substring(index + 1));
-    }
+    }, 0);
   }
 
   public Object getData(final String dataId) {
@@ -1396,7 +1401,8 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
     }
 
     document.insertString(startOffset, s);
-    editor.getCaretModel().moveToOffset(startOffset + s.length());
+    // Math.max is needed when cyclic buffer is used
+    editor.getCaretModel().moveToOffset(Math.min(startOffset + s.length(), document.getTextLength()));
     editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
   }