1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 14:42:11 +02:00

Bug 276688 Deadlock in MakeContentProvider

- Display#syncExec(...) while the workspace lock is held => changed to #asyncExec(...)
 - Generics
This commit is contained in:
James Blackburn 2009-05-18 19:24:24 +00:00
parent b25aa7413b
commit ee9b1aa905

View file

@ -27,11 +27,13 @@ import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.viewers.AbstractTreeViewer; import org.eclipse.jface.viewers.AbstractTreeViewer;
import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.StructuredViewer; import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
public class MakeContentProvider implements ITreeContentProvider, IMakeTargetListener, IResourceChangeListener { public class MakeContentProvider implements ITreeContentProvider, IMakeTargetListener, IResourceChangeListener {
protected boolean bFlatten; protected boolean bFlatten;
@ -57,7 +59,7 @@ public class MakeContentProvider implements ITreeContentProvider, IMakeTargetLis
// ignore // ignore
} }
} else if (obj instanceof IContainer) { } else if (obj instanceof IContainer) {
ArrayList children = new ArrayList(); ArrayList<IAdaptable> children = new ArrayList<IAdaptable>();
try { try {
IResource[] resource = ((IContainer)obj).members(); IResource[] resource = ((IContainer)obj).members();
for (int i = 0; i < resource.length; i++) { for (int i = 0; i < resource.length; i++) {
@ -89,7 +91,7 @@ public class MakeContentProvider implements ITreeContentProvider, IMakeTargetLis
public Object[] getElements(Object obj) { public Object[] getElements(Object obj) {
if (bFlatten) { if (bFlatten) {
List list = new ArrayList(); List<Object> list = new ArrayList<Object>();
Object[] children = getChildren(obj); Object[] children = getChildren(obj);
for (int i = 0; i < children.length; i++) { for (int i = 0; i < children.length; i++) {
list.add(children[i]); list.add(children[i]);
@ -139,7 +141,7 @@ public class MakeContentProvider implements ITreeContentProvider, IMakeTargetLis
switch (event.getType()) { switch (event.getType()) {
case MakeTargetEvent.PROJECT_ADDED : case MakeTargetEvent.PROJECT_ADDED :
case MakeTargetEvent.PROJECT_REMOVED : case MakeTargetEvent.PROJECT_REMOVED :
ctrl.getDisplay().syncExec(new Runnable() { ctrl.getDisplay().asyncExec(new Runnable() {
public void run() { public void run() {
if (ctrl != null && !ctrl.isDisposed()) { if (ctrl != null && !ctrl.isDisposed()) {
@ -151,7 +153,7 @@ public class MakeContentProvider implements ITreeContentProvider, IMakeTargetLis
case MakeTargetEvent.TARGET_ADD : case MakeTargetEvent.TARGET_ADD :
case MakeTargetEvent.TARGET_CHANGED : case MakeTargetEvent.TARGET_CHANGED :
case MakeTargetEvent.TARGET_REMOVED : case MakeTargetEvent.TARGET_REMOVED :
ctrl.getDisplay().syncExec(new Runnable() { ctrl.getDisplay().asyncExec(new Runnable() {
public void run() { public void run() {
if (ctrl != null && !ctrl.isDisposed()) { if (ctrl != null && !ctrl.isDisposed()) {
@ -199,57 +201,61 @@ public class MakeContentProvider implements ITreeContentProvider, IMakeTargetLis
} }
// Get the affected resource // Get the affected resource
IResource resource = delta.getResource(); final IResource resource = delta.getResource();
// Handle removed children. Issue one update for all removals. // Handle removed children. Issue one update for all removals.
affectedChildren = delta.getAffectedChildren(IResourceDelta.REMOVED); affectedChildren = delta.getAffectedChildren(IResourceDelta.REMOVED);
if (affectedChildren.length > 0) { if (affectedChildren.length > 0) {
ArrayList affected = new ArrayList(affectedChildren.length); final ArrayList<IResource> affected = new ArrayList<IResource>(affectedChildren.length);
for (int i = 0; i < affectedChildren.length; i++) { for (int i = 0; i < affectedChildren.length; i++) {
if (affectedChildren[i].getResource().getType() == IResource.FOLDER) { if (affectedChildren[i].getResource().getType() == IResource.FOLDER) {
affected.add(affectedChildren[i].getResource()); affected.add(affectedChildren[i].getResource());
} }
} }
if (affected.size() != 0) { if (!affected.isEmpty()) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
if (viewer == null || viewer.getControl() == null || viewer.getControl().isDisposed())
return;
if (viewer instanceof AbstractTreeViewer) { if (viewer instanceof AbstractTreeViewer) {
((AbstractTreeViewer) viewer).remove(affected.toArray()); ((AbstractTreeViewer) viewer).remove(affected.toArray());
} else { } else {
viewer.refresh(resource); viewer.refresh(resource);
} }
} }
});
}
} }
// Handle added children. Issue one update for all insertions. // Handle added children. Issue one update for all insertions.
affectedChildren = delta.getAffectedChildren(IResourceDelta.ADDED); affectedChildren = delta.getAffectedChildren(IResourceDelta.ADDED);
if (affectedChildren.length > 0) { if (affectedChildren.length > 0) {
ArrayList affected = new ArrayList(affectedChildren.length); final ArrayList<IResource> affected = new ArrayList<IResource>(affectedChildren.length);
for (int i = 0; i < affectedChildren.length; i++) { for (int i = 0; i < affectedChildren.length; i++) {
if (affectedChildren[i].getResource().getType() == IResource.FOLDER) { if (affectedChildren[i].getResource().getType() == IResource.FOLDER) {
affected.add(affectedChildren[i].getResource()); affected.add(affectedChildren[i].getResource());
} }
} }
if (affected.size() != 0) { if (!affected.isEmpty()) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
if (viewer == null || viewer.getControl() == null || viewer.getControl().isDisposed())
return;
if (viewer instanceof AbstractTreeViewer) { if (viewer instanceof AbstractTreeViewer) {
((AbstractTreeViewer) viewer).add(resource, affected.toArray()); ((AbstractTreeViewer) viewer).add(resource, affected.toArray());
} else { } else {
viewer.refresh(resource); viewer.refresh(resource);
} }
} }
});
}
} }
} }
public void resourceChanged(IResourceChangeEvent event) { public void resourceChanged(IResourceChangeEvent event) {
final IResourceDelta delta = event.getDelta(); final IResourceDelta delta = event.getDelta();
Control ctrl = viewer.getControl(); Control ctrl = viewer.getControl();
if (ctrl != null && !ctrl.isDisposed()) { if (ctrl != null && !ctrl.isDisposed())
// Do a sync exec, not an async exec, since the resource delta
// must be traversed in this method. It is destroyed
// when this method returns.
ctrl.getDisplay().syncExec(new Runnable() {
public void run() {
processDelta(delta); processDelta(delta);
} }
});
}
}
} }