1515
1616import org .eclipse .core .runtime .Assert ;
1717import org .eclipse .core .runtime .IProgressMonitor ;
18- import org .eclipse .core .runtime .IStatus ;
1918import org .eclipse .core .runtime .NullProgressMonitor ;
20- import org .eclipse .core .runtime .Status ;
2119import org .eclipse .core .runtime .jobs .Job ;
2220
2321import org .eclipse .jface .text .DocumentEvent ;
5250 */
5351abstract public class AbstractReconciler implements IReconciler {
5452
55-
56- /**
57- * Background thread for the reconciling activity.
58- */
59- private class BackgroundThread extends Job {
60-
61- /** Has the reconciler been canceled. */
62- private boolean fCanceled = false ;
63- /** Has the reconciler been reset. */
64- private boolean fReset = false ;
65- /** Some changes need to be processed. */
66- private boolean fIsDirty = false ;
67- /** Is a reconciling strategy active. */
68- private boolean fIsActive = false ;
69-
70- private volatile boolean fIsAlive ;
71-
72- private boolean started ;
73-
74- /**
75- * Creates a new background thread. The thread
76- * runs with minimal priority.
77- *
78- * @param name the thread's name
79- */
80- public BackgroundThread (String name ) {
81- super (name );
82- setPriority (Job .DECORATE );
83- setSystem (true );
84- }
85-
86- /**
87- * Returns whether a reconciling strategy is active right now.
88- *
89- * @return <code>true</code> if a activity is active
90- */
91- public boolean isActive () {
92- return fIsActive ;
93- }
94-
95- /**
96- * Returns whether some changes need to be processed.
97- *
98- * @return <code>true</code> if changes wait to be processed
99- * @since 3.0
100- */
101- public synchronized boolean isDirty () {
102- return fIsDirty ;
103- }
104-
105- /**
106- * Cancels the background thread.
107- */
108- public void doCancel () {
109- fCanceled = true ;
110- IProgressMonitor pm = fProgressMonitor ;
111- if (pm != null )
112- pm .setCanceled (true );
113- synchronized (fDirtyRegionQueue ) {
114- fDirtyRegionQueue .notifyAll ();
115- }
116- }
117-
118- /**
119- * Suspends the caller of this method until this background thread has
120- * emptied the dirty region queue.
121- */
122- public void suspendCallerWhileDirty () {
123- AbstractReconciler .this .signalWaitForFinish ();
124- boolean isDirty ;
125- do {
126- synchronized (fDirtyRegionQueue ) {
127- isDirty = fDirtyRegionQueue .getSize () > 0 ;
128- if (isDirty ) {
129- try {
130- fDirtyRegionQueue .wait ();
131- } catch (InterruptedException x ) {
132- }
133- }
134- }
135- } while (isDirty );
136- }
137-
138- /**
139- * Reset the background thread as the text viewer has been changed,
140- */
141- public void reset () {
142-
143- if (fDelay > 0 ) {
144-
145- synchronized (this ) {
146- fIsDirty = true ;
147- fReset = true ;
148- }
149- synchronized (fDirtyRegionQueue ) {
150- fDirtyRegionQueue .notifyAll (); // wake up wait(fDelay);
151- }
152-
153- } else {
154-
155- synchronized (this ) {
156- fIsDirty = true ;
157- }
158-
159- synchronized (fDirtyRegionQueue ) {
160- fDirtyRegionQueue .notifyAll ();
161- }
162- }
163- synchronized (this ) {
164- started = false ;
165- }
166- informNotFinished ();
167- reconcilerReset ();
168- }
169-
170- /**
171- * The background activity. Waits until there is something in the
172- * queue managing the changes that have been applied to the text viewer.
173- * Removes the first change from the queue and process it.
174- * <p>
175- * Calls {@link AbstractReconciler#initialProcess()} on entrance.
176- * </p>
177- */
178- @ Override
179- public IStatus run (IProgressMonitor monitor ) {
180- fIsAlive = true ;
181- delay ();
182-
183- if (fCanceled )
184- return Status .CANCEL_STATUS ;
185-
186- initialProcess ();
187-
188- while (!fCanceled ) {
189-
190- delay ();
191-
192- if (fCanceled )
193- break ;
194-
195- if (!isDirty ()) {
196- waitFinish = false ; //signalWaitForFinish() was called but nothing todo
197- continue ;
198- }
199-
200- synchronized (this ) {
201- if (fReset ) {
202- fReset = false ;
203- continue ;
204- }
205- }
206-
207- DirtyRegion r = null ;
208- synchronized (fDirtyRegionQueue ) {
209- r = fDirtyRegionQueue .removeNextDirtyRegion ();
210- }
211-
212- fIsActive = true ;
213-
214- fProgressMonitor .setCanceled (false );
215-
216- process (r );
217-
218- synchronized (fDirtyRegionQueue ) {
219- if (0 == fDirtyRegionQueue .getSize ()) {
220- synchronized (this ) {
221- fIsDirty = fProgressMonitor .isCanceled ();
222- }
223- fDirtyRegionQueue .notifyAll ();
224- }
225- }
226-
227- fIsActive = false ;
228- }
229- fIsAlive = false ;
230- return Status .OK_STATUS ;
231- }
232-
233- public boolean isAlive () {
234- return fIsAlive ;
235- }
236-
237- public synchronized void start () {
238- if (!started ) {
239- started = true ;
240- schedule ();
241- }
242- }
243-
244- @ Override
245- public boolean belongsTo (Object family ) {
246- return family == fViewer || AbstractReconciler .class == family ;
247- }
248- }
249-
25053 /**
25154 * Internal document listener and text input listener.
25255 */
@@ -323,13 +126,14 @@ public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
323126 }
324127
325128 /** Queue to manage the changes applied to the text viewer. */
326- private DirtyRegionQueue fDirtyRegionQueue ;
129+ DirtyRegionQueue fDirtyRegionQueue ;
327130 /** The background thread. */
328- private BackgroundThread fThread ;
131+ private ReconcilerJob fThread ;
329132 /** Internal document and text input listener. */
330133 private Listener fListener ;
134+
331135 /** The background thread delay. */
332- private int fDelay = 500 ;
136+ int fDelay = 500 ;
333137 /** Signal that the the background thread should not delay. */
334138 volatile boolean waitFinish ;
335139 /** Are there incremental reconciling strategies? */
@@ -476,7 +280,7 @@ public void install(ITextViewer textViewer) {
476280 synchronized (this ) {
477281 if (fThread != null )
478282 return ;
479- fThread = new BackgroundThread (getClass ().getName ());
283+ fThread = new ReconcilerJob (getClass ().getName (), this );
480284 }
481285
482286 fDirtyRegionQueue = new DirtyRegionQueue ();
@@ -510,7 +314,7 @@ public void uninstall() {
510314
511315 synchronized (this ) {
512316 // http://dev.eclipse.org/bugs/show_bug.cgi?id=19135
513- BackgroundThread bt = fThread ;
317+ ReconcilerJob bt = fThread ;
514318 fThread = null ;
515319 bt .doCancel ();
516320 }
@@ -579,7 +383,7 @@ public void signalWaitForFinish() {
579383 }
580384 }
581385
582- private void informNotFinished () {
386+ void informNotFinished () {
583387 waitFinish = false ;
584388 aboutToWork ();
585389 }
@@ -590,7 +394,7 @@ private void aboutToBeReconciledInternal() {
590394 }
591395
592396
593- private void delay () {
397+ void delay () {
594398 synchronized (fDirtyRegionQueue ) {
595399 if (waitFinish ) {
596400 return ; // do not delay when waiting;
0 commit comments