performance: do not call .notify() after processWithProgress() terminates, rely on Future.get() instead

This commit is contained in:
Alexey Kudravtsev
2013-08-06 13:28:37 +04:00
parent 2c85e90196
commit a1e849491f
6 changed files with 24 additions and 75 deletions
@@ -188,7 +188,7 @@ public abstract class DaemonAnalyzerTestCase extends CodeInsightTestCase {
@Override
protected void tearDown() throws Exception {
((StartupManagerImpl)StartupManager.getInstance(getProject())).checkCleared();
((DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(getProject())).cleanupAfterTest(!LightPlatformTestCase.isLight(getProject()));
((DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(getProject())).cleanupAfterTest();
super.tearDown();
//((VirtualFilePointerManagerImpl)VirtualFilePointerManager.getInstance()).assertPointersDisposed();
}
@@ -52,7 +52,7 @@ public abstract class LightDaemonAnalyzerTestCase extends LightCodeInsightTestCa
@Override
protected void tearDown() throws Exception {
((DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(getProject())).cleanupAfterTest(!isLight(getProject()));
((DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(getProject())).cleanupAfterTest();
super.tearDown();
}
@@ -40,6 +40,7 @@ public abstract class ProgressManager {
ProgressManager.ourInstance.doCheckCanceled();
}
@Override
public NonCancelableSection startNonCancelableSection() {
return ProgressManager.ourInstance.startNonCancelableSection();
@@ -209,13 +210,6 @@ public abstract class ProgressManager {
if (set) {
myThreadIndicator.set(oldIndicator);
}
if (progress != null) {
synchronized (progress) {
progress.notifyAll();
}
}
}
}
}
@@ -261,7 +261,6 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx
if (callbackWhileWaiting != null) {
callbackWhileWaiting.run();
}
progress.waitFor(50);
UIUtil.dispatchAllInvocationEvents();
Throwable savedException = PassExecutorService.getSavedException(progress);
if (savedException != null) throw savedException;
@@ -270,11 +269,9 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx
throw e;
}
catch (Error e) {
e.printStackTrace();
throw e;
}
catch (Throwable e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
@@ -299,16 +296,8 @@ public class DaemonCodeAnalyzerImpl extends DaemonCodeAnalyzer implements JDOMEx
}
@TestOnly
public void cleanupAfterTest(boolean dispose) {
public void cleanupAfterTest() {
if (!myProject.isOpen()) return;
//stopProcess(false);
//if (dispose) {
// projectClosed();
// Disposer.dispose(myStatusBarUpdater);
// myStatusBarUpdater = null;
// Disposer.dispose(myDaemonListeners);
// myDaemonListeners = null;
//}
setUpdateByTimerEnabled(false);
waitForTermination();
}
@@ -61,18 +61,6 @@ public class DaemonProgressIndicator extends AbstractProgressIndicatorBase {
super.start();
}
public boolean waitFor(int millisTimeout) {
synchronized (this) {
try {
// we count on ProgressManagerImpl doing progress.notifyAll() on finish
wait(millisTimeout);
}
catch (InterruptedException ignored) {
}
}
return isCanceled();
}
@TestOnly
public static void setDebug(boolean debug) {
DaemonProgressIndicator.debug = debug;
@@ -40,18 +40,17 @@ import javax.swing.*;
import java.awt.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class ProgressManagerImpl extends ProgressManager implements Disposable{
@NonNls private static final String PROCESS_CANCELED_EXCEPTION = "idea.ProcessCanceledException";
private final AtomicInteger myCurrentUnsafeProgressCount = new AtomicInteger(0);
private final AtomicInteger myCurrentModalProgressCount = new AtomicInteger(0);
private static volatile int ourLockedCheckCounter = 0;
private static final boolean DISABLED = "disabled".equals(System.getProperty(PROCESS_CANCELED_EXCEPTION));
private static final boolean DISABLED = "disabled".equals(System.getProperty("idea.ProcessCanceledException"));
private final ScheduledFuture<?> myCheckCancelledFuture;
public ProgressManagerImpl(Application application) {
@@ -63,7 +62,8 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
ProgressIndicatorProvider.ourNeedToCheckCancel = true;
}
}, 0, 10, TimeUnit.MILLISECONDS);
} else {
}
else {
myCheckCancelledFuture = null;
}
}
@@ -123,7 +123,7 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
}
@Override
public NonCancelableSection startNonCancelableSection() {
public final NonCancelableSection startNonCancelableSection() {
NonCancelableIndicator nonCancelor = new NonCancelableIndicator(myThreadIndicator.get());
myThreadIndicator.set(nonCancelor);
return nonCancelor;
@@ -131,13 +131,7 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
@Override
public void executeNonCancelableSection(@NotNull Runnable runnable) {
NonCancelableSection nonCancelor = startNonCancelableSection();
try {
runnable.run();
}
finally {
nonCancelor.done();
}
executeProcessUnderProgress(runnable, new NonCancelableIndicator(getProgressIndicator()));
}
@Override
@@ -174,9 +168,6 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
executeProcessUnderProgress(new Runnable(){
@Override
public void run() {
synchronized (process) {
process.notifyAll();
}
try {
if (progress != null && !progress.isRunning()) {
progress.start();
@@ -190,9 +181,6 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
if (progress instanceof ProgressIndicatorEx) {
((ProgressIndicatorEx)progress).processFinish();
}
synchronized (process) {
process.notifyAll();
}
}
}
}
@@ -281,7 +269,6 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
private static boolean runProcessWithProgressSynchronously(final Task task, @Nullable final JComponent parentComponent) {
final long start = System.currentTimeMillis();
long time = 0;
final boolean result = ((ApplicationEx)ApplicationManager.getApplication())
.runProcessWithProgressSynchronously(new TaskContainer(task) {
@Override
@@ -292,7 +279,7 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
if (result) {
final long end = System.currentTimeMillis();
final Task.NotificationInfo notificationInfo = task.notifyFinished();
time = end - start;
long time = end - start;
if (notificationInfo != null && time > 5000) { // show notification only if process took more than 5 secs
final JFrame frame = WindowManager.getInstance().getFrame(task.getProject());
if (!frame.hasFocus()) {
@@ -353,7 +340,7 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
});
}
public static void runProcessWithProgressAsynchronously(@NotNull Task.Backgroundable task) {
private static void runProcessWithProgressAsynchronously(@NotNull Task.Backgroundable task) {
final ProgressIndicator progressIndicator;
if (ApplicationManager.getApplication().isHeadlessEnvironment()) {
progressIndicator = new EmptyProgressIndicator();
@@ -364,13 +351,15 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
runProcessWithProgressAsynchronously(task, progressIndicator, null);
}
@Override
public void runProcessWithProgressAsynchronously(@NotNull Task.Backgroundable task, @NotNull ProgressIndicator progressIndicator) {
runProcessWithProgressAsynchronously(task, progressIndicator, null);
}
public static void runProcessWithProgressAsynchronously(@NotNull final Task.Backgroundable task,
@NotNull final ProgressIndicator progressIndicator,
@Nullable final Runnable continuation) {
@NotNull
public static Future<?> runProcessWithProgressAsynchronously(@NotNull final Task.Backgroundable task,
@NotNull final ProgressIndicator progressIndicator,
@Nullable final Runnable continuation) {
if (progressIndicator instanceof Disposable) {
Disposer.register(ApplicationManager.getApplication(), (Disposable)progressIndicator);
}
@@ -417,15 +406,7 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
}
};
synchronized (process) {
ApplicationManager.getApplication().executeOnPooledThread(action);
try {
process.wait();
}
catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
return ApplicationManager.getApplication().executeOnPooledThread(action);
}
@Override
@@ -500,19 +481,16 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
@Override
public void dispose() {
stopCheckCanceled();
}
private void stopCheckCanceled() {
if (myCheckCancelledFuture != null) myCheckCancelledFuture.cancel(false);
}
//for debugging
@TestOnly
@SuppressWarnings({"UnusedDeclaration"})
private static void stopCheckCanceled() {
((ProgressManagerImpl)getInstance()).dispose();
}
@TestOnly
@SuppressWarnings({"UnusedDeclaration"})
public static String isCanceledThread(Thread thread) {
public static String isCanceledThread(@NotNull Thread thread) {
try {
Field th = Thread.class.getDeclaredField("threadLocals");
th.setAccessible(true);
@@ -537,7 +515,7 @@ public class ProgressManagerImpl extends ProgressManager implements Disposable{
final int debugProgressTime = Registry.intValue("ide.debug.minProgressTime");
if (debugProgressTime > 0) {
try {
Thread.currentThread().sleep(debugProgressTime);
Thread.sleep(debugProgressTime);
}
catch (InterruptedException e) {
//ignore