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:
parent
d54cf4d243
commit
fe98dbbe57
1 changed files with 105 additions and 67 deletions
|
@ -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,70 +300,90 @@ 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;
|
} catch (CoreException e) {
|
||||||
}
|
CCorePlugin.log(e);
|
||||||
}
|
return null;
|
||||||
if (indexer == null && create) {
|
}
|
||||||
indexer = createIndexer(project, getIndexerId(project), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (indexer != null && indexer.getProject().equals(project)) {
|
||||||
return indexer;
|
return indexer;
|
||||||
}
|
}
|
||||||
} catch (CoreException e) {
|
|
||||||
CCorePlugin.log(e);
|
if (create) {
|
||||||
|
try {
|
||||||
|
return createIndexer(project, getIndexerId(project), false);
|
||||||
|
} catch (CoreException e) {
|
||||||
|
CCorePlugin.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IPDOMIndexer createIndexer(ICProject project, String indexerId, boolean forceReindex) throws CoreException {
|
private IPDOMIndexer createIndexer(ICProject project, String indexerId, boolean forceReindex) throws CoreException {
|
||||||
PDOM pdom= (PDOM) getPDOM(project);
|
assert Thread.holdsLock(fIndexerMutex);
|
||||||
boolean reindex= forceReindex || pdom.versionMismatch() || pdom.isEmpty();
|
|
||||||
synchronized (fIndexerMutex) {
|
PDOM pdom= (PDOM) getPDOM(project);
|
||||||
IPDOMIndexer indexer = null;
|
boolean reindex= forceReindex || pdom.versionMismatch() || pdom.isEmpty();
|
||||||
// Look up in extension point
|
|
||||||
IExtension indexerExt = Platform.getExtensionRegistry().getExtension(CCorePlugin.INDEXER_UNIQ_ID, indexerId);
|
IPDOMIndexer indexer = null;
|
||||||
if (indexerExt != null) {
|
// Look up in extension point
|
||||||
IConfigurationElement[] elements = indexerExt.getConfigurationElements();
|
IExtension indexerExt = Platform.getExtensionRegistry().getExtension(CCorePlugin.INDEXER_UNIQ_ID, indexerId);
|
||||||
for (int i = 0; i < elements.length; ++i) {
|
if (indexerExt != null) {
|
||||||
IConfigurationElement element = elements[i];
|
IConfigurationElement[] elements = indexerExt.getConfigurationElements();
|
||||||
if ("run".equals(element.getName())) { //$NON-NLS-1$
|
for (int i = 0; i < elements.length; ++i) {
|
||||||
indexer = (IPDOMIndexer)element.createExecutableExtension("class"); //$NON-NLS-1$
|
IConfigurationElement element = elements[i];
|
||||||
break;
|
if ("run".equals(element.getName())) { //$NON-NLS-1$
|
||||||
}
|
try {
|
||||||
|
indexer = (IPDOMIndexer)element.createExecutableExtension("class"); //$NON-NLS-1$
|
||||||
|
} catch (CoreException e) {
|
||||||
|
CCorePlugin.log(e);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (indexer == null)
|
|
||||||
// Unknown index, default to the null one
|
|
||||||
indexer = new PDOMNullIndexer();
|
|
||||||
|
|
||||||
indexer.setProject(project);
|
|
||||||
project.getProject().setSessionProperty(indexerProperty, indexer);
|
|
||||||
registerPreferenceListener(project);
|
|
||||||
|
|
||||||
if (reindex) {
|
|
||||||
indexer.reindex();
|
|
||||||
}
|
|
||||||
return indexer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unknown index, default to the null one
|
||||||
|
if (indexer == null)
|
||||||
|
indexer = new PDOMNullIndexer();
|
||||||
|
|
||||||
|
indexer.setProject(project);
|
||||||
|
registerPreferenceListener(project);
|
||||||
|
project.getProject().setSessionProperty(indexerProperty, indexer);
|
||||||
|
|
||||||
|
if (reindex) {
|
||||||
|
indexer.reindex();
|
||||||
|
}
|
||||||
|
return indexer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void enqueue(IPDOMIndexerTask subjob) {
|
public void enqueue(IPDOMIndexerTask subjob) {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue