mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-08 18:26:01 +02:00
Fix for 154060, dead lock in Deadlock in PDOMIndexerJob.cancelJobs()
This commit is contained in:
parent
3685773b05
commit
e91ceede17
2 changed files with 28 additions and 41 deletions
|
@ -11,9 +11,6 @@
|
|||
*******************************************************************************/
|
||||
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.dom.IPDOMIndexer;
|
||||
import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
|
||||
|
@ -29,18 +26,17 @@ import org.eclipse.core.runtime.jobs.Job;
|
|||
*/
|
||||
public class PDOMIndexerJob extends Job {
|
||||
|
||||
private final PDOMManager manager;
|
||||
private final PDOMManager pdomManager;
|
||||
|
||||
private LinkedList queue = new LinkedList();
|
||||
private IPDOMIndexerTask currentTask;
|
||||
private boolean isCancelling = false;
|
||||
private boolean cancelledByManager= false;
|
||||
private Object taskMutex = new Object();
|
||||
|
||||
private IProgressMonitor monitor;
|
||||
|
||||
public PDOMIndexerJob(PDOMManager manager) {
|
||||
super(CCorePlugin.getResourceString("pdom.indexer.name")); //$NON-NLS-1$
|
||||
this.manager = manager;
|
||||
this.pdomManager = manager;
|
||||
setPriority(Job.LONG);
|
||||
}
|
||||
|
||||
|
@ -52,30 +48,30 @@ public class PDOMIndexerJob extends Job {
|
|||
String taskName = CCorePlugin.getResourceString("pdom.indexer.task"); //$NON-NLS-1$
|
||||
monitor.beginTask(taskName, IProgressMonitor.UNKNOWN);
|
||||
|
||||
fillQueue();
|
||||
while (true) {
|
||||
while (!queue.isEmpty()) {
|
||||
synchronized (taskMutex) {
|
||||
currentTask = (IPDOMIndexerTask)queue.removeFirst();
|
||||
while (!pdomManager.finishIndexerJob()) {
|
||||
IPDOMIndexerTask nextTask= pdomManager.getNextTask();
|
||||
synchronized (taskMutex) {
|
||||
if (!cancelledByManager) {
|
||||
currentTask= nextTask; // write to currentTask needs protection
|
||||
}
|
||||
}
|
||||
if (currentTask != null) { // read on currentTask is ok (no write in other thread)
|
||||
currentTask.run(monitor);
|
||||
synchronized (taskMutex) {
|
||||
// mschorn: currentTask must be set to null, otherwise cancelJobs() waits forever.
|
||||
currentTask= null;
|
||||
if (isCancelling) {
|
||||
currentTask= null; // write to currentTask needs protection
|
||||
if (cancelledByManager) {
|
||||
// TODO chance for confusion here is user cancels
|
||||
// while project is getting deletes.
|
||||
monitor.setCanceled(false);
|
||||
isCancelling = false;
|
||||
cancelledByManager = false;
|
||||
taskMutex.notify();
|
||||
} else if (monitor.isCanceled())
|
||||
return Status.CANCEL_STATUS;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (manager.finishIndexerJob())
|
||||
break;
|
||||
else
|
||||
fillQueue();
|
||||
if (monitor.isCanceled()) {
|
||||
pdomManager.cancelledByUser();
|
||||
return Status.CANCEL_STATUS;
|
||||
}
|
||||
}
|
||||
|
||||
String showTimings = Platform.getDebugOption(CCorePlugin.PLUGIN_ID
|
||||
|
@ -85,27 +81,12 @@ public class PDOMIndexerJob extends Job {
|
|||
|
||||
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) {
|
||||
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)) {
|
||||
monitor.setCanceled(true);
|
||||
isCancelling = true;
|
||||
cancelledByManager = true;
|
||||
try {
|
||||
taskMutex.wait();
|
||||
} catch (InterruptedException e) {
|
||||
|
|
|
@ -66,8 +66,8 @@ public class PDOMManager implements IPDOMManager, IElementChangedListener {
|
|||
if (pdom == null) {
|
||||
String dbName = rproject.getPersistentProperty(dbNameProperty);
|
||||
if (dbName == null) {
|
||||
dbName = project.getElementName() + "."
|
||||
+ System.currentTimeMillis() + ".pdom";
|
||||
dbName = project.getElementName() + "." //$NON-NLS-1$
|
||||
+ System.currentTimeMillis() + ".pdom"; //$NON-NLS-1$
|
||||
rproject.setPersistentProperty(dbNameProperty, 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() {
|
||||
synchronized (indexerJobMutex) {
|
||||
if (indexerJobQueue.isEmpty()) {
|
||||
|
|
Loading…
Add table
Reference in a new issue