1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-04 23:05:47 +02:00

Bug 310007 core.resources can deadlock the CDT project model

This commit is contained in:
James Blackburn 2010-04-23 14:09:48 +00:00
parent c01b11c194
commit 51667854d1
2 changed files with 35 additions and 0 deletions

View file

@ -59,6 +59,7 @@ import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
@ -68,9 +69,11 @@ import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.QualifiedName; import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.ILock; import org.eclipse.core.runtime.jobs.ILock;
import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.core.runtime.jobs.MultiRule; import org.eclipse.core.runtime.jobs.MultiRule;
import org.osgi.framework.Version; import org.osgi.framework.Version;
import org.w3c.dom.Document; import org.w3c.dom.Document;
@ -128,18 +131,48 @@ public class XmlProjectDescriptionStorage extends AbstractCProjectDescriptionSto
private final ICProjectDescription fDes; private final ICProjectDescription fDes;
private final ICStorageElement fElement; private final ICStorageElement fElement;
/*
* See Bug 249951 & Bug 310007
* Notification run with the workspace lock (which clients can't acquire explicitly)
* The result is deadlock if:
* 1) Notification listener does getProjectDescription (workspaceLock -> serializingLock)
* 2) setProjectDescription does IFile write (serializingLock -> workspaceLock)
* This workaround stops the periodic notification job while we're persisting the project description
* which prevents notification (1) from occurring while we do (2)
*/
private class NotifyJobCanceller extends JobChangeAdapter {
@Override
public void aboutToRun(IJobChangeEvent event) {
final Job job = event.getJob();
if ("org.eclipse.core.internal.events.NotificationManager$NotifyJob".equals(job.getClass().getName())) {
job.cancel();
}
}
}
public DesSerializationRunnable(ICProjectDescription des, ICStorageElement el) { public DesSerializationRunnable(ICProjectDescription des, ICStorageElement el) {
fDes = des; fDes = des;
fElement = el; fElement = el;
} }
public void run(IProgressMonitor monitor) throws CoreException { public void run(IProgressMonitor monitor) throws CoreException {
JobChangeAdapter notifyJobCanceller = new NotifyJobCanceller();
try { try {
// See Bug 249951 & Bug 310007
Job.getJobManager().addJobChangeListener(notifyJobCanceller);
// Ensure we can check a null-job into the workspace
// i.e. if notification is currently in progress wait for it to finish...
ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
public void run(IProgressMonitor monitor) throws CoreException {
}
}, null, IWorkspace.AVOID_UPDATE, null);
// end Bug 249951 & Bug 310007
serializingLock.acquire(); serializingLock.acquire();
projectModificaitonStamp = serialize(fDes.getProject(), ICProjectDescriptionStorageType.STORAGE_FILE_NAME, fElement); projectModificaitonStamp = serialize(fDes.getProject(), ICProjectDescriptionStorageType.STORAGE_FILE_NAME, fElement);
((ContributedEnvironment) CCorePlugin.getDefault().getBuildEnvironmentManager().getContributedEnvironment()).serialize(fDes); ((ContributedEnvironment) CCorePlugin.getDefault().getBuildEnvironmentManager().getContributedEnvironment()).serialize(fDes);
} finally { } finally {
serializingLock.release(); serializingLock.release();
Job.getJobManager().removeJobChangeListener(notifyJobCanceller);
} }
} }

View file

@ -315,6 +315,8 @@ final public class CConfigBasedDescriptorManager implements ICDescriptorManager
* @throws CoreException * @throws CoreException
*/ */
private CConfigBasedDescriptor findDescriptor(IProject project, boolean create) throws CoreException { private CConfigBasedDescriptor findDescriptor(IProject project, boolean create) throws CoreException {
if (!project.isAccessible() && !create)
return null;
CConfigBasedDescriptor dr = null; CConfigBasedDescriptor dr = null;
Reference<CConfigBasedDescriptor> ref = fProjectDescriptorMap.get(project); Reference<CConfigBasedDescriptor> ref = fProjectDescriptorMap.get(project);
if (ref != null) if (ref != null)