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 Thread myThread ;
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 )
@@ -167,12 +175,12 @@ public void reset() {
167175 * </p>
168176 */
169177 @ Override
170- public void run () {
171-
178+ public IStatus run (IProgressMonitor monitor ) {
179+ myThread = Thread . currentThread ();
172180 delay ();
173181
174182 if (fCanceled )
175- return ;
183+ return Status . CANCEL_STATUS ;
176184
177185 initialProcess ();
178186
@@ -217,6 +225,19 @@ public void run() {
217225
218226 fIsActive = false ;
219227 }
228+ myThread = null ;
229+ return Status .OK_STATUS ;
230+ }
231+
232+ public boolean isAlive () {
233+ return myThread != null ;
234+ }
235+
236+ public synchronized void start () {
237+ if (!started ) {
238+ started = true ;
239+ schedule ();
240+ }
220241 }
221242 }
222243
@@ -233,7 +254,7 @@ public void documentAboutToBeChanged(DocumentEvent e) {
233254 public void documentChanged (DocumentEvent e ) {
234255
235256 if (fThread .isActive () || !fThread .isDirty () && fThread .isAlive ()) {
236- if (!fIsAllowedToModifyDocument && Thread . currentThread () == fThread )
257+ if (!fIsAllowedToModifyDocument && isRunningInReconcilerThread () )
237258 throw new UnsupportedOperationException ("The reconciler thread is not allowed to modify the document" ); //$NON-NLS-1$
238259 aboutToBeReconciledInternal ();
239260 }
@@ -449,7 +470,7 @@ public void install(ITextViewer textViewer) {
449470 synchronized (this ) {
450471 if (fThread != null )
451472 return ;
452- fThread = new BackgroundThread (getClass ().getName ());
473+ fThread = new BackgroundThread (getClass ().getName () + " reconciler thread" ); //$NON-NLS-1$
453474 }
454475
455476 fDirtyRegionQueue = new DirtyRegionQueue ();
@@ -614,14 +635,7 @@ protected synchronized void startReconciling() {
614635 return ;
615636
616637 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- }
638+ fThread .start ();
625639 } else {
626640 fThread .reset ();
627641 }
@@ -640,7 +654,10 @@ protected void reconcilerReset() {
640654 * @return <code>true</code> if running in this reconciler's background thread
641655 * @since 3.4
642656 */
643- protected boolean isRunningInReconcilerThread () {
644- return Thread .currentThread () == fThread ;
657+ protected synchronized boolean isRunningInReconcilerThread () {
658+ if (fThread == null ) {
659+ return false ;
660+ }
661+ return Thread .currentThread () == fThread .myThread ;
645662 }
646663}
0 commit comments