From 24aa1fcd70278fcf6258297a18f65fef488e5b3a Mon Sep 17 00:00:00 2001 From: irengrig Date: Tue, 23 Nov 2010 18:03:57 +0300 Subject: [PATCH] IDEA-61566 DeadLock on git update - apply patch splitted into smaller write actions --- .../diff/impl/patch/formove/PatchApplier.java | 4 +- .../impl/patch/formove/PathsVerifier.java | 17 +++++- .../vcs/changes/patch/ApplyPatchAction.java | 58 ++++++++++++------- 3 files changed, 55 insertions(+), 24 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/patch/formove/PatchApplier.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/patch/formove/PatchApplier.java index 1ae3557eb2f3..aba9b4f4f2c6 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/patch/formove/PatchApplier.java +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/patch/formove/PatchApplier.java @@ -96,7 +96,7 @@ public class PatchApplier { final ApplyPatchStatus patchStatus = nonWriteActionPreCheck(); if (ApplyPatchStatus.FAILURE.equals(patchStatus)) return patchStatus; - final ApplyPatchStatus applyStatus = ApplicationManager.getApplication().runWriteAction(new Computable() { + final ApplyPatchStatus applyStatus = ApplicationManager.getApplication().runReadAction(new Computable() { public ApplyPatchStatus compute() { final Ref refStatus = new Ref(ApplyPatchStatus.FAILURE); CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { @@ -172,7 +172,7 @@ public class PatchApplier { } protected ApplyPatchStatus executeWritable() { - return ApplicationManager.getApplication().runWriteAction(new Computable() { + return ApplicationManager.getApplication().runReadAction(new Computable() { public ApplyPatchStatus compute() { final Ref refStatus = new Ref(ApplyPatchStatus.FAILURE); CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/patch/formove/PathsVerifier.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/patch/formove/PathsVerifier.java index 039337c18fdf..e9c5632cfd54 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/patch/formove/PathsVerifier.java +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/patch/formove/PathsVerifier.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.diff.impl.patch.formove; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diff.impl.patch.BinaryFilePatch; import com.intellij.openapi.diff.impl.patch.FilePatch; import com.intellij.openapi.diff.impl.patch.TextFilePatch; @@ -463,7 +464,21 @@ public class PathsVerifier { final MovedFileData movedFile = myMovedFiles.get(file); if (movedFile != null) { myBeforePaths.add(new FilePathImpl(file.getParent(), file.getName(), file.isDirectory())); - final VirtualFile moveResult = movedFile.doMove(); + final IOException[] exc = new IOException[1]; + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + try { + final VirtualFile moveResult = movedFile.doMove(); + } + catch (IOException e) { + exc[0] = e; + } + } + }); + if (exc[0] != null) { + throw exc[0]; + } } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchAction.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchAction.java index a5b06db4ec4f..2074f6990d36 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchAction.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchAction.java @@ -25,6 +25,8 @@ package com.intellij.openapi.vcs.changes.patch; import com.intellij.openapi.actionSystem.ActionPlaces; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.application.Application; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.diff.ActionButtonPresentation; import com.intellij.openapi.diff.DiffManager; @@ -40,14 +42,17 @@ import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Computable; import com.intellij.openapi.vcs.*; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Consumer; import com.intellij.util.containers.Convertor; import com.intellij.util.containers.MultiMap; +import com.intellij.vcsUtil.Rethrow; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.io.IOException; import java.util.Collection; import java.util.LinkedList; import java.util.List; @@ -113,13 +118,29 @@ public class ApplyPatchAction extends DumbAwareAction { return sb.toString(); } - public static ApplyPatchStatus applyOnly(final Project project, final ApplyFilePatchBase patch, final ApplyPatchContext context, final VirtualFile file) { + public static ApplyPatchStatus applyOnly(final Project project, final ApplyFilePatchBase patch, + final ApplyPatchContext context, final VirtualFile file) { final T patchBase = patch.getPatch(); - try { - return patch.apply(file, context, project); - } - catch(ApplyPatchException ex) { - if (!patchBase.isNewFile() && !patchBase.isDeletedFile() && patchBase instanceof TextFilePatch) { + final Application application = ApplicationManager.getApplication(); + final ApplyPatchException[] exc = new ApplyPatchException[1]; + final ApplyPatchStatus applyPatchStatus = application.runWriteAction(new Computable() { + @Override + public ApplyPatchStatus compute() { + try { + return patch.apply(file, context, project); + } + catch (IOException e) { + LOG.error(e); + return ApplyPatchStatus.FAILURE; + } + catch (ApplyPatchException e) { + exc[0] = e; + } + return ApplyPatchStatus.FAILURE; + } + }); + if (exc[0] != null) { + if (! patchBase.isNewFile() && ! patchBase.isDeletedFile() && patchBase instanceof TextFilePatch) { //final VirtualFile beforeRename = (pathBeforeRename == null) ? file : pathBeforeRename; ApplyPatchStatus mergeStatus = mergeAgainstBaseVersion(project, file, new FilePathImpl(file), (TextFilePatch) patchBase, ApplyPatchMergeRequestFactory.INSTANCE); @@ -127,21 +148,11 @@ public class ApplyPatchAction extends DumbAwareAction { return mergeStatus; } } - Messages.showErrorDialog(project, VcsBundle.message("patch.apply.error", patchBase.getBeforeName(), ex.getMessage()), + Messages.showErrorDialog(project, VcsBundle.message("patch.apply.error", patchBase.getBeforeName(), exc[0].getMessage()), VcsBundle.message("patch.apply.dialog.title")); + return ApplyPatchStatus.FAILURE; } - catch (Exception ex) { - LOG.error(ex); - } - return ApplyPatchStatus.FAILURE; - } - - @Nullable - public static ApplyPatchStatus mergeAgainstBaseVersion(Project project, VirtualFile file, ApplyPatchContext context, - final TextFilePatch patch, - final PatchMergeRequestFactory mergeRequestFactory) { - final FilePath pathBeforeRename = context.getPathBeforeRename(file); - return mergeAgainstBaseVersion(project, file, pathBeforeRename, patch, mergeRequestFactory); + return applyPatchStatus; } @Nullable @@ -159,7 +170,12 @@ public class ApplyPatchAction extends DumbAwareAction { return status; } if (status != ApplyPatchStatus.ALREADY_APPLIED) { - return showMergeDialog(project, file, threeTexts.getBase(), threeTexts.getPatched(), mergeRequestFactory); + return ApplicationManager.getApplication().runWriteAction(new Computable() { + @Override + public ApplyPatchStatus compute() { + return showMergeDialog(project, file, threeTexts.getBase(), threeTexts.getPatched(), mergeRequestFactory); + } + }); } else { return status; @@ -173,7 +189,7 @@ public class ApplyPatchAction extends DumbAwareAction { return ApplyPatchStatus.FAILURE; } final MergeRequest request = mergeRequestFactory.createMergeRequest(fileContent.toString(), patchedContent, content.toString(), file, - project); + project); DiffManager.getInstance().getDiffTool().show(request); if (request.getResult() == DialogWrapper.OK_EXIT_CODE) { return ApplyPatchStatus.SUCCESS;