Project: JDT
Bug 197768 [reconciling] Bug with reconciler that has no progress monitor
Reported: 2007-07-25 06:26:49 | Status: resolved fixed

Build ID: I20070621-1340 Steps To Reproduce: It is hard to reproduce as it deals with multi-threading. But i can reproduce it. It only happens with non incremental reconcilers. In some particular cases (that i will describe), a change made in the document is omitted and the process(r) method is never called. I put here the *simplified* code (mainly removed the synchronized blocks) of the background thread run method (in AbstractReconciler): 1 : while(!canceled) 2 : { 3 : 4 : fDirtyRegionQueue.wait(fDelay); 5 : //... 6 : if (!isDirty()) 7 : continue; 8 : //... 9 : 10: r= fDirtyRegionQueue.removeNextDirtyRegion(); 11: 12: fIsActive= true; 13: process(r); 14: if (0 == fDirtyRegionQueue.getSize()) { 15: fIsDirty== false; 16: } 17: 18: fIsActive= false; 19: 20: }//end of while The important thing to notice is that, if your reconciler is set as non incremental, that no dirty region are added to the dirtyRegionQueue, it is always empty, thus the following test is always true : *0 == fDirtyRegionQueue.getSize()* That means that the dirty field is always set to false after a process() call. Remember that when the document is changed, the dirty field is set to true. Imagine then that just after the *process(r)* method call (line 13), a document event is fired, then dirty is set to true (by the UI thread). *But* as the queue is always empty, dirty is set to false just after(line 15). Then the next time, when the thread will start again, it will not pass the *if (!isDirty())* test (line: 6) and the model will not be reconciled. NB: with incremental reconcilers it works because fDirtyRegionQueue.getSize() >0 . More information: I think the fReset field can be used to fix the problem. In the scenario i describe the fIsDirty field is set to false (although the text has changed) *but* the fReset field is still true! This patch should fix the problem, in v1.34 replace lines 184 to 192 with : synchronized (this) { if (!fIsDirty && !fReset) continue; if (fReset) { fReset = false; continue; } }

Files changed in fix:
org.eclipse.jdt.ui.examples.javafamily/src/org/eclipse/jdt/internal/ui/examples/jspeditor/JspSourceViewerConfiguration.java org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/propertiesfileeditor/PropertiesFileSourceViewerConfiguration.java org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/text/JavaSourceViewerConfiguration.java