1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-09 10:46:02 +02:00

Fix for 154060, dead lock in Deadlock in PDOMIndexerJob.cancelJobs()

This commit is contained in:
Markus Schorn 2006-10-02 14:42:13 +00:00
parent 3685773b05
commit e91ceede17
2 changed files with 28 additions and 41 deletions

View file

@ -11,9 +11,6 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.pdom; package org.eclipse.cdt.internal.core.pdom;
import java.util.Iterator;
import java.util.LinkedList;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMIndexer; import org.eclipse.cdt.core.dom.IPDOMIndexer;
import org.eclipse.cdt.core.dom.IPDOMIndexerTask; import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
@ -29,18 +26,17 @@ import org.eclipse.core.runtime.jobs.Job;
*/ */
public class PDOMIndexerJob extends Job { public class PDOMIndexerJob extends Job {
private final PDOMManager manager; private final PDOMManager pdomManager;
private LinkedList queue = new LinkedList();
private IPDOMIndexerTask currentTask; private IPDOMIndexerTask currentTask;
private boolean isCancelling = false; private boolean cancelledByManager= false;
private Object taskMutex = new Object(); private Object taskMutex = new Object();
private IProgressMonitor monitor; private IProgressMonitor monitor;
public PDOMIndexerJob(PDOMManager manager) { public PDOMIndexerJob(PDOMManager manager) {
super(CCorePlugin.getResourceString("pdom.indexer.name")); //$NON-NLS-1$ super(CCorePlugin.getResourceString("pdom.indexer.name")); //$NON-NLS-1$
this.manager = manager; this.pdomManager = manager;
setPriority(Job.LONG); setPriority(Job.LONG);
} }
@ -52,30 +48,30 @@ public class PDOMIndexerJob extends Job {
String taskName = CCorePlugin.getResourceString("pdom.indexer.task"); //$NON-NLS-1$ String taskName = CCorePlugin.getResourceString("pdom.indexer.task"); //$NON-NLS-1$
monitor.beginTask(taskName, IProgressMonitor.UNKNOWN); monitor.beginTask(taskName, IProgressMonitor.UNKNOWN);
fillQueue(); while (!pdomManager.finishIndexerJob()) {
while (true) { IPDOMIndexerTask nextTask= pdomManager.getNextTask();
while (!queue.isEmpty()) { synchronized (taskMutex) {
synchronized (taskMutex) { if (!cancelledByManager) {
currentTask = (IPDOMIndexerTask)queue.removeFirst(); currentTask= nextTask; // write to currentTask needs protection
} }
}
if (currentTask != null) { // read on currentTask is ok (no write in other thread)
currentTask.run(monitor); currentTask.run(monitor);
synchronized (taskMutex) { synchronized (taskMutex) {
// mschorn: currentTask must be set to null, otherwise cancelJobs() waits forever. currentTask= null; // write to currentTask needs protection
currentTask= null; if (cancelledByManager) {
if (isCancelling) {
// TODO chance for confusion here is user cancels // TODO chance for confusion here is user cancels
// while project is getting deletes. // while project is getting deletes.
monitor.setCanceled(false); monitor.setCanceled(false);
isCancelling = false; cancelledByManager = false;
taskMutex.notify(); taskMutex.notify();
} else if (monitor.isCanceled()) }
return Status.CANCEL_STATUS;
} }
} }
if (manager.finishIndexerJob()) if (monitor.isCanceled()) {
break; pdomManager.cancelledByUser();
else return Status.CANCEL_STATUS;
fillQueue(); }
} }
String showTimings = Platform.getDebugOption(CCorePlugin.PLUGIN_ID String showTimings = Platform.getDebugOption(CCorePlugin.PLUGIN_ID
@ -86,26 +82,11 @@ public class PDOMIndexerJob extends Job {
return Status.OK_STATUS; return Status.OK_STATUS;
} }
private void fillQueue() {
synchronized (taskMutex) {
IPDOMIndexerTask task = manager.getNextTask();
while (task != null) {
queue.addLast(task);
task = manager.getNextTask();
}
}
}
public void cancelJobs(IPDOMIndexer indexer) { public void cancelJobs(IPDOMIndexer indexer) {
synchronized (taskMutex) { synchronized (taskMutex) {
for (Iterator i = queue.iterator(); i.hasNext();) {
IPDOMIndexerTask task = (IPDOMIndexerTask)i.next();
if (task.getIndexer().equals(indexer))
i.remove();
}
if (currentTask != null && currentTask.getIndexer().equals(indexer)) { if (currentTask != null && currentTask.getIndexer().equals(indexer)) {
monitor.setCanceled(true); monitor.setCanceled(true);
isCancelling = true; cancelledByManager = true;
try { try {
taskMutex.wait(); taskMutex.wait();
} catch (InterruptedException e) { } catch (InterruptedException e) {

View file

@ -66,8 +66,8 @@ public class PDOMManager implements IPDOMManager, IElementChangedListener {
if (pdom == null) { if (pdom == null) {
String dbName = rproject.getPersistentProperty(dbNameProperty); String dbName = rproject.getPersistentProperty(dbNameProperty);
if (dbName == null) { if (dbName == null) {
dbName = project.getElementName() + "." dbName = project.getElementName() + "." //$NON-NLS-1$
+ System.currentTimeMillis() + ".pdom"; + System.currentTimeMillis() + ".pdom"; //$NON-NLS-1$
rproject.setPersistentProperty(dbNameProperty, dbName); rproject.setPersistentProperty(dbNameProperty, dbName);
} }
IPath dbPath = CCorePlugin.getDefault().getStateLocation().append(dbName); IPath dbPath = CCorePlugin.getDefault().getStateLocation().append(dbName);
@ -292,6 +292,12 @@ public class PDOMManager implements IPDOMManager, IElementChangedListener {
} }
} }
void cancelledByUser() {
synchronized (indexerJobMutex) {
indexerJobQueue.clear();
}
}
boolean finishIndexerJob() { boolean finishIndexerJob() {
synchronized (indexerJobMutex) { synchronized (indexerJobMutex) {
if (indexerJobQueue.isEmpty()) { if (indexerJobQueue.isEmpty()) {