@@ -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
/**
@@ -270,7 +274,6 @@ private final class FilesLoader implements Runnable {
270
274
private final boolean fileSelectionEnabled ;
271
275
private final int fid ;
272
276
private final File currentDirectory ;
273
- private volatile DoChangeContents runnable ;
274
277
private final Thread loadThread ;
275
278
276
279
private FilesLoader (File currentDirectory , int fid ) {
@@ -291,22 +294,20 @@ public void run() {
291
294
}
292
295
293
296
private void run0 () {
294
- FileSystemView fileSystem = fileSystemView ;
295
-
296
297
if (loadThread .isInterrupted ()) {
297
298
return ;
298
299
}
299
300
300
- File [] list = fileSystem .getFiles (currentDirectory , useFileHiding );
301
+ File [] list = fileSystemView .getFiles (currentDirectory , useFileHiding );
301
302
302
303
if (loadThread .isInterrupted ()) {
303
304
return ;
304
305
}
305
306
306
307
final Vector <File > newFileCache = new Vector <File >();
307
- Vector <File > newFiles = new Vector <File >();
308
+ final Vector <File > newFiles = new Vector <File >();
308
309
309
- // run through the file list, add directories and selectable files to fileCache
310
+ // Run through the file list, add directories and selectable files to fileCache
310
311
// Note that this block must be OUTSIDE of Invoker thread because of
311
312
// deadlock possibility with custom synchronized FileSystemView
312
313
for (File file : list ) {
@@ -333,7 +334,7 @@ private void run0() {
333
334
334
335
// To avoid loads of synchronizations with Invoker and improve performance we
335
336
// execute the whole block on the COM thread
336
- runnable = ShellFolder .invoke (new Callable <DoChangeContents >() {
337
+ DoChangeContents runnable = ShellFolder .invoke (new Callable <DoChangeContents >() {
337
338
public DoChangeContents call () {
338
339
synchronized (fileCache ) {
339
340
int newSize = newFileCache .size ();
@@ -389,7 +390,7 @@ public DoChangeContents call() {
389
390
}
390
391
if (!fileCache .equals (newFileCache )) {
391
392
if (loadThread .isInterrupted ()) {
392
- cancelRunnables () ;
393
+ return null ;
393
394
}
394
395
return new DoChangeContents (newFileCache , 0 , fileCache , 0 , fid );
395
396
}
@@ -402,12 +403,6 @@ public DoChangeContents call() {
402
403
SwingUtilities .invokeLater (runnable );
403
404
}
404
405
}
405
-
406
- private void cancelRunnables () {
407
- if (runnable != null ) {
408
- runnable .cancel ();
409
- }
410
- }
411
406
}
412
407
413
408
@@ -516,45 +511,46 @@ public void run() {
516
511
private final class DoChangeContents implements Runnable {
517
512
private final List <File > addFiles ;
518
513
private final List <File > remFiles ;
519
- private boolean doFire = true ;
520
514
private final int fid ;
521
- private int addStart = 0 ;
522
- private int remStart = 0 ;
515
+ private final int addStart ;
516
+ private final int remStart ;
523
517
524
- DoChangeContents (List <File > addFiles , int addStart , List <File > remFiles ,
525
- int remStart , int fid ) {
518
+ private DoChangeContents (List <File > addFiles , int addStart ,
519
+ List <File > remFiles , int remStart ,
520
+ int fid ) {
526
521
this .addFiles = addFiles ;
527
522
this .addStart = addStart ;
528
523
this .remFiles = remFiles ;
529
524
this .remStart = remStart ;
530
525
this .fid = fid ;
531
526
}
532
527
533
- synchronized void cancel () {
534
- doFire = false ;
535
- }
528
+ @ Override
529
+ public void run () {
530
+ if (fetchID .get () != fid ) {
531
+ return ;
532
+ }
536
533
537
- public synchronized void run () {
538
- if (fetchID .get () == fid && doFire ) {
539
- int remSize = (remFiles == null ) ? 0 : remFiles .size ();
540
- int addSize = (addFiles == null ) ? 0 : addFiles .size ();
541
- synchronized (fileCache ) {
542
- if (remSize > 0 ) {
543
- fileCache .removeAll (remFiles );
544
- }
545
- if (addSize > 0 ) {
546
- fileCache .addAll (addStart , addFiles );
547
- }
548
- files = null ;
549
- directories = null ;
534
+ final int remSize = (remFiles == null ) ? 0 : remFiles .size ();
535
+ final int addSize = (addFiles == null ) ? 0 : addFiles .size ();
536
+ final int cacheSize ;
537
+ synchronized (fileCache ) {
538
+ if (remSize > 0 ) {
539
+ fileCache .removeAll (remFiles );
550
540
}
551
- if (remSize > 0 && addSize == 0 ) {
552
- fireIntervalRemoved (BasicDirectoryModel .this , remStart , remStart + remSize - 1 );
553
- } else if (addSize > 0 && remSize == 0 && addStart + addSize <= fileCache .size ()) {
554
- fireIntervalAdded (BasicDirectoryModel .this , addStart , addStart + addSize - 1 );
555
- } else {
556
- fireContentsChanged ();
541
+ if (addSize > 0 ) {
542
+ fileCache .addAll (addStart , addFiles );
557
543
}
544
+ files = null ;
545
+ directories = null ;
546
+ cacheSize = fileCache .size ();
547
+ }
548
+ if (remSize > 0 && addSize == 0 ) {
549
+ fireIntervalRemoved (BasicDirectoryModel .this , remStart , remStart + remSize - 1 );
550
+ } else if (addSize > 0 && remSize == 0 && addStart + addSize <= cacheSize ) {
551
+ fireIntervalAdded (BasicDirectoryModel .this , addStart , addStart + addSize - 1 );
552
+ } else {
553
+ fireContentsChanged ();
558
554
}
559
555
}
560
556
}
0 commit comments