From e91ceede176e66b36e5c3ab218114ab7429bb08a Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Mon, 2 Oct 2006 14:42:13 +0000 Subject: [PATCH] Fix for 154060, dead lock in Deadlock in PDOMIndexerJob.cancelJobs() --- .../internal/core/pdom/PDOMIndexerJob.java | 59 +++++++------------ .../cdt/internal/core/pdom/PDOMManager.java | 10 +++- 2 files changed, 28 insertions(+), 41 deletions(-) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMIndexerJob.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMIndexerJob.java index f733be11283..72cbbef716d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMIndexerJob.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMIndexerJob.java @@ -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) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java index 5273ca41a38..4ebb4db17eb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java @@ -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()) {