mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
add transactions for startup & exit
This commit is contained in:
@@ -97,6 +97,19 @@ public abstract class TransactionGuard {
|
||||
getInstance().submitMergeableTransaction(TransactionKind.NO_MERGE, transaction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the given code synchronously inside a transaction. Fails if transactions of given kind are not allowed at this moment.
|
||||
* @see #startSynchronousTransaction(TransactionKind)
|
||||
*/
|
||||
public static void syncTransaction(@NotNull TransactionKind kind, @NotNull Runnable transaction) {
|
||||
AccessToken token = getInstance().startSynchronousTransaction(kind);
|
||||
try {
|
||||
transaction.run();
|
||||
} finally {
|
||||
token.finish();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a transaction and waits for it to be completed. Fails if invoked on UI thread inside an incompatible transaction,
|
||||
* or inside a read action on non-UI thread.
|
||||
|
||||
+5
-17
@@ -19,8 +19,7 @@ import com.intellij.ProjectTopics;
|
||||
import com.intellij.notification.Notification;
|
||||
import com.intellij.notification.NotificationType;
|
||||
import com.intellij.notification.Notifications;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.*;
|
||||
import com.intellij.openapi.components.State;
|
||||
import com.intellij.openapi.components.Storage;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -126,26 +125,15 @@ public class ModuleManagerComponent extends ModuleManagerImpl {
|
||||
return;
|
||||
}
|
||||
|
||||
Runnable runnableWithProgress = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (final Module module : myModuleModel.myModules.values()) {
|
||||
final Application app = ApplicationManager.getApplication();
|
||||
final Runnable swingRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
fireModuleAddedInWriteAction(module);
|
||||
}
|
||||
};
|
||||
ProgressIndicator pi = ProgressManager.getInstance().getProgressIndicator();
|
||||
app.invokeAndWait(swingRunnable, pi.getModalityState());
|
||||
}
|
||||
Runnable runnableWithProgress = () -> {
|
||||
for (final Module module : myModuleModel.myModules.values()) {
|
||||
TransactionGuard.getInstance().submitTransactionAndWait(TransactionKind.ANY_CHANGE, () -> fireModuleAddedInWriteAction(module));
|
||||
}
|
||||
};
|
||||
|
||||
ProgressIndicator progressIndicator = myProgressManager.getProgressIndicator();
|
||||
if (progressIndicator == null) {
|
||||
myProgressManager.runProcessWithProgressSynchronously(runnableWithProgress, "Initializing modules...", false, myProject);
|
||||
myProgressManager.runProcessWithProgressSynchronously(runnableWithProgress, "Initializing Modules...", false, myProject);
|
||||
}
|
||||
else {
|
||||
runnableWithProgress.run();
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.ide.caches.FileContent;
|
||||
import com.intellij.ide.startup.StartupManagerEx;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.TransactionGuard;
|
||||
import com.intellij.openapi.components.AbstractProjectComponent;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
@@ -80,15 +81,10 @@ public class FileBasedIndexProjectHandler extends AbstractProjectComponent imple
|
||||
public void run() {
|
||||
PushedFilePropertiesUpdater.getInstance(project).initializeProperties();
|
||||
|
||||
// dumb mode should start before post-startup activities
|
||||
// only when queueTask is called from UI thread, we can guarantee that
|
||||
// when the method returns, the application has entered dumb mode
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!project.isDisposed() && FileBasedIndex.getInstance() instanceof FileBasedIndexImpl) {
|
||||
DumbService.getInstance(project).queueTask(new UnindexedFilesUpdater(project, true));
|
||||
}
|
||||
// schedule dumb mode start after the read action we're currently in
|
||||
TransactionGuard.submitTransaction(() -> {
|
||||
if (!project.isDisposed() && FileBasedIndex.getInstance() instanceof FileBasedIndexImpl) {
|
||||
DumbService.getInstance(project).queueTask(new UnindexedFilesUpdater(project, true));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+8
-8
@@ -308,12 +308,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
}
|
||||
}
|
||||
}
|
||||
runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Disposer.dispose(ApplicationImpl.this);
|
||||
}
|
||||
});
|
||||
TransactionGuard.syncTransaction(TransactionKind.ANY_CHANGE, () -> runWriteAction(() -> Disposer.dispose(this)));
|
||||
|
||||
Disposer.assertIsEmpty();
|
||||
return true;
|
||||
@@ -376,6 +371,11 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
@Override
|
||||
public Future<?> executeOnPooledThread(@NotNull final Runnable action) {
|
||||
return ourThreadExecutorsService.submit(new Runnable() {
|
||||
@Override
|
||||
public String toString() {
|
||||
return action.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
assert !isReadAccessAllowed(): describe(Thread.currentThread());
|
||||
@@ -864,7 +864,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
}
|
||||
|
||||
private boolean doExit(boolean allowListenersToCancel, boolean restart) {
|
||||
saveSettings();
|
||||
TransactionGuard.syncTransaction(TransactionKind.ANY_CHANGE, this::saveSettings);
|
||||
|
||||
if (allowListenersToCancel && !canExit()) {
|
||||
return false;
|
||||
@@ -1230,8 +1230,8 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App
|
||||
assertIsDispatchThread(getStatus(), "Write access is allowed from event dispatch thread only");
|
||||
HeavyProcessLatch.INSTANCE.stopThreadPrioritizing(); // let non-cancellable read actions complete faster, if present
|
||||
if (!TransactionGuard.getInstance().isInsideTransaction() && Registry.is("ide.require.transaction.for.model.changes", false)) {
|
||||
// please assign exceptions that occur here to Peter
|
||||
LOG.error("Write access is allowed from model transactions only, see TransactionGuard documentation for details");
|
||||
//todo throw new IllegalStateException("Write access is allowed from model transactions only, see TransactionGuard documentation for details");
|
||||
}
|
||||
boolean writeActionPending = myWriteActionPending;
|
||||
myWriteActionPending = true;
|
||||
|
||||
+11
-20
@@ -28,10 +28,7 @@ import com.intellij.notification.NotificationListener;
|
||||
import com.intellij.notification.NotificationType;
|
||||
import com.intellij.notification.NotificationsManager;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ApplicationNamesInfo;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.*;
|
||||
import com.intellij.openapi.components.impl.stores.StorageUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
@@ -351,9 +348,8 @@ public class ProjectManagerImpl extends ProjectManagerEx implements Disposable {
|
||||
}
|
||||
|
||||
fireProjectOpened(project);
|
||||
DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try (AccessToken ignored = TransactionGuard.getInstance().startSynchronousTransaction(TransactionKind.ANY_CHANGE)) {
|
||||
DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, () ->
|
||||
DumbService.getInstance(project).queueTask(new DumbModeTask() {
|
||||
@Override
|
||||
public void performInDumbMode(@NotNull ProgressIndicator indicator) {
|
||||
@@ -364,9 +360,9 @@ public class ProjectManagerImpl extends ProjectManagerEx implements Disposable {
|
||||
public String toString() {
|
||||
return "wait for file watcher";
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
final StartupManagerImpl startupManager = (StartupManagerImpl)StartupManager.getInstance(project);
|
||||
boolean ok = myProgressManager.runProcessWithProgressSynchronously(new Runnable() {
|
||||
@@ -374,15 +370,10 @@ public class ProjectManagerImpl extends ProjectManagerEx implements Disposable {
|
||||
public void run() {
|
||||
startupManager.runStartupActivities();
|
||||
|
||||
// dumb mode should start before post-startup activities
|
||||
// only when startCacheUpdate is called from UI thread, we can guarantee that
|
||||
// when the method returns, the application has entered dumb mode
|
||||
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
startupManager.startCacheUpdate();
|
||||
}
|
||||
});
|
||||
// Startup activities (e.g. the one in FileBasedIndexProjectHandler) have scheduled dumb mode to begin "later"
|
||||
// Now we schedule-and-wait to the same event queue to guarantee that the dumb mode really begins now:
|
||||
// Post-startup activities should not ever see unindexed and at the same time non-dumb state
|
||||
TransactionGuard.getInstance().submitTransactionAndWait(TransactionKind.ANY_CHANGE, startupManager::startCacheUpdate);
|
||||
|
||||
startupManager.runPostStartupActivitiesFromExtensions();
|
||||
|
||||
@@ -615,7 +606,7 @@ public class ProjectManagerImpl extends ProjectManagerEx implements Disposable {
|
||||
if (checkCanClose && !canClose(project)) return false;
|
||||
final ShutDownTracker shutDownTracker = ShutDownTracker.getInstance();
|
||||
shutDownTracker.registerStopperThread(Thread.currentThread());
|
||||
try {
|
||||
try (AccessToken ignored = TransactionGuard.getInstance().startSynchronousTransaction(TransactionKind.NO_MERGE)) {
|
||||
if (save) {
|
||||
FileDocumentManager.getInstance().saveAllDocuments();
|
||||
project.save();
|
||||
|
||||
Reference in New Issue
Block a user