diff options
author | Andrey Loskutov | 2016-05-30 17:16:08 +0000 |
---|---|---|
committer | Dani Megert | 2016-09-23 13:58:17 +0000 |
commit | 938ab5d592348f65249ed9cc454013850d035d32 (patch) | |
tree | 2ed483ef5cd015baa5f12d3414a59db2a0319ec6 /org.eclipse.ui.editors | |
parent | d0224e9edbcfc9358268121c5fba4b3aca59f4a1 (diff) | |
download | eclipse.platform.text-938ab5d592348f65249ed9cc454013850d035d32.tar.gz eclipse.platform.text-938ab5d592348f65249ed9cc454013850d035d32.tar.xz eclipse.platform.text-938ab5d592348f65249ed9cc454013850d035d32.zip |
Bug 482354 - SVN checkout deadlocks Eclipse
FileDocumentProvider.refreshFile(IFile) is called from UI thread but in
worst case (if the IFile is out-of-sync with file system state) it
acquires workspace lock for refreshing the resource state.
If at same time any workspace job holding a lock on a parent project
will try to use IOConsoleOutputStream.write(String) to report lot of
data (> 160000 characters) to the console, the
IOConsolePartitioner.streamAppended() call will block forever waiting
for queue processed by the (locked) UI thread.
Proposed solution: FileDocumentProvider.refreshFile(IFile) should run
DocumentProviderOperation in providers runnable context to avoid such
deadlocks. In the case the resource tree is locked, a "User Operation is
Waiting" progress dialog will be shown, giving the user a chance to
resolve the deadlock situation by canceling one of the affected tasks.
To be consistent with existing API and to allow clients override the
supplied refresh rule, new API is introduced in FileDocumentProvider:
protected ISchedulingRule.getRefreshRule(Object element). Default
implementation in FileDocumentProvider uses
ResourceRuleFactory.refreshRule for given file.
Change-Id: Id742d98403cc546fad4a21d25eb18ab7bef48776
Signed-off-by: Andrey Loskutov <loskutov@gmx.de>
Diffstat (limited to 'org.eclipse.ui.editors')
-rw-r--r-- | org.eclipse.ui.editors/META-INF/MANIFEST.MF | 2 | ||||
-rw-r--r-- | org.eclipse.ui.editors/pom.xml | 2 | ||||
-rw-r--r-- | org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/FileDocumentProvider.java | 47 |
3 files changed, 43 insertions, 8 deletions
diff --git a/org.eclipse.ui.editors/META-INF/MANIFEST.MF b/org.eclipse.ui.editors/META-INF/MANIFEST.MF index 61e03df97cd..f4776442f56 100644 --- a/org.eclipse.ui.editors/META-INF/MANIFEST.MF +++ b/org.eclipse.ui.editors/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.ui.editors; singleton:=true -Bundle-Version: 3.10.100.qualifier +Bundle-Version: 3.11.0.qualifier Bundle-Activator: org.eclipse.ui.internal.editors.text.EditorsPlugin Bundle-ActivationPolicy: lazy Bundle-Vendor: %providerName diff --git a/org.eclipse.ui.editors/pom.xml b/org.eclipse.ui.editors/pom.xml index 5aa682e00ff..4ff140da338 100644 --- a/org.eclipse.ui.editors/pom.xml +++ b/org.eclipse.ui.editors/pom.xml @@ -18,6 +18,6 @@ </parent> <groupId>org.eclipse.ui</groupId> <artifactId>org.eclipse.ui.editors</artifactId> - <version>3.10.100-SNAPSHOT</version> + <version>3.11.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project> diff --git a/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/FileDocumentProvider.java b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/FileDocumentProvider.java index 7307e6080ae..e875921e5dd 100644 --- a/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/FileDocumentProvider.java +++ b/org.eclipse.ui.editors/src/org/eclipse/ui/editors/text/FileDocumentProvider.java @@ -74,6 +74,7 @@ import org.eclipse.ui.internal.editors.text.WorkspaceOperationRunner; import org.eclipse.ui.part.FileEditorInput; import org.eclipse.ui.texteditor.AbstractMarkerAnnotationModel; +import org.eclipse.ui.texteditor.ISchedulingRuleProvider; import org.eclipse.ui.texteditor.ResourceMarkerAnnotationModel; @@ -945,7 +946,8 @@ public class FileDocumentProvider extends StorageDocumentProvider { } /** - * Refreshes the given file resource. + * Refreshes the given file resource. This method will run the operation in the providers + * runnable context using the monitor supplied by {@link #getProgressMonitor()}. * * @param file the file * @throws CoreException if the refresh fails @@ -956,18 +958,31 @@ public class FileDocumentProvider extends StorageDocumentProvider { } /** - * Refreshes the given file resource. + * Refreshes the given file resource. This method will run the operation in the providers + * runnable context using given monitor. * * @param file the file to be refreshed * @param monitor the progress monitor - * @throws org.eclipse.core.runtime.CoreException if the refresh fails + * @throws org.eclipse.core.runtime.CoreException if the refresh fails * @since 3.0 */ protected void refreshFile(IFile file, IProgressMonitor monitor) throws CoreException { - try { - file.refreshLocal(IResource.DEPTH_INFINITE, monitor); - } catch (OperationCanceledException x) { + class RefreshFileOperation extends DocumentProviderOperation implements ISchedulingRuleProvider { + @Override + protected void execute(IProgressMonitor m) throws CoreException { + try { + file.refreshLocal(IResource.DEPTH_INFINITE, m); + } catch (OperationCanceledException x) { + // ignore + } + } + + @Override + public ISchedulingRule getSchedulingRule() { + return getRefreshRule(file); + } } + executeOperation(new RefreshFileOperation(), monitor); } @Override @@ -1101,6 +1116,26 @@ public class FileDocumentProvider extends StorageDocumentProvider { return null; } + /** + * Returns the scheduling rule required for executing <code>refresh</code> on the given element. + * This implementation uses default refresh rule provided by + * {@link IResourceRuleFactory#refreshRule(IResource)}. + * + * @param element the element + * @return the scheduling rule for <code>refresh</code> + * @since 3.11 + */ + protected ISchedulingRule getRefreshRule(Object element) { + if (element instanceof IResource) { + return fResourceRuleFactory.refreshRule((IResource) element); + } + if (element instanceof IFileEditorInput) { + IFileEditorInput input= (IFileEditorInput) element; + return fResourceRuleFactory.refreshRule(input.getFile()); + } + return null; + } + @Override protected ISchedulingRule getSaveRule(Object element) { if (element instanceof IFileEditorInput) { |