1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Simplified and doucmented synchronization in PDOMManager

This commit is contained in:
Markus Schorn 2006-10-20 12:21:28 +00:00
parent d54cf4d243
commit fe98dbbe57

View file

@ -87,12 +87,17 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
} }
}; };
/**
* Protects indexerJob, currentTask and taskQueue.
*/
private Object taskQueueMutex = new Object();
private PDOMIndexerJob indexerJob; private PDOMIndexerJob indexerJob;
private IPDOMIndexerTask currentTask; private IPDOMIndexerTask currentTask;
private LinkedList taskQueue = new LinkedList(); private LinkedList taskQueue = new LinkedList();
private Object taskQueueMutex = new Object();
private Object fWakeupOnIdle= new Object();
/**
* Stores mapping from pdom to project, used to serialize\ creation of new pdoms.
*/
private Map fPDOMs= new HashMap(); private Map fPDOMs= new HashMap();
private ListenerList fChangeListeners= new ListenerList(); private ListenerList fChangeListeners= new ListenerList();
private ListenerList fStateListeners= new ListenerList(); private ListenerList fStateListeners= new ListenerList();
@ -100,10 +105,13 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
private IndexChangeEvent fIndexChangeEvent= new IndexChangeEvent(); private IndexChangeEvent fIndexChangeEvent= new IndexChangeEvent();
private IndexerStateEvent fIndexerStateEvent= new IndexerStateEvent(); private IndexerStateEvent fIndexerStateEvent= new IndexerStateEvent();
// classes that help out to make this one simpler
private IElementChangedListener fCModelListener= new CModelListener(this); private IElementChangedListener fCModelListener= new CModelListener(this);
private IndexFactory fIndexFactory= new IndexFactory(this); private IndexFactory fIndexFactory= new IndexFactory(this);
/**
* Serializes creation of new indexer, when acquiring the lock you are
* not allowed to hold a lock on fPDOMs.
*/
private Object fIndexerMutex= new Object(); private Object fIndexerMutex= new Object();
private IPreferenceChangeListener fPreferenceChangeListener= new IPreferenceChangeListener(){ private IPreferenceChangeListener fPreferenceChangeListener= new IPreferenceChangeListener(){
public void preferenceChange(PreferenceChangeEvent event) { public void preferenceChange(PreferenceChangeEvent event) {
@ -200,7 +208,7 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
} }
} }
public String getIndexerId(ICProject project) throws CoreException { public String getIndexerId(ICProject project) {
IEclipsePreferences prefs = new ProjectScope(project.getProject()).getNode(CCorePlugin.PLUGIN_ID); IEclipsePreferences prefs = new ProjectScope(project.getProject()).getNode(CCorePlugin.PLUGIN_ID);
if (prefs == null) if (prefs == null)
return getDefaultIndexerId(); return getDefaultIndexerId();
@ -240,7 +248,7 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
return indexerId; return indexerId;
} }
public void setIndexerId(final ICProject project, String indexerId) throws CoreException { public void setIndexerId(final ICProject project, String indexerId) {
IEclipsePreferences prefs = new ProjectScope(project.getProject()).getNode(CCorePlugin.PLUGIN_ID); IEclipsePreferences prefs = new ProjectScope(project.getProject()).getNode(CCorePlugin.PLUGIN_ID);
if (prefs == null) if (prefs == null)
return; // TODO why would this be null? return; // TODO why would this be null?
@ -277,9 +285,8 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
ICProject cproject= CoreModel.getDefault().create(project); ICProject cproject= CoreModel.getDefault().create(project);
if (cproject != null) { if (cproject != null) {
try { try {
String oldId= (String) event.getOldValue();
String newId= (String) event.getNewValue(); String newId= (String) event.getNewValue();
if (newId != null && !newId.equals(oldId)) { if (newId != null) {
changeIndexer(cproject, newId); changeIndexer(cproject, newId);
} }
} }
@ -293,44 +300,60 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
} }
private void changeIndexer(ICProject cproject, String newid) throws CoreException { private void changeIndexer(ICProject cproject, String newid) throws CoreException {
IPDOMIndexer indexer= getIndexer(cproject, false); assert !Thread.holdsLock(fPDOMs);
if (indexer != null) { IPDOMIndexer oldIndexer= null;
stopIndexer(indexer); synchronized (fIndexerMutex) {
oldIndexer= getIndexer(cproject, false);
if (oldIndexer != null) {
if (oldIndexer.getID().equals(newid)) {
return;
}
}
createIndexer(cproject, newid, true);
}
if (oldIndexer != null) {
stopIndexer(oldIndexer);
} }
indexer= createIndexer(cproject, newid, true);
} }
public IPDOMIndexer getIndexer(ICProject project, boolean create) { public IPDOMIndexer getIndexer(ICProject project, boolean create) {
try { assert !Thread.holdsLock(fPDOMs);
synchronized (fIndexerMutex) { synchronized (fIndexerMutex) {
IProject rproject = project.getProject(); IProject rproject = project.getProject();
if (!rproject.isOpen()) { if (!rproject.isOpen()) {
return null; return null;
} }
IPDOMIndexer indexer = (IPDOMIndexer)rproject.getSessionProperty(indexerProperty);
if (indexer != null) { IPDOMIndexer indexer;
ICProject indexerProject= indexer.getProject(); try {
if (!project.equals(indexerProject)) { indexer = (IPDOMIndexer)rproject.getSessionProperty(indexerProperty);
indexer= null;
}
}
if (indexer == null && create) {
indexer = createIndexer(project, getIndexerId(project), false);
}
return indexer;
}
} catch (CoreException e) { } catch (CoreException e) {
CCorePlugin.log(e); CCorePlugin.log(e);
return null; return null;
} }
if (indexer != null && indexer.getProject().equals(project)) {
return indexer;
}
if (create) {
try {
return createIndexer(project, getIndexerId(project), false);
} catch (CoreException e) {
CCorePlugin.log(e);
}
}
return null;
}
} }
private IPDOMIndexer createIndexer(ICProject project, String indexerId, boolean forceReindex) throws CoreException { private IPDOMIndexer createIndexer(ICProject project, String indexerId, boolean forceReindex) throws CoreException {
assert Thread.holdsLock(fIndexerMutex);
PDOM pdom= (PDOM) getPDOM(project); PDOM pdom= (PDOM) getPDOM(project);
boolean reindex= forceReindex || pdom.versionMismatch() || pdom.isEmpty(); boolean reindex= forceReindex || pdom.versionMismatch() || pdom.isEmpty();
synchronized (fIndexerMutex) {
IPDOMIndexer indexer = null; IPDOMIndexer indexer = null;
// Look up in extension point // Look up in extension point
IExtension indexerExt = Platform.getExtensionRegistry().getExtension(CCorePlugin.INDEXER_UNIQ_ID, indexerId); IExtension indexerExt = Platform.getExtensionRegistry().getExtension(CCorePlugin.INDEXER_UNIQ_ID, indexerId);
@ -339,25 +362,29 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
for (int i = 0; i < elements.length; ++i) { for (int i = 0; i < elements.length; ++i) {
IConfigurationElement element = elements[i]; IConfigurationElement element = elements[i];
if ("run".equals(element.getName())) { //$NON-NLS-1$ if ("run".equals(element.getName())) { //$NON-NLS-1$
try {
indexer = (IPDOMIndexer)element.createExecutableExtension("class"); //$NON-NLS-1$ indexer = (IPDOMIndexer)element.createExecutableExtension("class"); //$NON-NLS-1$
} catch (CoreException e) {
CCorePlugin.log(e);
}
break; break;
} }
} }
} }
if (indexer == null)
// Unknown index, default to the null one // Unknown index, default to the null one
if (indexer == null)
indexer = new PDOMNullIndexer(); indexer = new PDOMNullIndexer();
indexer.setProject(project); indexer.setProject(project);
project.getProject().setSessionProperty(indexerProperty, indexer);
registerPreferenceListener(project); registerPreferenceListener(project);
project.getProject().setSessionProperty(indexerProperty, indexer);
if (reindex) { if (reindex) {
indexer.reindex(); indexer.reindex();
} }
return indexer; return indexer;
} }
}
public void enqueue(IPDOMIndexerTask subjob) { public void enqueue(IPDOMIndexerTask subjob) {
boolean notifyBusy= false; boolean notifyBusy= false;
@ -467,6 +494,19 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
private void stopIndexer(IPDOMIndexer indexer) { private void stopIndexer(IPDOMIndexer indexer) {
ICProject project= indexer.getProject(); ICProject project= indexer.getProject();
synchronized (fIndexerMutex) {
IProject rp= project.getProject();
if (rp.isOpen()) {
try {
if (rp.getSessionProperty(indexerProperty) == indexer) {
rp.setSessionProperty(indexerProperty, null);
}
}
catch (CoreException e) {
CCorePlugin.log(e);
}
}
}
unregisterPreferenceListener(project); unregisterPreferenceListener(project);
synchronized (taskQueueMutex) { synchronized (taskQueueMutex) {
if (indexerJob != null) { if (indexerJob != null) {
@ -493,9 +533,8 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
private void notifyState(final int state) { private void notifyState(final int state) {
if (state == IndexerStateEvent.STATE_IDLE) { if (state == IndexerStateEvent.STATE_IDLE) {
assert !Thread.holdsLock(taskQueueMutex); synchronized(taskQueueMutex) {
synchronized(fWakeupOnIdle) { taskQueueMutex.notifyAll();
fWakeupOnIdle.notifyAll();
} }
} }
@ -573,31 +612,30 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
if (monitor.isCanceled()) { if (monitor.isCanceled()) {
return false; return false;
} }
boolean wouldFail= false; boolean hasTimedOut= false;
int wait= 1000; int wait= 1000;
if (waitMaxMillis >= 0) { if (waitMaxMillis >= 0) {
int rest= (int) (limit - System.currentTimeMillis()); int rest= (int) (limit - System.currentTimeMillis());
if (rest < wait) { if (rest < wait) {
if (rest <= 0) { if (rest <= 0) {
wouldFail= true; hasTimedOut= true;
} }
wait= rest; wait= rest;
} }
} }
assert !Thread.holdsLock(taskQueueMutex); synchronized(taskQueueMutex) {
synchronized(fWakeupOnIdle) {
if (isIndexerIdle()) { if (isIndexerIdle()) {
return true; return true;
} }
if (wouldFail) { if (hasTimedOut) {
return false; return false;
} }
monitor.subTask(MessageFormat.format(Messages.PDOMManager_FilesToIndexSubtask, new Object[] {new Integer(getFilesToIndexCount())})); monitor.subTask(MessageFormat.format(Messages.PDOMManager_FilesToIndexSubtask, new Object[] {new Integer(getFilesToIndexCount())}));
try { try {
fWakeupOnIdle.wait(wait); taskQueueMutex.wait(wait);
} catch (InterruptedException e) { } catch (InterruptedException e) {
return false; return false;
} }