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:
parent
c01b11c194
commit
51667854d1
2 changed files with 35 additions and 0 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Add table
Reference in a new issue