26
26
import java .io .File ;
27
27
import java .io .IOException ;
28
28
import java .nio .file .DirectoryStream ;
29
+ import java .nio .file .FileAlreadyExistsException ;
29
30
import java .nio .file .FileVisitResult ;
30
31
import java .nio .file .Files ;
31
32
import java .nio .file .Path ;
@@ -360,7 +361,7 @@ private void doLink(PendingSymlinkageExec lnk) throws IOException {
360
361
deleteFileOrDirectory (sourcePath );
361
362
362
363
File sourceParentFile = sourcePath .getParent ().toFile ();
363
- /**
364
+ /*
364
365
* The double check-exists in the following conditional is necessary
365
366
* because during a race when two threads are simultaneously linking
366
367
* for a not-yet-existent `sourceParentFile`, the first check-exists
@@ -372,11 +373,16 @@ private void doLink(PendingSymlinkageExec lnk) throws IOException {
372
373
sourceParentFile .exists ()) {
373
374
Files .createSymbolicLink (sourcePath , Paths .get (lnk .targetRel ));
374
375
}
376
+ } catch (FileAlreadyExistsException e ) {
377
+ // Another case of racing threads. Given that each of them works with the same path,
378
+ // there is no need to worry.
379
+ return ;
375
380
} catch (IOException e ) {
376
381
LOGGER .log (Level .WARNING , "Failed to link: {0} -> {1}" ,
377
382
new Object []{lnk .source , lnk .targetRel });
378
383
throw e ;
379
384
}
385
+
380
386
if (LOGGER .isLoggable (Level .FINEST )) {
381
387
LOGGER .log (Level .FINEST , "Linked pending: {0} -> {1}" ,
382
388
new Object []{lnk .source , lnk .targetRel });
0 commit comments