diff --git a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java index 9b4dfaa3e9b2..0d23ff0594d7 100644 --- a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java +++ b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java @@ -376,6 +376,8 @@ public class IdeEventQueue extends EventQueue { myIsInInputEvent = e instanceof InputEvent || e instanceof InputMethodEvent || e instanceof WindowEvent || e instanceof ActionEvent; if (myIsInInputEvent) { HeavyProcessLatch.INSTANCE.prioritizeUiActivity(); + } else { + HeavyProcessLatch.INSTANCE.stopThreadPrioritizing(); } AWTEvent oldEvent = myCurrentEvent; myCurrentEvent = e; diff --git a/platform/util/src/com/intellij/util/io/storage/HeavyProcessLatch.java b/platform/util/src/com/intellij/util/io/storage/HeavyProcessLatch.java index 83306ca3114a..0e6962249f12 100644 --- a/platform/util/src/com/intellij/util/io/storage/HeavyProcessLatch.java +++ b/platform/util/src/com/intellij/util/io/storage/HeavyProcessLatch.java @@ -36,9 +36,16 @@ public class HeavyProcessLatch { private final Set myHeavyProcesses = new THashSet(); private final EventDispatcher myEventDispatcher = EventDispatcher.create(HeavyProcessListener.class); + private final EventDispatcher myUIProcessDispatcher = EventDispatcher.create(HeavyProcessListener.class); private volatile Thread myUiActivityThread; - private volatile long myPrioritizingDeadLine; + /** + Don't wait forever in case someone forgot to stop prioritizing before waiting for other threads to complete + wait just for 12 seconds; this will be noticeable (and we'll get 2 thread dumps) but not fatal + */ + private static final int MAX_PRIORITIZATION_MILLIS = 12 * 1000; + private volatile long myPrioritizingStarted; + private final List toExecuteOutOfHeavyActivity = new ArrayList(); private HeavyProcessLatch() { @@ -137,6 +144,7 @@ public class HeavyProcessLatch { /** * Gives current event processed on Swing thread higher priority + * by letting other threads to sleep a bit whenever they call checkCanceled. * @see #stopThreadPrioritizing() */ public void prioritizeUiActivity() { @@ -146,19 +154,10 @@ public class HeavyProcessLatch { return; } - // don't wait forever in case someone forgot to stop prioritizing before waiting for other threads to complete - // wait just for 12 seconds; this will be noticeable (and we'll get 2 thread dumps) but not fatal - myPrioritizingDeadLine = System.currentTimeMillis() + 12 * 1000; + myPrioritizingStarted = System.currentTimeMillis(); myUiActivityThread = Thread.currentThread(); myUIProcessDispatcher.getMulticaster().processStarted(); - //noinspection SSBasedInspection - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - stopThreadPrioritizing(); - } - }); } /** @@ -167,6 +166,8 @@ public class HeavyProcessLatch { * @see #prioritizeUiActivity() */ public void stopThreadPrioritizing() { + if (myUiActivityThread == null) return; + myUiActivityThread = null; myUIProcessDispatcher.getMulticaster().processFinished(); } @@ -181,7 +182,13 @@ public class HeavyProcessLatch { if (state == Thread.State.WAITING || state == Thread.State.TIMED_WAITING || state == Thread.State.BLOCKED) { return false; } - if (System.currentTimeMillis() > myPrioritizingDeadLine) { + + long time = System.currentTimeMillis() - myPrioritizingStarted; + if (time < 5) { + return false; // don't sleep when EDT activities are very short (e.g. empty processing of mouseMoved events) + } + + if (time > MAX_PRIORITIZATION_MILLIS) { stopThreadPrioritizing(); return false; }