@@ -98,10 +98,13 @@ public void propertyChange(PropertyChangeEvent e) {
98
98
* This method is used to interrupt file loading thread.
99
99
*/
100
100
public void invalidateFileCache () {
101
- if (filesLoader != null ) {
102
- filesLoader .loadThread .interrupt ();
103
- filesLoader .cancelRunnables ();
104
- filesLoader = null ;
101
+ synchronized (this ) {
102
+ if (filesLoader != null ) {
103
+ filesLoader .loadThread .interrupt ();
104
+ filesLoader = null ;
105
+ // Increment fetch ID to invalidate pending DoChangeContents
106
+ fetchID .incrementAndGet ();
107
+ }
105
108
}
106
109
}
107
110
@@ -156,14 +159,15 @@ public void validateFileCache() {
156
159
if (currentDirectory == null ) {
157
160
return ;
158
161
}
159
- if ( filesLoader != null ) {
160
- filesLoader . loadThread . interrupt ();
161
- filesLoader .cancelRunnables ();
162
- }
162
+ synchronized ( this ) {
163
+ if ( filesLoader != null ) {
164
+ filesLoader .loadThread . interrupt ();
165
+ }
163
166
164
- int fid = fetchID .incrementAndGet ();
165
- setBusy (true , fid );
166
- filesLoader = new FilesLoader (currentDirectory , fid );
167
+ int fid = fetchID .incrementAndGet ();
168
+ setBusy (true , fid );
169
+ filesLoader = new FilesLoader (currentDirectory , fid );
170
+ }
167
171
}
168
172
169
173
/**
@@ -276,7 +280,6 @@ private final class FilesLoader implements Runnable {
276
280
private final boolean fileSelectionEnabled ;
277
281
private final int fid ;
278
282
private final File currentDirectory ;
279
- private volatile DoChangeContents runnable ;
280
283
private final Thread loadThread ;
281
284
282
285
private FilesLoader (File currentDirectory , int fid ) {
@@ -297,22 +300,20 @@ public void run() {
297
300
}
298
301
299
302
private void run0 () {
300
- FileSystemView fileSystem = fileSystemView ;
301
-
302
303
if (loadThread .isInterrupted ()) {
303
304
return ;
304
305
}
305
306
306
- File [] list = fileSystem .getFiles (currentDirectory , useFileHiding );
307
+ File [] list = fileSystemView .getFiles (currentDirectory , useFileHiding );
307
308
308
309
if (loadThread .isInterrupted ()) {
309
310
return ;
310
311
}
311
312
312
313
final Vector <File > newFileCache = new Vector <File >();
313
- Vector <File > newFiles = new Vector <File >();
314
+ final Vector <File > newFiles = new Vector <File >();
314
315
315
- // run through the file list, add directories and selectable files to fileCache
316
+ // Run through the file list, add directories and selectable files to fileCache
316
317
// Note that this block must be OUTSIDE of Invoker thread because of
317
318
// deadlock possibility with custom synchronized FileSystemView
318
319
for (File file : list ) {
@@ -339,7 +340,7 @@ private void run0() {
339
340
340
341
// To avoid loads of synchronizations with Invoker and improve performance we
341
342
// execute the whole block on the COM thread
342
- runnable = ShellFolder .invoke (new Callable <DoChangeContents >() {
343
+ DoChangeContents runnable = ShellFolder .invoke (new Callable <DoChangeContents >() {
343
344
public DoChangeContents call () {
344
345
synchronized (fileCache ) {
345
346
int newSize = newFileCache .size ();
@@ -395,7 +396,7 @@ public DoChangeContents call() {
395
396
}
396
397
if (!fileCache .equals (newFileCache )) {
397
398
if (loadThread .isInterrupted ()) {
398
- cancelRunnables () ;
399
+ return null ;
399
400
}
400
401
return new DoChangeContents (newFileCache , 0 , fileCache , 0 , fid );
401
402
}
@@ -408,12 +409,6 @@ public DoChangeContents call() {
408
409
SwingUtilities .invokeLater (runnable );
409
410
}
410
411
}
411
-
412
- private void cancelRunnables () {
413
- if (runnable != null ) {
414
- runnable .cancel ();
415
- }
416
- }
417
412
}
418
413
419
414
@@ -522,45 +517,46 @@ public void run() {
522
517
private final class DoChangeContents implements Runnable {
523
518
private final List <File > addFiles ;
524
519
private final List <File > remFiles ;
525
- private boolean doFire = true ;
526
520
private final int fid ;
527
- private int addStart = 0 ;
528
- private int remStart = 0 ;
521
+ private final int addStart ;
522
+ private final int remStart ;
529
523
530
- DoChangeContents (List <File > addFiles , int addStart , List <File > remFiles ,
531
- int remStart , int fid ) {
524
+ private DoChangeContents (List <File > addFiles , int addStart ,
525
+ List <File > remFiles , int remStart ,
526
+ int fid ) {
532
527
this .addFiles = addFiles ;
533
528
this .addStart = addStart ;
534
529
this .remFiles = remFiles ;
535
530
this .remStart = remStart ;
536
531
this .fid = fid ;
537
532
}
538
533
539
- synchronized void cancel () {
540
- doFire = false ;
541
- }
534
+ @ Override
535
+ public void run () {
536
+ if (fetchID .get () != fid ) {
537
+ return ;
538
+ }
542
539
543
- public synchronized void run () {
544
- if (fetchID .get () == fid && doFire ) {
545
- int remSize = (remFiles == null ) ? 0 : remFiles .size ();
546
- int addSize = (addFiles == null ) ? 0 : addFiles .size ();
547
- synchronized (fileCache ) {
548
- if (remSize > 0 ) {
549
- fileCache .removeAll (remFiles );
550
- }
551
- if (addSize > 0 ) {
552
- fileCache .addAll (addStart , addFiles );
553
- }
554
- files = null ;
555
- directories = null ;
540
+ final int remSize = (remFiles == null ) ? 0 : remFiles .size ();
541
+ final int addSize = (addFiles == null ) ? 0 : addFiles .size ();
542
+ final int cacheSize ;
543
+ synchronized (fileCache ) {
544
+ if (remSize > 0 ) {
545
+ fileCache .removeAll (remFiles );
556
546
}
557
- if (remSize > 0 && addSize == 0 ) {
558
- fireIntervalRemoved (BasicDirectoryModel .this , remStart , remStart + remSize - 1 );
559
- } else if (addSize > 0 && remSize == 0 && addStart + addSize <= fileCache .size ()) {
560
- fireIntervalAdded (BasicDirectoryModel .this , addStart , addStart + addSize - 1 );
561
- } else {
562
- fireContentsChanged ();
547
+ if (addSize > 0 ) {
548
+ fileCache .addAll (addStart , addFiles );
563
549
}
550
+ files = null ;
551
+ directories = null ;
552
+ cacheSize = fileCache .size ();
553
+ }
554
+ if (remSize > 0 && addSize == 0 ) {
555
+ fireIntervalRemoved (BasicDirectoryModel .this , remStart , remStart + remSize - 1 );
556
+ } else if (addSize > 0 && remSize == 0 && addStart + addSize <= cacheSize ) {
557
+ fireIntervalAdded (BasicDirectoryModel .this , addStart , addStart + addSize - 1 );
558
+ } else {
559
+ fireContentsChanged ();
564
560
}
565
561
}
566
562
}
0 commit comments