From a88ad70110d848ec247c73af27608dae86c5194c Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Thu, 21 May 2015 19:03:15 +0300 Subject: [PATCH] IDEA-140501 Send repo update events on a separate thread Otherwise, if update() is called from VcsRepositoryManager#getRepositoryForRoot (a Repository for the root was not created yet => it is being created at once) other messages from the message bus queue block the current thread from returning the created GitRepositoryImpl instance, and moreover may cause other GitRepositoryImpl() creations (because the repo map is still not up-to-date). A correct solution is to disable all git/hg actions while the repo map is being updated, but it is a large change. On the other hand, sending notification events on a separate thread shouldn't hurt. --- .../src/git4idea/repo/GitRepositoryImpl.java | 12 ++++++++++-- .../org/zmlx/hg4idea/repo/HgRepositoryImpl.java | 14 ++++++++++---- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/plugins/git4idea/src/git4idea/repo/GitRepositoryImpl.java b/plugins/git4idea/src/git4idea/repo/GitRepositoryImpl.java index b6e05731a9d1..89041eed257d 100644 --- a/plugins/git4idea/src/git4idea/repo/GitRepositoryImpl.java +++ b/plugins/git4idea/src/git4idea/repo/GitRepositoryImpl.java @@ -17,6 +17,7 @@ package git4idea.repo; import com.intellij.dvcs.repo.RepositoryImpl; import com.intellij.openapi.Disposable; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.vcs.AbstractVcs; @@ -206,12 +207,19 @@ public class GitRepositoryImpl extends RepositoryImpl implements GitRepository { } // previous info can be null before the first update - private static void notifyListeners(@NotNull GitRepository repository, @Nullable GitRepoInfo previousInfo, @NotNull GitRepoInfo info) { + private static void notifyListeners(@NotNull final GitRepository repository, @Nullable GitRepoInfo previousInfo, @NotNull GitRepoInfo info) { if (Disposer.isDisposed(repository.getProject())) { return; } if (!info.equals(previousInfo)) { - repository.getProject().getMessageBus().syncPublisher(GIT_REPO_CHANGE).repositoryChanged(repository); + ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { + public void run() { + Project project = repository.getProject(); + if (!project.isDisposed()) { + project.getMessageBus().syncPublisher(GIT_REPO_CHANGE).repositoryChanged(repository); + } + } + }); } } diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java index 69a6f32bc18a..9246480463e4 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java @@ -18,6 +18,7 @@ package org.zmlx.hg4idea.repo; import com.intellij.dvcs.repo.RepositoryImpl; import com.intellij.openapi.Disposable; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; @@ -213,7 +214,7 @@ public class HgRepositoryImpl extends RepositoryImpl implements HgRepository { HgRepoInfo currentInfo = readRepoInfo(); // update only if something changed!!! if update every time - new log will be refreshed every time, too. // Then blinking and do not work properly; - Project project = getProject(); + final Project project = getProject(); if (!project.isDisposed() && !currentInfo.equals(myInfo)) { myInfo = currentInfo; HgCommandResult branchCommandResult = new HgBranchesCommand(project, getRoot()).collectBranches(); @@ -224,9 +225,14 @@ public class HgRepositoryImpl extends RepositoryImpl implements HgRepository { else { myOpenedBranches = HgBranchesCommand.collectNames(branchCommandResult); } - if (!project.isDisposed()) { - project.getMessageBus().syncPublisher(HgVcs.STATUS_TOPIC).update(project, getRoot()); - } + + ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { + public void run() { + if (!project.isDisposed()) { + project.getMessageBus().syncPublisher(HgVcs.STATUS_TOPIC).update(project, getRoot()); + } + } + }); } }