15
15
16
16
import org .eclipse .core .runtime .Assert ;
17
17
import org .eclipse .core .runtime .IProgressMonitor ;
18
- import org .eclipse .core .runtime .IStatus ;
19
18
import org .eclipse .core .runtime .NullProgressMonitor ;
20
- import org .eclipse .core .runtime .Status ;
21
19
import org .eclipse .core .runtime .jobs .Job ;
22
20
23
21
import org .eclipse .jface .text .DocumentEvent ;
52
50
*/
53
51
abstract public class AbstractReconciler implements IReconciler {
54
52
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
-
250
53
/**
251
54
* Internal document listener and text input listener.
252
55
*/
@@ -323,13 +126,14 @@ public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
323
126
}
324
127
325
128
/** Queue to manage the changes applied to the text viewer. */
326
- private DirtyRegionQueue fDirtyRegionQueue ;
129
+ DirtyRegionQueue fDirtyRegionQueue ;
327
130
/** The background thread. */
328
- private BackgroundThread fThread ;
131
+ private ReconcilerJob fThread ;
329
132
/** Internal document and text input listener. */
330
133
private Listener fListener ;
134
+
331
135
/** The background thread delay. */
332
- private int fDelay = 500 ;
136
+ int fDelay = 500 ;
333
137
/** Signal that the the background thread should not delay. */
334
138
volatile boolean waitFinish ;
335
139
/** Are there incremental reconciling strategies? */
@@ -476,7 +280,7 @@ public void install(ITextViewer textViewer) {
476
280
synchronized (this ) {
477
281
if (fThread != null )
478
282
return ;
479
- fThread = new BackgroundThread (getClass ().getName ());
283
+ fThread = new ReconcilerJob (getClass ().getName (), this );
480
284
}
481
285
482
286
fDirtyRegionQueue = new DirtyRegionQueue ();
@@ -510,7 +314,7 @@ public void uninstall() {
510
314
511
315
synchronized (this ) {
512
316
// http://dev.eclipse.org/bugs/show_bug.cgi?id=19135
513
- BackgroundThread bt = fThread ;
317
+ ReconcilerJob bt = fThread ;
514
318
fThread = null ;
515
319
bt .doCancel ();
516
320
}
@@ -579,7 +383,7 @@ public void signalWaitForFinish() {
579
383
}
580
384
}
581
385
582
- private void informNotFinished () {
386
+ void informNotFinished () {
583
387
waitFinish = false ;
584
388
aboutToWork ();
585
389
}
@@ -590,7 +394,7 @@ private void aboutToBeReconciledInternal() {
590
394
}
591
395
592
396
593
- private void delay () {
397
+ void delay () {
594
398
synchronized (fDirtyRegionQueue ) {
595
399
if (waitFinish ) {
596
400
return ; // do not delay when waiting;
0 commit comments