1515
1616import org .eclipse .core .runtime .Assert ;
1717import org .eclipse .core .runtime .IProgressMonitor ;
18+ import org .eclipse .core .runtime .IStatus ;
1819import org .eclipse .core .runtime .NullProgressMonitor ;
20+ import org .eclipse .core .runtime .Status ;
21+ import org .eclipse .core .runtime .jobs .Job ;
1922
2023import org .eclipse .jface .text .DocumentEvent ;
2124import org .eclipse .jface .text .IDocument ;
@@ -53,7 +56,7 @@ abstract public class AbstractReconciler implements IReconciler {
5356 /**
5457 * Background thread for the reconciling activity.
5558 */
56- class BackgroundThread extends Thread {
59+ class BackgroundThread extends Job {
5760
5861 /** Has the reconciler been canceled. */
5962 private boolean fCanceled = false ;
@@ -64,6 +67,10 @@ class BackgroundThread extends Thread {
6467 /** Is a reconciling strategy active. */
6568 private boolean fIsActive = false ;
6669
70+ private volatile boolean fIsAlive ;
71+
72+ private boolean started ;
73+
6774 /**
6875 * Creates a new background thread. The thread
6976 * runs with minimal priority.
@@ -72,8 +79,8 @@ class BackgroundThread extends Thread {
7279 */
7380 public BackgroundThread (String name ) {
7481 super (name );
75- setPriority (Thread . MIN_PRIORITY );
76- setDaemon (true );
82+ setPriority (Job . DECORATE );
83+ setSystem (true );
7784 }
7885
7986 /**
@@ -98,7 +105,8 @@ public synchronized boolean isDirty() {
98105 /**
99106 * Cancels the background thread.
100107 */
101- public void cancel () {
108+ @ Override
109+ protected void canceling () {
102110 fCanceled = true ;
103111 IProgressMonitor pm = fProgressMonitor ;
104112 if (pm != null )
@@ -153,7 +161,9 @@ public void reset() {
153161 fDirtyRegionQueue .notifyAll ();
154162 }
155163 }
156-
164+ synchronized (this ) {
165+ started = false ;
166+ }
157167 informNotFinished ();
158168 reconcilerReset ();
159169 }
@@ -167,12 +177,12 @@ public void reset() {
167177 * </p>
168178 */
169179 @ Override
170- public void run () {
171-
180+ public IStatus run (IProgressMonitor monitor ) {
181+ fIsAlive = true ;
172182 delay ();
173183
174184 if (fCanceled )
175- return ;
185+ return Status . CANCEL_STATUS ;
176186
177187 initialProcess ();
178188
@@ -217,6 +227,19 @@ public void run() {
217227
218228 fIsActive = false ;
219229 }
230+ fIsAlive = false ;
231+ return Status .OK_STATUS ;
232+ }
233+
234+ public boolean isAlive () {
235+ return fIsAlive ;
236+ }
237+
238+ public synchronized void start () {
239+ if (!started ) {
240+ started = true ;
241+ schedule ();
242+ }
220243 }
221244 }
222245
@@ -233,7 +256,7 @@ public void documentAboutToBeChanged(DocumentEvent e) {
233256 public void documentChanged (DocumentEvent e ) {
234257
235258 if (fThread .isActive () || !fThread .isDirty () && fThread .isAlive ()) {
236- if (!fIsAllowedToModifyDocument && Thread . currentThread () == fThread )
259+ if (!fIsAllowedToModifyDocument && isRunningInReconcilerThread () )
237260 throw new UnsupportedOperationException ("The reconciler thread is not allowed to modify the document" ); //$NON-NLS-1$
238261 aboutToBeReconciledInternal ();
239262 }
@@ -449,7 +472,7 @@ public void install(ITextViewer textViewer) {
449472 synchronized (this ) {
450473 if (fThread != null )
451474 return ;
452- fThread = new BackgroundThread (getClass ().getName ());
475+ fThread = new BackgroundThread (getClass ().getName () + " reconciler thread" ); //$NON-NLS-1$
453476 }
454477
455478 fDirtyRegionQueue = new DirtyRegionQueue ();
@@ -614,14 +637,7 @@ protected synchronized void startReconciling() {
614637 return ;
615638
616639 if (!fThread .isAlive ()) {
617- try {
618- fThread .start ();
619- } catch (IllegalThreadStateException e ) {
620- // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=40549
621- // This is the only instance where the thread is started; since
622- // we checked that it is not alive, it must be dead already due
623- // to a run-time exception or error. Exit.
624- }
640+ fThread .start ();
625641 } else {
626642 fThread .reset ();
627643 }
@@ -640,7 +656,10 @@ protected void reconcilerReset() {
640656 * @return <code>true</code> if running in this reconciler's background thread
641657 * @since 3.4
642658 */
643- protected boolean isRunningInReconcilerThread () {
644- return Thread .currentThread () == fThread ;
659+ protected synchronized boolean isRunningInReconcilerThread () {
660+ if (fThread == null ) {
661+ return false ;
662+ }
663+ return Job .getJobManager ().currentJob () == fThread ;
645664 }
646665}
0 commit comments