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:
parent
3685773b05
commit
e91ceede17
2 changed files with 28 additions and 41 deletions
|
@ -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,31 +48,31 @@ 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) {
|
||||||
currentTask = (IPDOMIndexerTask)queue.removeFirst();
|
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);
|
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())
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (monitor.isCanceled()) {
|
||||||
|
pdomManager.cancelledByUser();
|
||||||
return Status.CANCEL_STATUS;
|
return Status.CANCEL_STATUS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (manager.finishIndexerJob())
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
fillQueue();
|
|
||||||
}
|
|
||||||
|
|
||||||
String showTimings = Platform.getDebugOption(CCorePlugin.PLUGIN_ID
|
String showTimings = Platform.getDebugOption(CCorePlugin.PLUGIN_ID
|
||||||
+ "/debug/pdomtimings"); //$NON-NLS-1$
|
+ "/debug/pdomtimings"); //$NON-NLS-1$
|
||||||
|
@ -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) {
|
||||||
|
|
|
@ -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()) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue