diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/SingleTaskController.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/SingleTaskController.java index 1dc718b5d987..fc0d2ea2ff26 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/SingleTaskController.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/SingleTaskController.java @@ -15,6 +15,7 @@ */ package com.intellij.vcs.log.data; +import com.intellij.openapi.Disposable; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.util.Consumer; @@ -36,7 +37,7 @@ import java.util.List; *

* The class is thread-safe: all operations are synchronized. */ -public abstract class SingleTaskController { +public abstract class SingleTaskController implements Disposable { private static final Logger LOG = Logger.getInstance(SingleTaskController.class); @@ -47,6 +48,8 @@ public abstract class SingleTaskController { @NotNull private List myAwaitingRequests; @Nullable private ProgressIndicator myRunningTask; + private boolean myIsDisposed = false; + public SingleTaskController(@NotNull Consumer handler, boolean cancelRunning) { myResultHandler = handler; myAwaitingRequests = ContainerUtil.newLinkedList(); @@ -60,6 +63,7 @@ public abstract class SingleTaskController { */ public final void request(@NotNull Request requests) { synchronized (LOCK) { + if (myIsDisposed) return; myAwaitingRequests.add(requests); LOG.debug("Added requests: " + requests); if (myRunningTask != null && myCancelRunning) { @@ -148,4 +152,19 @@ public abstract class SingleTaskController { } } } + + @Override + public void dispose() { + synchronized (LOCK) { + if (myIsDisposed) return; + myIsDisposed = true; + + if (myRunningTask != null) { + myRunningTask.cancel(); + myRunningTask = null; + } + + myAwaitingRequests.clear(); + } + } } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogData.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogData.java index 0fbb92edfa52..54f2def153e6 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogData.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogData.java @@ -124,6 +124,7 @@ public class VcsLogData implements Disposable, VcsLogDataProvider { myRefresher = new VcsLogRefresherImpl(myProject, myStorage, myLogProviders, myUserRegistry, myIndex, progress, myTopCommitsDetailsCache, this::fireDataPackChangeEvent, FAILING_EXCEPTION_HANDLER, RECENT_COMMITS_COUNT); + Disposer.register(this, myRefresher); myContainingBranchesGetter = new ContainingBranchesGetter(this, this); diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java index 1dd376d4f9e5..3aba2f1c2503 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java @@ -15,11 +15,13 @@ */ package com.intellij.vcs.log.data; +import com.intellij.openapi.Disposable; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vfs.VirtualFile; @@ -39,7 +41,7 @@ import org.jetbrains.annotations.Nullable; import java.util.*; import java.util.stream.Collectors; -public class VcsLogRefresherImpl implements VcsLogRefresher { +public class VcsLogRefresherImpl implements VcsLogRefresher, Disposable { private static final Logger LOG = Logger.getInstance(VcsLogRefresherImpl.class); @@ -88,6 +90,7 @@ public class VcsLogRefresherImpl implements VcsLogRefresher { return VcsLogRefresherImpl.this.startNewBackgroundTask(new MyRefreshTask(myDataPack)); } }; + Disposer.register(this, mySingleTaskController); } protected ProgressIndicator startNewBackgroundTask(@NotNull final Task.Backgroundable refreshTask) { @@ -192,6 +195,10 @@ public class VcsLogRefresherImpl implements VcsLogRefresher { return myProgress; } + @Override + public void dispose() { + } + private class MyRefreshTask extends Task.Backgroundable { @NotNull private DataPack myCurrentDataPack; diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogPersistentIndex.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogPersistentIndex.java index a0f01bf2e2db..aa40e353b7e3 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogPersistentIndex.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/index/VcsLogPersistentIndex.java @@ -131,6 +131,7 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable { myIndexingLimit.put(root, new AtomicInteger(getIndexingLimit())); } + Disposer.register(myIndexStorage != null ? myIndexStorage : this, mySingleTaskController); Disposer.register(disposableParent, this); } @@ -449,7 +450,7 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable { public void dispose() { } - static class IndexStorage { + static class IndexStorage implements Disposable { private static final String COMMITS = "commits"; private static final String MESSAGES = "messages"; private static final String PARENTS = "parents"; @@ -471,8 +472,7 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable { @NotNull FatalErrorHandler fatalErrorHandler, @NotNull Disposable parentDisposable) throws IOException { - Disposable disposable = Disposer.newDisposable(); - Disposer.register(parentDisposable, disposable); + Disposer.register(parentDisposable, this); try { int version = getVersion(); @@ -480,28 +480,28 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable { File commitsStorage = getStorageFile(INDEX, COMMITS, logId, version); myIsFresh = !commitsStorage.exists(); commits = new PersistentSetImpl<>(commitsStorage, EnumeratorIntegerDescriptor.INSTANCE, Page.PAGE_SIZE, null, version); - Disposer.register(disposable, () -> catchAndWarn(commits::close)); + Disposer.register(this, () -> catchAndWarn(commits::close)); File messagesStorage = getStorageFile(INDEX, MESSAGES, logId, VcsLogStorageImpl.VERSION + MESSAGES_VERSION); messages = new PersistentHashMap<>(messagesStorage, new IntInlineKeyDescriptor(), EnumeratorStringDescriptor.INSTANCE, Page.PAGE_SIZE); - Disposer.register(disposable, () -> catchAndWarn(messages::close)); + Disposer.register(this, () -> catchAndWarn(messages::close)); - trigrams = new VcsLogMessagesTrigramIndex(logId, fatalErrorHandler, disposable); - users = new VcsLogUserIndex(logId, userRegistry, fatalErrorHandler, disposable); - paths = new VcsLogPathsIndex(logId, roots, fatalErrorHandler, disposable); + trigrams = new VcsLogMessagesTrigramIndex(logId, fatalErrorHandler, this); + users = new VcsLogUserIndex(logId, userRegistry, fatalErrorHandler, this); + paths = new VcsLogPathsIndex(logId, roots, fatalErrorHandler, this); File parentsStorage = getStorageFile(INDEX, PARENTS, logId, version); parents = new PersistentHashMap<>(parentsStorage, EnumeratorIntegerDescriptor.INSTANCE, new IntListDataExternalizer(), Page.PAGE_SIZE, version); - Disposer.register(disposable, () -> catchAndWarn(parents::close)); + Disposer.register(this, () -> catchAndWarn(parents::close)); File renamesStorage = getStorageFile(INDEX, RENAMES, logId, version); renames = new PersistentSetImpl<>(renamesStorage, EnumeratorIntegerDescriptor.INSTANCE, Page.PAGE_SIZE, null, version); - Disposer.register(disposable, () -> catchAndWarn(renames::close)); + Disposer.register(this, () -> catchAndWarn(renames::close)); } catch (Throwable t) { - Disposer.dispose(disposable); + Disposer.dispose(this); throw t; } } @@ -532,6 +532,10 @@ public class VcsLogPersistentIndex implements VcsLogIndex, Disposable { public boolean isFresh() { return myIsFresh; } + + @Override + public void dispose() { + } } private class MySingleTaskController extends SingleTaskController { diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/visible/VisiblePackRefresherImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/visible/VisiblePackRefresherImpl.java index 332a98e64056..41921d26a428 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/visible/VisiblePackRefresherImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/visible/VisiblePackRefresherImpl.java @@ -23,6 +23,7 @@ import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.ContainerUtil; @@ -79,6 +80,7 @@ public class VisiblePackRefresherImpl implements VisiblePackRefresher, Disposabl return indicator; } }; + Disposer.register(this, myTaskController); myIndexingFinishedListener = root -> myTaskController.request(new IndexingFinishedRequest(root)); myLogData.getIndex().addListener(myIndexingFinishedListener);